在 Qt 中优雅展示 Markdown 文档——therecipe/QMarkdown 详解与代码示例
在 Qt 应用中集成 Markdown 的编辑与预览功能,最成熟、高效的方案之一就是使用 QMarkdownTextEdit。它提供了一个开箱即用的 Markdown 编辑器组件,能为你节省大量从头开发的时间。

下面我来详细介绍它的核心功能、集成方法,并提供一个完整的代码示例。
🔎 QMarkdownTextEdit 是什么?
QMarkdownTextEdit 本质上是一个基于 QPlainTextEdit 的高功能定制版编辑器。开发者 pbek 将编辑器的核心编辑区与 Markdown 语法高亮等功能深度结合,让开发者可以很方便地把一个专业的 Markdown 编辑器嵌入到自己的应用中。
它的设计初衷是处理纯文本文档,不会自动将 Markdown 代码渲染为 HTML,而是通过高亮代码块、标记特定语法等方式,让编辑过程本身更直观。
✨ 核心特性一览
QMarkdownTextEdit 的功能非常全面,覆盖了日常写作到程序员工作的各种需求:
-
Markdown 语法高亮:自动识别并高亮
# 标题、**粗体**、*斜体*、- 列表等语法元素,让文档结构一目了然。 -
代码块语法高亮:不仅识别 Markdown 的代码块标识符(
```),还能对主流编程语言的代码进行语法高亮,对开发者来说非常实用。 -
交互功能:
-
编辑器功能:支持多级缩进( Tab/Shift+Tab)、快速复制行(Ctrl+Alt+Down)、括号自动闭合等,提升了编辑效率。 -
文本搜索:内置查找( Ctrl+F)、替换(Ctrl+R),并支持正则表达式和全词匹配。 -
行号显示:支持显示行号,方便定位和调试(需要 Qt >= 5.5)。
-
Markdown 特性覆盖:支持加粗、斜体、标题、列表(有序/无序)、链接和图片、引用、表格、代码块(缩进式/围栏式)以及删除线等主流 Markdown 语法。
📦 如何集成到你的项目里?
QMarkdownTextEdit 支持通过 QMake 和 CMake 两种主流构建系统进行集成,它也同时支持 Qt5 和 Qt6 两大版本。
方式一:通过 QMake 集成
-
将源码仓库中的 qmarkdowntextedit.pri文件复制到你的项目目录下。 -
在你项目的 .pro文件中,通过include指令引入它:
include(qmarkdowntextedit/qmarkdowntextedit.pri)
方式二:通过 CMake 集成
-
将 QMarkdownTextEdit的源码目录放至你的项目子目录中。 -
在你项目的 CMakeLists.txt文件中,通过add_subdirectory添加它:
add_subdirectory(qmarkdowntextedit)
在 Qt Designer 中使用完成上述构建系统的配置后,你可以直接在 Qt Designer 中任意拖放一个 QPlainTextEdit 控件并:
-
右键点击该控件,选择“**Promote to…**”。 -
在弹出的对话框中,“Promoted class name”填写 QMarkdownTextEdit,“Base class name”确保是QPlainTextEdit,然后点击“Add”和“Promote”即可。
-
只使用高亮器:不想使用全部功能,只想用它的语法高亮能力,也可以这样做:
// 假设你的编辑器控件叫 plainTextEdit
auto doc = ui->plainTextEdit->document();
// 单独创建高亮器对象,并绑定到指定控件的文档上
auto *highlighter = new MarkdownHighlighter(doc);
💻 一个完整的代码示例
下面是一个完整的 Qt Widgets 应用示例,它创建了一个简单的 Markdown 编辑器,编辑区右侧有一个预览区,会将输入的 Markdown 实时渲染。
#include<QApplication>
#include<QMainWindow>
#include<QSplitter>
#include<QTextEdit>
#include<QTimer>
#include<QFile>
// 引入 QMarkdownTextEdit
#include"qmarkdowntextedit.h"
classMainWindow :public QMainWindow {
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr) : QMainWindow(parent) {
// 1. 创建编辑器组件和高亮器
editor = new QMarkdownTextEdit(this);
// 启用行号显示
editor->showLineNumbers(true);
// 设置一个占位符文本
editor->setPlaceholderText("在这里输入 Markdown...");
// 设置 Markdown 高亮器
MarkdownHighlighter *highlighter = new MarkdownHighlighter(editor->document());
Q_UNUSED(highlighter); // 避免编译器警告
// 2. 创建预览区
preview = new QTextEdit(this);
preview->setReadOnly(true); // 预览区只读
// 3. 将编辑器与预览区放入分割窗口
QSplitter *splitter = new QSplitter(Qt::Horizontal, this);
splitter->addWidget(editor);
splitter->addWidget(preview);
splitter->setSizes({width() / 2, width() / 2});
setCentralWidget(splitter);
setWindowTitle(tr("Markdown 编辑器 - QMarkdownTextEdit 示例"));
resize(1000, 700);
// 4. 实时预览:将编辑器内容变化与预览更新关联
connect(editor, &QMarkdownTextEdit::textChanged, this, &MainWindow::updatePreview);
// 5. 初始加载一些示例文本
QTimer::singleShot(0, this, &MainWindow::loadExampleText);
}
private slots:
voidupdatePreview(){
if (!preview) return;
// 获取编辑区当前 Markdown 文本
QString mdText = editor->toPlainText();
// 方法一:利用 QTextDocument 内置的 Markdown 转换 (Qt 5.14+)
// ---------------------------------------------
// 这是最简单、最直接的方法,无需引入额外库
QTextDocument doc;
doc.setMarkdown(mdText); // 将 Markdown 文本设置到文档
QString html = doc.toHtml(); // 获取转换后的 HTML
// 方法二:如果需要扩展语法支持 (如 LaTeX / Mermaid)
// ---------------------------------------------
// 可以将 mdText 传递给外部转换库 (如 cmark, hoedown, discount 等)
// 或使用 Qt WebEngine 加载 JavaScript Markdown 渲染器
// 这里为了保持示例简单,使用方法一
// 将 HTML 设置到预览区
preview->setHtml(html);
}
voidloadExampleText(){
QString exampleText =
"# 欢迎使用 QMarkdownTextEdit!\n\n"
"这是一个 **功能强大** 的 Markdown 编辑器组件。\n\n"
"## 主要特性\n\n"
"- 实时语法高亮\n"
"- 代码块高亮\n"
"- 行号显示\n"
"- 搜索/替换\n\n"
"## 代码示例\n\n"
"```cpp\n"
"#include <iostream>\n"
"int main() {\n"
" std::cout << \"Hello, Markdown!\" << std::endl;\n"
" return 0;\n"
"}\n"
"```\n\n"
"> 这是一个引用块。\n\n"
"更多信息请访问 [GitHub 仓库](https://github.com/pbek/qmarkdowntextedit)。";
editor->setPlainText(exampleText);
}
private:
QMarkdownTextEdit *editor;
QTextEdit *preview;
};
intmain(int argc, char *argv[]){
QApplication app(argc, argv);
MainWindow window;
window.show();
return app.exec();
}
// 如果你在使用 Qt 5 且编译时遇到 moc 问题,请确保该文件被包含在项目的 HEADERS 中,
// 或者将上述类定义和实现分开到头文件和源文件中。
#include"main.moc"
-
构建配置:请务必根据你使用的构建工具(QMake 或 CMake)正确集成 QMarkdownTextEdit。 -
Qt版本要求:代码中用于预览的 doc.setMarkdown()方法要求 Qt 5.14 或更高版本。 -
依赖管理: QMarkdownTextEdit本身是纯头文件/源码的组件,无需安装额外的动态库或静态库,直接包含源文件即可编译。
如果你需要更高级的渲染(例如支持 LaTeX 或 Mermaid 图表),可以考虑将上述代码中的 updatePreview() 方法替换为连接一个本地的 HTTP 服务,通过 QWebEngineView 加载一个成熟的 JavaScript 库(如 marked.js + highlight.js + katex)来进行渲染。
💎 总结与补充
总的来说,QMarkdownTextEdit 为你提供了一个近乎 QPlainTextEdit 的平替选择,是一个强大、高效的 Markdown 编辑器组件。如果你的应用场景是纯编辑,这个库几乎不需要你做额外工作。
-
常用特性快捷键: -
** Ctrl+Click**:打开链接或文件路径。 -
** Ctrl+Alt+Down**:复制当前行。 -
** Ctrl+F/Ctrl+R**:查找与替换。 -
常见问题解决: -
编译错误:确保你的 Qt 版本支持所用特性,并已正确配置构建系统以包含库的源文件和头文件。 -
高亮不生效:检查是否正确创建了 MarkdownHighlighter实例并绑定到了目标控件上。 -
老版本 Qt (5.14 以下) 预览方案: -
**使用 QTextDocumentWriter**:利用 Qt 内置的QTextDocumentWriter将文档转为 HTML。 -
**使用 QWebEngineView**:在应用内嵌入一个轻量级浏览器控件。 -
使用外部库:集成 cmark或hoedown等高性能 C 库进行转换。
如果你计划创建一个兼具所见即所得体验的编辑器,也可以考虑 QMarkdownView(主要提供预览功能)或功能更全面的 QMarkdowner,它们在这个方向上探索得更深。
夜雨聆风