☰
QCodeEditor 集成实战:给 Qt 应用打造带语法高亮的代码编辑器
2026/10/4 21:53:22 网站建设 项目流程

简介:这是一份面向Qt开发者的代码编辑器小部件组件包,基于C++11与Qt5构建,提供编辑/查看代码的核心能力。组件内置自动括号匹配、自动缩进、空格替换制表符,并内置GLSL、C++、XML、JSON、Lua、Python等多种语言的语法高亮与代码补全规则,同时支持Qt Creator风格主题切换与框架选择,可直接嵌入需要代码编辑界面的工具、IDE插件或教学演示项目。整个工程以CMake库形式组织,可作为子模块集成到现有工程中。压缩包共73个文件,大小108KB。其中18个hpp和18个cpp构成核心源码框架,7个xml描述高亮规则,2个qrc管理资源引用,另含json、lua、glsl、py等语言相关文件,以及示例工程和MIT许可证,目录划分清晰,便于按需裁剪或二次开发。目前已有817人学习下载,对想理解语法高亮实现原理的Qt进阶者而言,是一份轻量且完整的参考实现。

1. QCodeEditor 是什么:给 Qt 工具加编辑器,为什么不用 QPlainTextEdit 硬写

很多 Qt 开发者第一次遇到 QCodeEditor 的场景很一致:手头工具需要一个能看又能改代码的窗口,先拖一个 QPlainTextEdit 进去,结果行号没有、高亮没有、缩进靠运气,写完自己都嫌弃。QCodeEditor 是一个开源的 Qt 代码编辑器小部件,它的定位是给 Qt 桌面应用嵌入一个“够用且不折腾”的编辑区,不需要像 QScintilla 那样引入一大套第三方库,也不需要自己从 QAbstractScrollArea 开始堆轮子,它直接基于 QPlainTextEdit 加了一层行号区域、语法高亮框架和搜索组件,做到开箱即用。

这个方案适合谁?如果你在做的工具是日志查看器、脚本配置面板、SQL 客户端、内嵌 Python 调试器或者任何“需要一段带高亮的文本编辑区”的桌面程序,QCodeEditor 能帮你把编辑器部分半天内落地。它的短板也明显:不是完整的 IDE 内核,代码补全、诊断、断点这些都不提供,需要自己接。这篇文章会从编译集成、最小窗口、高亮规则定制到避坑逐个拆开,给出能直接复现的做法和参数。文中所有命令和代码都以 Qt 5.15 / 6.x + CMake 为基准,MSVC 和 MinGW 的差异会在踩坑章节单独说明。

2. 编译集成:把 QCodeEditor 源码接进 Qt 工程的两条可靠路径

2.1 路径一:CMake add_subdirectory 源码级集成

QCodeEditor 的源码结构不复杂,核心就是 QCodeEditor 类、QHighlightRule、QHighlighter、QLineNumberArea、QSearchWidget 这几个文件。最常见的接入方式是直接把源码目录放进你的工程,用 CMake 的 add_subdirectory 把它编译成库,再让目标链接它。这种方式的好处是调试时可以直接跟进 QCodeEditor 内部,坏处是你的工程里会多出一份第三方源码,更新版本时需要注意。

# CMakeLists.txt 片段 cmake_minimum_required(VERSION 3.16) project(MyEditorApp VERSION 0.1 LANGUAGES CXX) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) # 如果 Qt 不在默认路径,手动指定 # set(CMAKE_PREFIX_PATH "D:/Qt/5.15.2/msvc2019_64") find_package(Qt5 COMPONENTS Widgets REQUIRED) # 引入 QCodeEditor 源码目录,假设第三方库放在 3rdparty 下 add_subdirectory(3rdparty/QCodeEditor) add_executable(MyEditorApp main.cpp MainWindow.cpp MainWindow.h ) target_link_libraries(MyEditorApp PRIVATE Qt5::Widgets QCodeEditor )

这里的关键是 add_subdirectory 之后,QCodeEditor 库会自动把 Widgets 依赖、自身头文件搜索路径一并传给 MyEditorApp,你不需要再单独加 include 目录。如果编译报错提示找不到 QCodeEditor 头文件,先检查这个库的 CMakeLists 里是否设置了 target_include_directories,有的旧版本 fork 用的是 BUILD_INTERFACE 而不是 INSTALL_INTERFACE,源码级接入时没问题,但如果你想把它 install 出去复用,就得改一下导出配置。

