尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Qt QTextEdit 简单使用:字体/颜色/图片配置与最大行数限制,顺带聊聊 TaoToken 统一 Key 通道

Qt QTextEdit 简单使用:字体/颜色/图片配置与最大行数限制,顺带聊聊 TaoToken 统一 Key 通道 1. 从一次日志窗口的翻车说起QTextEdit 是 Qt Widgets 里最常被拿来当“万能文本框”的控件既能当只读日志窗也能当富文本编辑器还能塞图片、改颜色、限制行数。但真到项目里很多人第一次用它都会踩同一类坑——字体设了没生效、颜色只改了一半、图片路径在 Windows 上死活加载不出来、setMaximumBlockCount设了 5 结果第 6 行把第 1 行顶掉却不知道去哪了。这篇就围绕 Qt QTextEdit 的简单使用展开字体、颜色、大小怎么配图片怎么插行数和字数怎么取最大行数怎么限制。同时我会顺带聊一个实际开发里很省事的做法用 TaoToken 统一 Key/API 通道把 AI 辅助补全接进你的 Qt 工具链不用每个模型单独维护一套密钥和地址。适合正在写 Qt 桌面端、需要日志面板或富文本输入框的同学代码可以直接复制进项目跑。2. 先把 QTextEdit 的基础配置跑通2.1 字体、颜色、大小的三种设置方式QTextEdit 设置字体有三个层级搞混了就会出现“我明明设了字体却没变”的情况。第一种是控件级直接对整个 QTextEdit 生效QFont font QFont(Microsoft YaHei, 14); font.setBold(true); font.setItalic(false); ui-textEdit-setFont(font);第二种是光标级只影响接下来插入的文本用QTextCharFormat配合QTextCursorQTextCharFormat fmt; fmt.setForeground(Qt::blue); fmt.setFont(QFont(YouYuan, 20, QFont::Bold, true)); QTextCursor cursor ui-textEdit-textCursor(); cursor.mergeCharFormat(fmt);第三种是文档级通过document()-setDefaultFont()影响整篇文档的默认样式。实际项目里我一般用控件级定基调光标级做局部高亮比如日志里 ERROR 行标红、WARN 行标黄。2.2 列出系统支持的中文字体不确定字体名写什么可以先枚举出来看看QFontDatabase fontDatabase; for (auto it : fontDatabase.families(QFontDatabase::SimplifiedChinese)) { qDebug() it; }注意families()返回的是字体族名Windows 上“微软雅黑”对应Microsoft YaHei“幼圆”对应YouYuan写错一个字母就会回退到默认字体而且不报错这是最常见的隐形坑。2.3 插入图片的正确姿势QTextEdit 插图片有两种方式。一种是 HTML 片段QTextDocumentFragment fragment QTextDocumentFragment::fromHtml(img srcc:/Setting.png); ui-textEdit-textCursor().insertFragment(fragment);另一种是直接操作文档资源QTextDocument *doc ui-textEdit-document(); doc-addResource(QTextDocument::ImageResource, QUrl(mydata://logo), QImage(:/images/logo.png)); ui-textEdit-textCursor().insertImage(mydata://logo);路径分隔符建议统一用正斜杠/Windows 的反斜杠在 HTML 里是转义字符c:\Setting.png很容易解析失败。资源文件用:/前缀走 Qt 资源系统最稳。2.4 获取行数、字数与最大行数限制int lineCount ui-textEdit-document()-lineCount(); int charCount ui-textEdit-document()-characterCount(); qDebug() 行数 lineCount 字数 charCount; ui-textEdit-document()-setMaximumBlockCount(5);这里有个关键区别lineCount()数的是视觉行自动换行也算blockCount()数的是段落块一个回车才算一块。日志窗口通常用blockCount()更符合直觉。setMaximumBlockCount(5)限制的是块数量超出后最旧的块会被自动删除适合做滚动日志。字数用characterCount()会包含换行符要精确统计得自己遍历。3. TaoToken 前置统一 Key 通道怎么接3.1 为什么要在 Qt 项目里接统一通道写 Qt 工具时经常想加个 AI 辅助功能比如代码补全、注释生成、日志摘要。问题是不同模型厂商的 Key、Base URL、请求格式都不一样散落在代码里维护成本很高。TaoToken 提供的是统一 Key/API 通道一个 Key 走一套 OpenAI 兼容接口切换模型只改模型名不用动请求代码。官网地址是 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content API 入口是 https://taotoken.net/api 注意 API 地址不带 UTM 参数。3.2 拿 Key 与配置文件骨架先去控制台创建 API Key入口在 https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_contentconsoleutm_campaignrewrite Key 管理页在 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewrite 。拿到 Key 后在 Qt 项目里放一个config.toml[ai] base_url https://taotoken.net/api api_key sk-你的Key model claude-sonnet-4-5 timeout_ms 30000 max_tokens 1024 [editor] font_family Microsoft YaHei font_size 14 max_blocks 500Qt 里解析 TOML 可以用 toml 或者自己写个简单解析也可以先用 QSettings 存 ini 过渡。Key 不要硬编码进源码提交到仓库用环境变量或本地配置文件加.gitignore。3.3 在 QTextEdit 里触发 AI 补全思路很简单用户选中一段文本按下快捷键把选中内容发给统一通道返回结果插到光标后面。void MainWindow::onAiComplete() { QString selected ui-textEdit-textCursor().selectedText(); if (selected.isEmpty()) return; QNetworkAccessManager *mgr new QNetworkAccessManager(this); QNetworkRequest req(QUrl(https://taotoken.net/api/v1/chat/completions)); req.setHeader(QNetworkRequest::ContentTypeHeader, application/json); req.setRawHeader(Authorization, QString(Bearer %1).arg(apiKey).toUtf8()); QJsonObject body; body[model] modelName; body[max_tokens] 1024; QJsonArray messages; messages.append(QJsonObject{{role, user}, {content, 请补全以下代码\n selected}}); body[messages] messages; QNetworkReply *reply mgr-post(req, QJsonDocument(body).toJson()); connect(reply, QNetworkReply::finished, this, []() { QJsonDocument doc QJsonDocument::fromJson(reply-readAll()); QString content doc.object()[choices].toArray()[0] .toObject()[message].toObject()[content].toString(); ui-textEdit-textCursor().insertText(\n content); reply-deleteLater(); }); }长期做编码辅助或 Agent 类功能可以看 Coding Planhttps://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding-planutm_campaignrewrite 。想先验证模型输出效果用模型对话页https://taotoken.net/models?utm_sourcetaotoken_aicg_blog_endutm_contentmodelsutm_campaignrewrite 。接入细节查文档https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 。4. 可复制配置完整初始化代码把前面几块拼起来一个可直接跑的 QTextEdit 初始化函数void MainWindow::initTextEdit() { // 基础字体 QFont font(Microsoft YaHei, 14); ui-textEdit-setFont(font); ui-textEdit-setReadOnly(false); ui-textEdit-setAcceptRichText(true); // 最大块数做滚动日志 ui-textEdit-document()-setMaximumBlockCount(500); // 插入一行蓝色加粗标题 QTextCharFormat titleFmt; titleFmt.setForeground(Qt::darkBlue); titleFmt.setFont(QFont(Microsoft YaHei, 16, QFont::Bold)); QTextCursor cursor ui-textEdit-textCursor(); cursor.insertText( 运行日志 \n, titleFmt); // 插入图片 QTextDocumentFragment frag QTextDocumentFragment::fromHtml(img src:/icons/status.png width24); cursor.insertFragment(frag); cursor.insertText(\n); // 统计 qDebug() 块数 ui-textEdit-document()-blockCount() 字数 ui-textEdit-document()-characterCount(); }追加日志时用append()会自动换行并滚动到底部比手动移动光标省事。要按级别上色封装一个appendLog(level, msg)void MainWindow::appendLog(const QString level, const QString msg) { QTextCharFormat fmt; if (level ERROR) fmt.setForeground(Qt::red); else if (level WARN) fmt.setForeground(QColor(#B8860B)); else fmt.setForeground(Qt::black); QTextCursor cursor(ui-textEdit-document()); cursor.movePosition(QTextCursor::End); cursor.insertText(QString([%1] %2\n).arg(level, msg), fmt); }5. 验证请求与成功结果配置完先别急着接 AI分两步验证。第一步验证 QTextEdit 本身运行程序确认字体是微软雅黑 14 号标题行是深蓝加粗图片正常显示连续追加 600 行日志后只剩最后 500 块控制台打印的块数和字数随追加递增。第二步验证统一通道在模型对话页发一条测试消息确认 Key 有效、模型名正确、返回正常。然后在 Qt 里触发onAiComplete()选中一段代码按快捷键观察 QTextEdit 是否在光标后插入补全内容。成功时你会看到选中文本下方多出一段 AI 生成的代码且格式与原有字体一致。如果返回内容带 Markdown 标记可以在插入前做一次简单清洗或者用QTextDocumentFragment::fromMarkdown()转成富文本再插入这样代码块和列表能保留样式。6. 本篇常见错排查字体设了没生效检查字体族名拼写用QFontDatabase枚举确认如果 QTextEdit 已经setAcceptRichText(true)且内容来自 HTMLHTML 里的样式会覆盖控件字体需要改 HTML 或对光标单独设格式。颜色只改了一半mergeCharFormat只影响当前选区或后续插入已存在的文本不会变。要改已有文本得先选中再 merge或者遍历文档块逐个设置。图片不显示路径用正斜杠资源文件确认已加入.qrc并编译HTML 里的width属性部分 Qt 版本支持有限建议用QTextImageFormat精确控制尺寸。最大行数没限制住setMaximumBlockCount限制的是块不是视觉行自动换行的长文本仍会占多行。要按视觉行限制得自己监听contentsChanged手动裁剪。请求返回 401 或超时检查 Key 是否带Bearer前缀、Base URL 是否误加了 UTM 参数、网络是否可达。接入报错优先查 API Keys 页和接入文档入口分别是 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewrite 和 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 。JSON 解析崩溃choices数组为空时直接取[0]会越界先判断reply-error()和数组长度再取值这是网络请求里最容易忽略的一步。把 QTextEdit 的样式配置和统一通道的请求封装成两个独立模块后面换模型、改主题都只动一处维护起来会轻松很多。
返回列表