qt textedit行号显示
时间: 2024-04-01 15:24:50 浏览: 33
Qt 的 QTextEdit 组件默认是没有行号显示的,但是可以通过自定义 QSyntaxHighlighter 类来实现行号显示。
下面是一个简单的示例代码:
```cpp
class LineNumberArea : public QWidget
{
public:
LineNumberArea(QTextEdit* editor) : QWidget(editor)
{
m_editor = editor;
}
QSize sizeHint() const override
{
return QSize(m_editor->lineNumberAreaWidth(), 0);
}
protected:
void paintEvent(QPaintEvent* event) override
{
m_editor->lineNumberAreaPaintEvent(event);
}
private:
QTextEdit* m_editor;
};
class TextEdit : public QTextEdit
{
public:
TextEdit(QWidget* parent = nullptr) : QTextEdit(parent)
{
m_lineNumberArea = new LineNumberArea(this);
connect(this, &TextEdit::blockCountChanged, this, &TextEdit::updateLineNumberAreaWidth);
connect(this, &TextEdit::updateRequest, this, &TextEdit::updateLineNumberArea);
connect(this, &TextEdit::cursorPositionChanged, this, &TextEdit::highlightCurrentLine);
updateLineNumberAreaWidth();
highlightCurrentLine();
}
protected:
void resizeEvent(QResizeEvent* event) override
{
QTextEdit::resizeEvent(event);
QRect cr = contentsRect();
m_lineNumberArea->setGeometry(QRect(cr.left(), cr.top(), lineNumberAreaWidth(), cr.height()));
}
private:
void updateLineNumberAreaWidth()
{
setViewportMargins(lineNumberAreaWidth(), 0, 0, 0);
}
void updateLineNumberArea(const QRect& rect, int dy)
{
if (dy)
m_lineNumberArea->scroll(0, dy);
else
m_lineNumberArea->update(0, rect.y(), m_lineNumberArea->width(), rect.height());
if (rect.contains(viewport()->rect()))
updateLineNumberAreaWidth();
}
void lineNumberAreaPaintEvent(QPaintEvent* event)
{
QPainter painter(m_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, m_lineNumberArea->width(), fontMetrics().height(), Qt::AlignRight, number);
}
block = block.next();
top = bottom;
bottom = top + qRound(blockBoundingRect(block).height());
++blockNumber;
}
}
void 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);
}
int lineNumberAreaWidth()
{
int digits = 1;
int max = qMax(1, blockCount());
while (max >= 10)
{
max /= 10;
++digits;
}
int space = 3 + fontMetrics().width(QLatin1Char('9')) * digits;
return space;
}
private:
LineNumberArea* m_lineNumberArea;
};
```
在上面的代码中,我们自定义了 LineNumberArea 和 TextEdit 两个类。其中,LineNumberArea 是用来显示行号的 QWidget 子类,而 TextEdit 则是用来显示文本和行号的 QTextEdit 子类。
在 TextEdit 类中,我们重载了 resizeEvent()、updateRequest() 和 cursorPositionChanged() 三个函数,并且连接了它们的信号到对应的槽函数中。这些槽函数用来更新行号区域的大小、内容和当前行的高亮显示。
注意,在 TextEdit 类中,我们还重载了 setViewportMargins() 函数,用来设置视口的外边距。这里我们将左边距设置为行号区域的宽度,以便在 QTextEdit 中显示行号。
最后,我们可以像下面这样使用 TextEdit 类来显示带有行号的文本编辑器:
```cpp
int main(int argc, char** argv)
{
QApplication app(argc, argv);
TextEdit editor;
editor.show();
return app.exec();
}
```