马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
linenumberarea.h- #ifndef LINENUMBERAREA_H
- #define LINENUMBERAREA_H
- #include <QWidget>
- #include <QPainter>
- #include <QTextBlock>
- #include <QPlainTextEdit>
- class LineNumberArea;
- class CodeEditor : public QPlainTextEdit
- {
- Q_OBJECT
- public:
- CodeEditor(QWidget *parent = nullptr);
- //自定义的绘制事件处理函数,专门用于在行号区域绘制行号
- void lineNumberAreaPaintEvent(QPaintEvent *event);
- //负责计算并返回行号区域的宽度。这个函数通常在文本编辑器中使用,
- //以确保行号区域的宽度能够容纳所有可能的行号。
- int lineNumberAreaWidth();
- protected:
- //用于处理窗口或控件的大小调整事件
- //该方法确保在编辑器的大小变化时,行号区域能够正确调整其大小和位置。
- void resizeEvent(QResizeEvent *event) override;
- private slots:
- //,负责更新行号区域的宽度。这个函数在文本块数量变化时调用,
- //以确保行号区域的宽度足够显示所有行号。
- void updateLineNumberAreaWidth(int newBlockCount);
- //高亮当前行
- void highlightCurrentLine();
- //更新行号区域
- void updateLineNumberArea(const QRect &rect, int dy);
- private:
- QWidget *lineNumberArea;
- };
- class LineNumberArea : public QWidget
- {
- public:
- LineNumberArea(CodeEditor *editor) : QWidget(editor),
- codeEditor(editor){}
- //该方法计算并返回行号区域的建议大小
- QSize sizeHint() const override
- {
- return QSize(codeEditor->lineNumberAreaWidth(), 0);
- }
- protected:
- //该方法负责在行号区域绘制行号
- void paintEvent(QPaintEvent *event) override
- {
- codeEditor->lineNumberAreaPaintEvent(event);
- }
- private:
- CodeEditor *codeEditor;
- };
- #endif // LINENUMBERAREA_H
复制代码 linenumberarea.cpp- #include "linenumberarea.h"
- CodeEditor::CodeEditor(QWidget *parent) : QPlainTextEdit(parent)
- {
- lineNumberArea = new LineNumberArea(this);
- connect(this, &CodeEditor::blockCountChanged, this, &CodeEditor::updateLineNumberAreaWidth);
- connect(this, &CodeEditor::updateRequest, this, &CodeEditor::updateLineNumberArea);
- connect(this, &CodeEditor::cursorPositionChanged, this, &CodeEditor::highlightCurrentLine);
- updateLineNumberAreaWidth(0);//计算行号区域宽度
- highlightCurrentLine();//高亮显示
- }
- int CodeEditor::lineNumberAreaWidth()
- {
- int digits = 1;
- int max = qMax(1, blockCount());
- //计算数位
- while (max >= 10) {
- max /= 10;
- ++digits;
- }
- //取字符9的宽度
- int space = 3 + fontMetrics().horizontalAdvance(QLatin1Char('9')) * digits;
- return space;
- }
- void CodeEditor::updateLineNumberAreaWidth(int /* newBlockCount */)
- {
- setViewportMargins(lineNumberAreaWidth(), 0, 0, 0);
- }
- void CodeEditor::updateLineNumberArea(const QRect &rect, int dy)
- {
- if (dy)
- lineNumberArea->scroll(0, dy);
- else
- lineNumberArea->update(0, rect.y(), lineNumberArea->width(), rect.height());
- if (rect.contains(viewport()->rect()))
- updateLineNumberAreaWidth(0);
- }
- void CodeEditor::resizeEvent(QResizeEvent *e)
- {
- QPlainTextEdit::resizeEvent(e);
- QRect cr = contentsRect();
- lineNumberArea->setGeometry(QRect(cr.left(), cr.top(), lineNumberAreaWidth(), cr.height()));
- }
- void CodeEditor::highlightCurrentLine()
- {
- QList<QTextEdit::ExtraSelection> extraSelections;
- if (!isReadOnly()) {
- QTextEdit::ExtraSelection selection;
- QColor lineColor = QColor(Qt::yellow).lighter(160);
- selection.format.setBackground(lineColor);
- selection.format.setProperty(QTextFormat::FullWidthSelection, true);
- selection.cursor = textCursor();
- selection.cursor.clearSelection();
- extraSelections.append(selection);
- }
- setExtraSelections(extraSelections);
- }
- void CodeEditor::lineNumberAreaPaintEvent(QPaintEvent *event)
- {
- QPainter painter(lineNumberArea);
- painter.fillRect(event->rect(), Qt::lightGray);
- QTextBlock block = firstVisibleBlock();
- int blockNumber = block.blockNumber();
- int top = qRound(blockBoundingGeometry(block).translated(contentOffset()).top());
- int bottom = top + qRound(blockBoundingRect(block).height());
- while (block.isValid() && top <= event->rect().bottom()) {
- if (block.isVisible() && bottom >= event->rect().top()) {
- QString number = QString::number(blockNumber + 1);
- painter.setPen(Qt::black);
- painter.drawText(0, top, lineNumberArea->width(), fontMetrics().height(),
- Qt::AlignRight, number);
- }
- block = block.next();
- top = bottom;
- bottom = top + qRound(blockBoundingRect(block).height());
- ++blockNumber;
- }
- }
复制代码 mainwindow.h- #ifndef MAINWINDOW_H
- #define MAINWINDOW_H
- #include <QMainWindow>
- QT_BEGIN_NAMESPACE
- namespace Ui { class MainWindow; }
- QT_END_NAMESPACE
- class MainWindow : public QMainWindow
- {
- Q_OBJECT
- public:
- MainWindow(QWidget *parent = nullptr);
- ~MainWindow();
- private:
- Ui::MainWindow *ui;
- };
- #endif // MAINWINDOW_H
复制代码 mainwindow.cpp- #include "mainwindow.h"
- #include "ui_mainwindow.h"
- #include "linenumberarea.h"
- #include <QDebug>
- MainWindow::MainWindow(QWidget *parent)
- : QMainWindow(parent)
- , ui(new Ui::MainWindow)
- {
- ui->setupUi(this);
- CodeEditor *aaa=new CodeEditor();
- setCentralWidget(aaa);
- aaa->setPlainText("1234567891011");
- qDebug()<<aaa->toPlainText();
- }
- MainWindow::~MainWindow()
- {
- delete ui;
- }
复制代码 main.cpp- #include "mainwindow.h"
- #include <QApplication>
- int main(int argc, char *argv[])
- {
- QApplication a(argc, argv);
- MainWindow w;
- w.show();
- return a.exec();
- }
复制代码 运行截图:
|