另外一个常见做法是直接把 QCodeEditor 的 .cpp/.h 全部加到你的工程里,不走 add_subdirectory。如果你的工程本身就是 qmake 的 .pro 文件,这种直放方式反而最省事,把源码文件追加进 HEADERS 和 SOURCES,再链接 Qt5::Widgets 就够了。源码直放的坑是 QCodeEditor 内部用到了 QPainterPath 和 QTextObjectInterface,这些都是 Widgets 模块的内容,如果你只 link 了 Qt5::Core,链接期会报一堆无法解析的外部符号。

2.2 路径二:CMake 命令行构建与编译器套件匹配

无论你用 Qt Creator 还是 VS Code,本质都在调 CMake。构建 QCodeEditor 本身不需要额外配置,但嵌入你的工程后,常见翻车点是 Qt 套件和编译器版本对不上。我用 Qt 5.15.2 配 MSVC2019 构建过,也用过 Qt 6.2 配 MinGW 11,两条线都稳定,但有一点必须强调:MSVC 套件只能用 MSVC 编译器,MinGW 套件只能用 MinGW 编译器,混搭时 Qt 的元对象编译和二进制兼容会直接崩给你看。

# 命令行构建示例:Windows + MSVC2019 + Qt 5.15.2 mkdir build && cd build cmake .. -G "Visual Studio 16 2019" -A x64 ^ -DCMAKE_PREFIX_PATH=D:/Qt/5.15.2/msvc2019_64 cmake --build . --config Release

参数说明:-G指定生成器,这里用 VS2019;-A x64指定目标架构,如果你是 32 位插件进程,改成 Win32;关键参数是CMAKE_PREFIX_PATH,它告诉 CMake 去哪找 Qt 的 CMake 配置文件(Qt5Config.cmake 或 Qt6Config.cmake)。这个路径一旦写错,find_package(Qt5)就会失败,报错信息是“Could not find a package configuration file”,此时要去确认你的 Qt 安装目录里是否有lib/cmake/Qt5这个子目录。

在 Windows 上装 Qt 时,如果你嫌 Qt 官方下载器慢,可以用清华镜像源,这个做法在社区里很普遍,下载器里设置镜像地址后下载速度会快很多。另外注意 Qt 5.15.2 是最后一个支持 Win7 的版本,如果你的目标机器还在 Win7 上跑,就不要用 Qt 6;反过来,Qt 6 对 C++17 是硬性要求,你的代码里不要再出现 C++14 的写法。

2.3 集成后的最小验证:头文件能过、符号能链接

集成完成后,先别急着写界面,做一个最小编译验证。新建一个 main.cpp,只保留一个能创建 QCodeEditor 对象的main函数,确认这个库能编译、链接、运行。

#include <QApplication> #include <QCodeEditor> int main(int argc, char *argv[]) { QApplication app(argc, argv); QCodeEditor editor; editor.setPlainText("int x = 42;"); editor.resize(640, 480); editor.show(); return app.exec(); }

这段代码能跑起来,说明你的工程和 QCodeEditor 之间的目录、链接、Qt 模块三样东西都通顺。注意这里用setPlainText而不是setText,因为 QCodeEditor 继承自 QPlainTextEdit,setText不存在,老写 QTextEdit 的人在这个地方会浪费十秒钟。运行后你会看到一个带行号、默认有高亮规则的编辑器窗口,默认高亮规则覆盖 C++ 关键字,这算是一个内置的冒烟验证。

如果这一步失败了,不要急着改代码,先看 CMake 缓存:把build/CMakeCache.txt里的CMAKE_PREFIX_PATH和CMAKE_CXX_COMPILER两个变量打出来核对,百分之八十的集成问题都出在这两个变量上,而不是 QCodeEditor 自己。

3. 最小可跑窗口:五步搭出带打开、保存、行号的编辑器核心

3.1 主窗口布局:QCodeEditor 放进 QMainWindow 的正确姿势

QCodeEditor 是普通 QWidget 子类,放进 QMainWindow 的setCentralWidget就行,不用包 ScrollArea,也不用手动管理布局。行号区是它内部自动绘制的,不需要你自己再画。这里要把 tab 键行为和缩进语义设置好,不然代码编辑体验很差。

