qt做一个带行号的文本编辑器

前言

做单片机开发的经常需要一些协议转换的小工具(虽然mcu厂商有提供,但与我们要用的不能完全兼容)。最近为了做一款hex文件格式转s19格式的上位机软件,最开始设计界面与一般的上位机一样搞个PushButton,点击一下打开文件,然后开始转换。后面觉得界面实在太丑了,而且每次转换都得先点击上位机,然后再找文件后开始转换。

为何不直接点击hex文件,然后就能调用文件转换工具?或者在hex文件的地方点击右键,右键菜单中有hex->s19的功能呢?

这里我选择了前一种方式。里有是更加直观。你可以像用记事本打开txt文件一样简单。既可以直接点击hex文件,也可以先打开上位机再打开文本文件

 功能特点

一、可以通过菜单栏打开文件

二、可以通过拖拽功能打开文件

三、可以通过点击文本文件打开文本文件(此处需要设置默认打开程序)

四、显示文本行号

文本显示控件MyTextEdit

qt中没有可以自带显示行号的控件,该控件为自己修改控件,包含了QTextEdit,QTextBrowser、QScrollBar三个小控件。

 QTextEdit 用来显示文本,QTextBrowser用来显示行号、QScrollBar为横向滚动条。

在ui文件中禁用掉QTextBrowser横向、纵向滚动条以及QTextEdit横向滚动条。

之所以添加横向QScrollBar,主要是因为若QTextEdit出现横向滚动条,QTextBrowser无滚动条时会导致行号显示位置与文本显示不在同一水平线上。

设置好界面后使用信号槽方式关联好滚动条与显示的关系

实际运行效果

  • 5
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
QtQTextEdit 组件默认是没有行号显示的,但是可以通过自定义 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(); } ```
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值