// MainWindow.h #pragma once #include <QMainWindow> #include <QCodeEditor> class MainWindow : public QMainWindow { Q_OBJECT public: explicit MainWindow(QWidget *parent = nullptr); private slots: void openFile(); void saveFile(); private: QCodeEditor *m_editor; };
// MainWindow.cpp #include "MainWindow.h" #include <QMenuBar> #include <QToolBar> #include <QFileDialog> #include <QFile> #include <QTextStream> #include <QMessageBox> #include <QStandardPaths> MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { m_editor = new QCodeEditor(this); setCentralWidget(m_editor); // 打开、保存动作 QAction *actOpen = new QAction(tr("打开"), this); QAction *actSave = new QAction(tr("保存"), this); connect(actOpen, &QAction::triggered, this, &MainWindow::openFile); connect(actSave, &QAction::triggered, this, &MainWindow::saveFile); QToolBar *toolbar = addToolBar(tr("文件")); toolbar->addAction(actOpen); toolbar->addAction(actSave); }

这段代码里我故意把菜单和工具栏精简了,核心是你需要理解 QCodeEditor 作为 centralWidget 时,它的尺寸策略是优先填满窗口,而且它内部的行号区宽度会根据数字位数自动调整,不需要你做额外计算。addToolBar返回的 QToolBar 可以直接往里插 QAction,这是 Qt 里最省代码的工具栏写法。

3.2 文件读写:编码处理和换行符的两个小坑

文件读写看起来是 trivial 的,但 Qt 的QTextStream默认编码是 UTF-8,在 Windows 上如果你读到一个 GBK 编码的旧脚本,会乱码。做法是读取时先检查 BOM,再看内容是否合法 UTF-8,最后回退到本地编码。QCodeEditor 本质是 QPlainTextEdit,toPlainText()拿到的永远是 QString,内部无编码概念,所以编码转换必须在文件边界做掉。

void MainWindow::openFile() { const QString path = QFileDialog::getOpenFileName(this, tr("打开文件")); if (path.isEmpty()) return; QFile file(path); if (!file.open(QIODevice::ReadOnly)) { QMessageBox::warning(this, tr("错误"), tr("无法打开文件: %1").arg(file.errorString())); return; } QByteArray raw = file.readAll(); file.close(); // 编码判定:优先 UTF-8 BOM,其次合法 UTF-8,最后本地编码 QString content; if (raw.startsWith("\xEF\xBB\xBF")) { content = QString::fromUtf8(raw.mid(3)); } else { QTextCodec *codec = QTextCodec::codecForName("UTF-8"); if (codec && codec->canEncode(QString::fromUtf8(raw))) { content = QString::fromUtf8(raw); } else { content = QString::fromLocal8Bit(raw); } } m_editor->setPlainText(content); // 这个属性让编辑器记住当前文件路径,保存时不需要再次弹对话框 m_editor->setProperty("filePath", path); setWindowTitle(path); }

注意几个参数:QString::fromUtf8(raw.mid(3))去掉 BOM 再转,避免行首出现不可见字符;QTextCodec::canEncode不是完美的 UTF-8 检测手段,但对付绝大多数场景够用了。如果你在处理日志文件时发现中文仍然乱码,那么十有八九文件是 GB18030 编码,此时直接把codecForName("UTF-8")换成QTextCodec::codecForName("GB18030")即可,但这种硬编码不推荐,更好的做法是把编码选择做成记忆式下拉框。

3.3 核心交互设置:tab 宽度、自动缩进和行尾模式

QCodeEditor 本身提供了几个值得一调的公共接口。setTabReplaceSize控制 tab 替换成几个空格;setAutoIndentation开关自动缩进;setLineNumbersVisible控制行号区显隐。这三个参数基本决定了一个编辑器“像不像编辑器”。

// 推荐参数 m_editor->setTabReplaceSize(4); // tab 替换为 4 个空格 m_editor->setAutoIndentation(true); // 回车后自动对齐上一行缩进 m_editor->setLineNumbersVisible(true); // 显示行号 // 括号高亮是 QCodeEditor 的特色之一,建议打开 // 它内部用 QTextCursor 的 anchor 和 position 来做括号配对,开销很小 QFont font("Cascadia Code", 11); font.setStyleHint(QFont::Monospace); m_editor->setFont(font);

setTabReplaceSize(4)之后,编辑器里敲 Tab 会输入 4 个空格而不是\t,这是为了配合语法高亮规则里的^\s+正则匹配,空格缩进在后续自定义高亮时更可控。setAutoIndentation(true)的实现原理是捕获 Key_Return 和 Key_Enter,取当前行行首空白串,拼到新行前面,它不做智能缩进分析,所以不要指望它像 IDE 那样自动补花括号层级。字体选择上,Cascadia Code 或 JetBrains Mono 都好,关键是setStyleHint(QFont::Monospace),否则 Windows 下会退回到无法对齐的字体,行号区间距也会乱。

4. 语法高亮定制:QHighlightRule 规则表与 setFormat 背后的匹配逻辑

4.1 QSyntaxHighlighter 的 block 回调机制:为什么规则要返回 index

QCodeEditor 的高亮底层是 Qt 的 QSyntaxHighlighter。这个类的工作方式不是“对整个文档跑一遍正则”,而是按行(block)逐个回调highlightBlock(const QString &text)。QCodeEditor 在自己内部把一组 QHighlightRule 遍历执行,每条规则包含一个 QRegularExpression 和一个 QTextCharFormat,匹配到就调用setFormat(0, match.capturedLength(), format)。

理解这个机制的第一个关键点:highlightBlock只在文档变化时被调用,而且只调用受影响的行及其后续行块。因此如果你的高亮规则性能差,大文件编辑时会感受到输入卡顿,因为每次按键可能触发多行重排。QCodeEditor 默认规则集对 C++ 而言性能是可接受的,但如果你自己要加规则,务必避免使用过于宽泛的贪婪匹配。

第二个关键点是捕获组索引index。QHighlightRule 里有个index字段,默认是 0,意思是整个匹配都上色。如果你写正则\b(int|float|double)\b,index=0表示匹配到的完整 token 上色。如果你有嵌套需求比如函数名后跟括号,你可能想只给函数名上色,那么 index 设为 1,正则里把函数名放进第一个捕获组。

{ "pattern": "\\b(class|struct|enum)\\b", "format": { "color": "#569CD6" }, "index": 0 }

4.2 自定义高亮类:仿 VS Code 深色主题的规则表

下面给出一个完整可用的自定义高亮实现,以 JSON 加载规则的形式组织,方便你像配置主题一样调整颜色。QCodeEditor 本身支持loadSyntaxDefinition从 JSON 加载语法定义,这是它相比其他小部件最省事的地方。

// 自定义语法定义 my_syntax.json { "rules": [ { "pattern": "\\b(if|else|for|while|return|break|continue)\\b", "format": { "color": "#C586C0", "fontStyle": "bold" }, "index": 0 }, { "pattern": "(\\b[A-Za-z_][A-Za-z0-9_]*)\\s*\\(", "format": { "color": "#DCDCAA" }, "index": 1 }, { "pattern": "//[^\\n]*", "format": { "color": "#6A9955", "fontStyle": "italic" }, "index": 0 }, { "pattern": "\"[^\"\\n]*\"", "format": { "color": "#CE9178" }, "index": 0 } ] }
// 加载语法定义 QFile syntaxFile(":/syntax/my_syntax.json"); if (syntaxFile.open(QIODevice::ReadOnly)) { m_editor->loadSyntaxDefinition(syntaxFile.readAll()); syntaxFile.close(); } else { m_editor->loadSyntaxDefinition(":/syntax/cpp.json"); // 回退到内置 C++ }

第二段代码里第一行是追加高亮断点的用法,QHighlighter内部类QHighlightRule如果index设置为 0,整条匹配都会应用格式。index: 1就只看第一个捕获组。有一种常见误用:想高亮函数名但index没改,结果整段func(...)全部变色,这就是 index 没理解到位。

一个额外的建议:如果你需要高亮 HTML 标签内的属性名,建议写\\b[A-Za-z_-]+\\s*=配合 index 捕获属性名,而不是把整条name="value"都涂上一种颜色,后者的视觉噪声非常大。语法规则表的顺序也有讲究:先放关键字,再放函数名,再放字符串和注释。因为 QSyntaxHighlighter 的 setFormat 是后写覆盖前写,字符串里的保留字如果不希望被关键字规则染色,需要把字符串规则放在关键字规则前面。

4.3 为什么不推荐直接修改内置 cpp.json

QCodeEditor 内置的 cpp.json 覆盖了 C++ 关键字、预处理器、数字、注释等常见 token。看起来直接改这个文件最快,但实际上这个文件路径在源码资源里,你改了之后一旦升级库就会被覆盖。正确的做法是把自定义 JSON 作为 qrc 资源放进你的工程,在代码里显式加载,优先级高于内置。同时,内置 cpp.json 的着色规则偏静态,缺少对 C++11/14 新关键字的区分,比如nullptr和constexpr在部分旧版库里没有单独规则,这也是为什么自定义规则表几乎是必做事项。

还有一处隐藏细节是 QCodeEditor 的注释折叠。它支持代码折叠,折叠标记写在注释里,默认是// [fold]和// [/fold]这样的约定。如果你在公司内部做代码生成器,可以用这个折叠约定把自动生成段折叠起来,只露出手写区,交互体验会好很多。这个功能对应的底层是 Qt 的 QTextBlockUserData 和setFoldBlockStart标记,QCodeEditor 把它们封装成了简单的字符串约定。

5. 避坑排查:高亮不生效、折叠失效、MSVC 构建报错的 6 条血泪记录

5.1 高亮全部失效,但代码能编译能链接

现象是编辑器光秃秃一片,像普通 QPlainTextEdit,既没有关键字变色,也没有行号高亮。原因非常隐蔽:QCodeEditor 的高亮器QHighlighter是构造时关联编辑器的,但如果你在加载语法定义之前就setPlainText了大量代码,QSyntaxHighlighter 的重高亮事件没有触发,文本一直停留在“未高亮”状态。

解决方法是重新触发一次高亮:在加载语法定义完成后,调用m_editor->rehighlight()。更稳的方式是调整顺序,先构造编辑器,再加载语法定义,最后设置文本内容。我一般习惯用后者,因为rehighlight()在大文件上是全量重算,代价不小。如果你已经踩了这个坑需要补救,用下面的代码:

// 重新触发高亮 editor->setSyntaxDefinition(editor->syntaxDefinition()); // 或者直接强制重画 editor->viewport()->update();

5.2 自定义 JSON 加载后没有效果,日志也没有报错

这个坑的根源是 JSON 的格式问题。QCodeEditor 的loadSyntaxDefinition对 JSON 的解析依赖 QJsonDocument,但它对color字段的合法性没有做严格校验。如果你写"color": "#569CD6"没问题,但不小心写成"color": "569CD6"(少了#),QColor 构造函数会失败,这个 rule 被静默丢弃。

排查方法比较土但有效:把 JSON 单独复制到一个 Qt 工程里,用QJsonDocument::fromJson解析一遍,再检查每条 rule 里的QColor(colorString).isValid()。我遇到过三次这种问题,都是复制粘贴时丢了#。另一个常见错误是"fontStyle"字段写了"bold italic",而 QCodeEditor 解析时只认单个值,两个样式只生效一个,参考源码里的写法应该用"bold"或"italic"分开写。

5.3 MSVC 构建报:-1: error: dependent '..\..\..\..\..\..\qt\5.15.2\msvc2019_64\include\qtwidgets\...头文件找不到

这个报错在热搜词里出现过,是 Windows 上 Qt 工程最经典的路径依赖错误。现象是 CMake 配置成功,但编译到 QCodeEditor 的某个 .cpp 文件时,编译器报错说找不到 Qt 的qtwidgets相关头文件。原因有且只有一个:你的工程里某个 CMakeLists 用绝对路径引用了 Qt 头文件,或者编译器的 Include 目录被手动改过,导致 cl.exe 用相对路径回退时爆炸。

解决方法是不要手动在 Qt Creator 的构建设置里添加INCLUDEPATH,让 CMake 的target_link_libraries自动传递。检查build目录下的CMakeCache.txt里QT_HEADERS_DIR是否存在,以及CMAKE_PREFIX_PATH是否正确指向 Qt 安装根目录。网上有人用INCLUDE环境变量配 Qt 头文件,那个方案容易造成多版本 Qt 冲突,不推荐。另外如果你用 VS2022 打开 CMake 工程,首次构建会触发 Qt 的 Automatic MOC,如果你的 VS 插件版本较旧,也会报类似的误报错误,升级 Qt VS Tools 即可解决。

5.4 QSearchWidget 在关闭窗口时崩溃

QCodeEditor 内置了查找替换组件 QSearchWidget,但它的父对象指针处理有个小坑。如果你在代码里强制searchWidget->deleteLater()或者让 QCodeEditor 先于 SearchWidget 析构,程序退出时会 double-free。

做法是不要手动管理搜索框生命周期,让 QCodeEditor 自己销毁。如果你确实需要提前移除搜索框,要先调用editor->removeSearchWidget()再 delete,顺序不能反。这个坑在 Qt 5.15 和 Qt 6.2 上都出现过,源码里用的是setParent但没有显式deleteLater,堆对象析构顺序是未定义的。

5.5 中文注释高亮变成乱码方块

这个问题绝大多数出现在 Windows + MSVC 组合下。原因是源码文件和 JSON 资源文件的编码不是 UTF-8,MSVC 在编译字符串字面量时按本地代码页(GBK)解释,导致中文字符串写进源码后变成了乱码,进而显示为方块。

解决措施是让所有源文件和资源文件统一为 UTF-8。我的习惯是在每个 .cpp 文件头部加#pragma execution_character_set("utf-8"),这是只影响 MSVC 的前置指令,不影响 GCC/Clang。注意 JSON 资源文件本身也必须是 UTF-8,且在 Qt 的 .qrc 文件里不要标注错误的 codepage。另外 Qt 6 默认 UTF-8 源码,这个问题会少很多。

5.6 大文件打开卡顿,输入延迟明显

现象是打开 5MB 以上的文件时,编辑器长时间无响应,打开后输入字符有明显延迟。QPlainTextEdit 本身对大文件有块缓存机制,但 QSyntaxHighlighter 默认是逐行全量解析,5MB 的代码文件意味着几千行都要跑一遍正则,成本很高。

QCodeEditor 没有内置分片处理机制,常见做法是关闭高亮后加载,等用户完成编辑再手动重新高亮,或者只对前 N 行应用高亮(日志查看器场景)。具体到参数,setLineNumbersVisible(false)能省掉行号区绘制开销,setAutoIndentation(false)能省掉缩进计算。对于日志查看这类用途,很多人其实不需要语法高亮,直接用 QPlainTextEdit 反而更轻松,这是一个选型问题,需要你对场景诚实。

6. 从能跑到能用:主题切换、搜索跳转与一个验证脚本的技巧

QCodeEditor 的默认样式是浅色底深色字,直接拿给深色 UI 的工具用会很突兀。好消息是它支持setStyleSheet连同行号区和搜索框一起换肤。这个特性经常被忽略,事实上 QCodeEditor 的样式表接口比 QPlainTextEdit 更完整,它可以选中QLineNumberArea的背景色、QSearchWidget的按钮样式,一次性把整个编辑区变成统一风格。建议在启动时根据用户配置选择样式表,然后把样式表字符串独立成一个qss资源文件,方便以后调整。对于做嵌入式 HMI 工具链的开发者,深色主题几乎是刚需,一行setStyleSheet(codeEditorQss)能避免整个界面亮度刺眼的问题。

搜索跳转方面,QCodeEditor 自带 QSearchWidget,但少数源码版本默认不弹出搜索框。做法是做一个快捷键触发,调用editor->showSearchWidget(),然后用setSearchText预置搜索文本。QSearchWidget 支持findNext和findPrevious,底层用的是 QTextDocument 的find函数,不是正则搜索,所以搜索速度对大文件来说不错。搜索框默认是浮动在右上角的独立小窗口,不会挤压编辑区。如果你需要向上翻页逐条高亮当前搜索结果,QSearchWidget 只高亮当前匹配项,不改写全文。如果你需要全文高亮所有匹配项,得自己用QTextEdit::ExtraSelection遍历文本,这是 QCodeEditor 没有封装的部分,不过对大多数查找场景来说,单个高亮的体验也够用了。

最后说一个验证脚本的小技巧。集成完 QCodeEditor 后,为了保证每次改动不破坏既有功能,我会写一个基于 QTest 的冒烟测试:构造一个带 C++ 代码的 QString,设置到编辑器,触发高亮,然后用QTextCursor::select(QTextCursor::WordUnderCursor)遍历所有单词,检查关键 token 的QTextCharFormat::foreground().color()是否与预期一致。这个脚本不用 UI,用QApplication而不是QCoreApplication因为它需要字体和布局系统。跑一次大概消耗一两秒,但能确保你在后续升级库或修改高亮规则时不会把大块的关键字颜色改坏。这个验证方式成本很低,值得作为持续集成的一部分保留。

我自己的习惯是,每次做完一个基于 QCodeEditor 的工具,都会把自定义的 JSON 语法文件和样式表模板整理到同一个资源目录里维护。这个方案的弹性在于:语法规则是可配置的,样式是可切换的,编辑器本体是稳定的,在遇到下一个需要编辑器的场景时只需要复制目录而不是重写代码。这几年我在多个内部工具上用过它,踩过的坑就是上面那六条,写出来希望帮到你。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询