十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

QT,TaoToken 先给 Codex 填 Base URL,富文本 findNext 还查不到?

QT,TaoToken 先给 Codex 填 Base URL,富文本 findNext 还查不到? QT 的 QTextEdit 富文本编辑器里MainWindow5_3::findNext明明调用了ui-textEdit-find(str2, QTextDocument::FindBackward)输入框里的词却还是查不到最后只打印“未查找到信息”。如果你打算让 Codex 帮你排这段先别急着改FindBackward先把 TaoToken 的通道配通打开 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_end 创建 API Key模型 ID 以页面里的模型广场为准然后把~/.codex/config.toml的base_url填成 https://taotoken.net/api。这样 Codex 才能稳定读你贴出的mainwindow5_3.cpp、mysyntaxhiglighter.cpp和 Qt Creator 里的qDebug输出继续对照findNext的查找方向、blockNumber/columnNumber和光标移动逻辑。QT 的 QTextEdit 富文本不是记事本那种纯文本。你插入了字体、表格、编号、图片又给char做了语法高亮查找时看到的是最终排版后的文档模型不是 HTML 源码。原文里查找对话框只有一个按钮文本写着“查找上一个”槽却连到了findNext而findNext又用了QTextDocument::FindBackward。这个错位会让“下一个”和“上一个”的行为混在一起查不到并不奇怪。排查时要分两层看一层是 QTextEdit 的查找方向与光标起点另一层是 Codex 的 Base URL 是否真的指向https://taotoken.net/api。两件事都对了才能把问题压到findNext本身。1.findNext里用了FindBackward为什么“查找上一个”也像查不到1.1 先看MainWindow5_3::textFind和按钮绑定原文的textFind()只做了一件事findDialog-show()。查找对话框本身是非模态的用户可以一边看编辑器一边输入查找词。问题出在按钮创建和信号连接上代码里q_pushbutton-setText(tr(查找上一个))紧接着connect(q_pushbutton, QPushButton::clicked, this, MainWindow5_3::findNext)。这意味着按钮文字告诉用户“上一个”实际执行的是findNext。而findPrevious被注释掉了所以文档里根本没有一个真正的“查找上一个”入口。再看findNext()内部QString str2 lineEdit-text()从行编辑框取词然后调用ui-textEdit-find(str2, QTextDocument::FindBackward)。如果找不到打印“未查找到信息”然后ui-textEdit-moveCursor(QTextCursor::End)把光标推到文档末尾。这里有两个容易踩的点第一槽名和按钮文本不一致用户以为在找下一个实际方向可能相反第二未命中后强制移动光标到末尾下一次查找的起点被改掉了。如果你把这段贴给 Codex建议先让它只看行为不要急着改代码。可以让它回答三个问题这个按钮实际触发哪个槽这个槽使用的查找标志是什么方向未命中后光标去了哪里这三个问题答完再让它给修改建议。否则一上来就换FindBackward可能把“上一个”和“下一个”一起改坏。1.2QTextEdit::find的方向、光标起点和FindBackward语义QTextEdit::find的默认行为是从当前光标位置开始向文档末尾方向查找。也就是说默认是“向前找下一个”。如果你传入QTextDocument::FindBackward方向反过来变成从当前光标位置向文档开头方向查找。原文注释里写“默认向前查找FindBackward向后”大方向没错但后面又写“FindCaseSensitively 0x00002,不区分大小写”这句是反的FindCaseSensitively表示区分大小写不设置它才默认不区分。常用的查找标志可以这样对照查找标志实际作用排查时注意默认不传标志从光标向文档末尾找适合“查找下一个”QTextDocument::FindBackward从光标向文档开头找适合“查找上一个”QTextDocument::FindCaseSensitively区分大小写加上后Char和char不等价QTextDocument::FindWholeWords匹配整个单词查char不会命中character原文的findNext和findPrevious都写了FindBackward。如果“查找下一个”也走这个方向用户在文档中间点一下可能先找到前面的匹配项看起来像“上一个”再点一次又可能跳到更前面。用户想要的“从当前位置往后找”和实际行为不一致就会觉得“查不到”。排查时先确认按钮到底该连哪个槽再确认槽里该传什么标志不要只看按钮文字。另外QTextEdit::find从光标当前位置开始。如果当前已有选区查找起点可能受选区影响。有人在查找前刚刚选中了另一个词或者光标停在文档末尾下一次查找就会从那里开始。想要稳定可以在执行查找前先判断ui-textEdit-textCursor().hasSelection()必要时把光标移到选区末尾或开头但这要配合“上一个/下一个”的方向来定。1.3 未命中后moveCursor(QTextCursor::End)如何把下一次搜索带偏原文findNext()未命中时执行ui-textEdit-moveCursor(QTextCursor::End)。这行代码单看很合理找不到就把光标放到末尾。但放在查找逻辑里会带来副作用。假设文档第一段有char光标本来在中间你点“查找下一个”。如果方向是默认向前从中间往末尾找找不到第一段的char于是打印“未查找到信息”光标被移到末尾。下一次你再点“查找下一个”从末尾继续向末尾找当然还是找不到。用户会觉得“明明文中有为什么查不到”。如果findNext用了FindBackward未命中后光标在末尾下一次从末尾向开头找反而可能找到。但这时的行为已经不是“下一个”而是“从末尾反向找”。所以这行moveCursor(QTextCursor::End)会放大方向错位带来的困惑。正确做法通常是分方向处理查找下一个未命中时可以把光标移到QTextCursor::Start再试一次形成从头回绕查找上一个未命中时可以把光标移到QTextCursor::End再试一次形成从尾回绕。回绕后仍找不到才打印“未查找到信息”。还要注意QTextEdit::find本身不会自动帮你回绕。它找到末尾就结束找不到就返回false。所以“循环查找”需要你自己写一次重试。重试前要改光标位置重试时方向要和按钮语义一致。否则用户点三次光标在文档里乱跳查找结果就会变得不可预测。2. 富文本不是纯文本QTextDocument结构让查找结果容易误判2.1QTextFrame、QTextBlock、QTextTable与blockNumber/columnNumberQTextEdit 背后是QTextDocument文档结构由QTextFrame、QTextBlock、QTextTable、QTextList等元素组成。原文构造函数里拿到QTextDocument *qDoc ui-textEdit-document()再拿根框架qDoc-rootFrame()。根框架下面可以有文本块、子框架、表格。插入表格后每个单元格里也会形成文本块插入列表后列表项也是文本块。查找命中的位置用textCursor().blockNumber()和textCursor().columnNumber()输出。这两个值很容易被误认为“行号和列号”。实际上输出值真实含义排查时注意blockNumber()文本块序号从 0 开始不是物理行号表格单元格也会影响序号columnNumber()当前文本块内的字符偏移不是整行全局列号firstLineNumber()布局后的首行行号自动换行后可能变化selectedText()当前选中的文本找到后用它确认命中了什么原文showTextBlock()里用qblock.firstLineNumber()和qblock.length()遍历这能帮助理解块的结构。排查findNext时如果b_find为真不要只看blockNumber和columnNumber就下结论。把selectedText()一起打印出来确认命中的是不是你要找的词。如果selectedText()是空或者命中的是表格里的另一个块就要回头看光标位置和查找方向。2.2 插入字体、表格、编号、图片后哪些内容能被find查到原文实现了插入字体、表格、编号、图片、查找和语法高亮。这些功能对查找的影响不一样。字体格式、颜色、下划线属于字符格式不改变文本内容。你把“测试一下字体呢”设成宋体、蓝色背景、黄色前景查找“测试一下字体呢”仍然可以命中。表格和列表会改变文档块结构但单元格和列表项里的纯文本仍然能被QTextEdit::find搜索。也就是说你在表格里输入char查找char通常能命中只是blockNumber会变。图片不一样。原文insertImage()里设置qtext_image_format.setName(duck_dance.png)然后insertImage。图片在文档里是一个对象不是可搜索的普通文本。你查duck_dance.pngQTextEdit::find不会命中图片文件名。HTML 插入也一样。原文构造函数最后执行ui-textEdit-append(tr(h1font colorgray 测试使用HTML方式/font/h1))查找“测试使用HTML方式”可以因为标签被解析成了格式查找font、color、gray这类源码片段不行因为文档模型里它们不是可见文本。排查时可以把要查找的内容分成三类可见文本、格式属性、图片对象。QTextEdit::find主要查第一类。如果你要按格式或图片名定位需要走QTextDocument的块遍历、QTextFragment的字符格式或者自定义查找逻辑而不是继续纠结FindBackward。2.3 语法高亮不改变文本char变蓝不等于可查标签原文的MySyntaxHiglighter::highlightBlock用QRegExp匹配\\bchar\\b然后setFormat(index2, length2, my_format)把匹配到的char设成粗体、蓝色。这里要记住语法高亮只改格式不改文本。char还是那两个字符不会变成span stylecolor:bluechar/span这种源码。查找char仍然按纯文本匹配高亮不影响命中结果。但如果你误以为“蓝色 char”是一个可查找的标记就会走偏。比如你查blue、color、format这些都不是文档里的可见文本当然找不到。再比如你查Char如果没开FindCaseSensitively默认不区分大小写可能命中如果开了区分大小写就可能不命中。语法高亮本身不参与查找它只是绘制层设置。另外QRegExp在现代 Qt 里已经不是首选QRegularExpression更常见。但你现在排的是查找问题不必顺手重写高亮类。先把findNext的方向、光标和回绕修正再用 Codex 对照highlightBlock的影响。Codex 可以解释\bchar\b的匹配范围也可以提醒你setFormat不会改变QTextDocument::find的结果但编译和运行仍然要在本地 Qt Creator 里做。3. 让 Codex 对着findNext排查前先给它配通 TaoToken 的 Base URL3.1 打开 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_end 创建 Key 和确认模型 ID准备材料不复杂一份能编译的 QT 工程包含mainwindow5_3.h、mainwindow5_3.cpp、mysyntaxhiglighter.h、mysyntaxhiglighter.cpp一个可用的 Codex 入口一把 API Key。打开 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_end 注册并登录在控制台里创建 API Key占位符统一记成YOUR_API_KEY。模型 ID 不要凭记忆写去模型广场看当时列表以页面显示为准。原文没有指定任何模型名这里也不要自己编一个带日期后缀的 ID。拿到 Key 后先分清两个地址给人点的官网落地页是https://taotoken.net/?utm_sourcetaotoken_aicg_blog_end用于注册、创建 Key、看模型广场、看用量填进 Codex 的 Base URL 是https://taotoken.net/api末尾不要加/v1。这两个地址混用是后面请求不通的常见原因。官网首页不是 API 地址/api也不要被改写成/api/v1。3.2~/.codex/config.toml里填base_url https://taotoken.net/apiCodex 的配置文件通常放在~/.codex/config.toml。下面是一份可复制的结构其中模型 ID 仍然用占位符你按模型广场替换。注意不要把 Claude Code 的ANTHROPIC_*环境变量套到 Codex 上Codex 走的是model_provider和base_url。# ~/.codex/config.toml model_provider taotoken model YOUR_MODEL_ID [model_providers.taotoken] name TaoToken base_url https://taotoken.net/api env_key TAOTOKEN_API_KEY然后在启动 Codex 的终端里设置环境变量。Linux 或 macOS 可以这样export TAOTOKEN_API_KEYYOUR_API_KEYWindows PowerShell 可以这样$env:TAOTOKEN_API_KEYYOUR_API_KEY如果你的 Codex 版本要求环境变量名与配置里的env_key一致就保持TAOTOKEN_API_KEY。Key 从 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_end 创建不要写进代码仓库。Base URL 必须保持https://taotoken.net/api不要因为看到某些 OpenAI 兼容示例就补上/v1也不要填官网首页。3.3 验证请求把报错、代码、查找词一起交给 Codex配完后不要直接让 Codex 替你改整个工程。先做一次小验证在 Codex 里发一条简单消息确认请求能通。然后贴排查材料包括textFind()、findNext()、findPrevious()、按钮连接代码以及你实际输入的查找词。可以这样提问“下面是我 QT QTextEdit 的查找代码。按钮文本是‘查找上一个’但 connect 到findNextfindNext里用了QTextDocument::FindBackward。请逐行解释1. 这个按钮实际执行的方向是向前还是向后2. 未命中后moveCursor(QTextCursor::End)对下一次查找有什么影响3.blockNumber和columnNumber在这里分别代表什么4. 给出修改建议。只解释和给代码建议不要替我编译。”如果请求失败先查三个点Key 是否从官网创建、base_url是否误写成带/v1、模型 ID 是否在模型广场里存在。不要一失败就换网络地址。Codex 只负责生成、解释、对照代码QT 工程要在本地 Qt Creator 里编译运行把qDebug输出再贴回对话。4. 修正findNext与findPrevious的可运行代码4.1 把“下一个”和“上一个”分成两个按钮、两个槽原文查找对话框只有一个按钮文本和槽还错位。先改 UI 逻辑创建两个按钮分别连接findNext和findPrevious。这样用户点“查找下一个”就走向后点“查找上一个”就走向前不再靠猜。QPushButton *btnNext new QPushButton(tr(查找下一个), findDialog); QPushButton *btnPrev new QPushButton(tr(查找上一个), findDialog); connect(btnNext, QPushButton::clicked, this, MainWindow5_3::findNext); connect(btnPrev, QPushButton::clicked, this, MainWindow5_3::findPrevious); QVBoxLayout *layout new QVBoxLayout(findDialog); layout-addWidget(lineEdit); layout-addWidget(btnNext); layout-addWidget(btnPrev); findDialog-setLayout(layout);textFind()可以继续只负责显示对话框但最好顺带把对话框带到前面void MainWindow5_3::textFind() { findDialog-show(); findDialog-raise(); findDialog-activateWindow(); lineEdit-setFocus(); }这样查找词输入框会直接获得焦点用户不用再点一次。4.2 未命中回绕与光标位置Start/End 该选哪个修正思路是findNext默认向前未命中后把光标移到开头再试一次findPrevious使用FindBackward未命中后把光标移到末尾再试一次。找到后打印selectedText()、blockNumber()、columnNumber()方便和原文输出对照。void MainWindow5_3::findNext() { const QString needle lineEdit-text(); if (needle.isEmpty()) { qDebug() 查找内容为空; return; } QTextDocument::FindFlags flags; // 默认向前等价于查找下一个 bool found ui-textEdit-find(needle, flags); if (!found) { ui-textEdit-moveCursor(QTextCursor::Start); found ui-textEdit-find(needle, flags); } QTextCursor cursor ui-textEdit-textCursor(); if (found) { qDebug() 找到: cursor.selectedText() 块号: cursor.blockNumber() 列号: cursor.columnNumber(); } else { qDebug() 未查找到信息; } } void MainWindow5_3::findPrevious() { const QString needle lineEdit-text(); if (needle.isEmpty()) { qDebug() 查找内容为空; return; } QTextDocument::FindFlags flags QTextDocument::FindBackward; bool found ui-textEdit-find(needle, flags); if (!found) { ui-textEdit-moveCursor(QTextCursor::End); found ui-textEdit-find(needle, flags); } QTextCursor cursor ui-textEdit-textCursor(); if (found) { qDebug() 找到: cursor.selectedText() 块号: cursor.blockNumber() 列号: cursor.columnNumber(); } else { qDebug() 未查找到信息; } }这段代码没有改变你的文档结构只修正了方向、回绕和输出。注意moveCursor(QTextCursor::Start)与moveCursor(QTextCursor::End)是回绕起点不是每次查找前都移动。如果每次查找前都移动用户连续点“下一个”就会重复命中文档开头。4.3 查找表格文本、HTML 插入文本和图片占位用一份测试文档验证修正后的逻辑第一段写char a;第二段用语法高亮显示char再插入一个 2x2 表格在单元格里写char table;再用append插入一段 HTML 文本。然后分别查char、table、测试使用HTML方式。你应该能看到char在普通段落、表格单元格、高亮段落里都能命中但命中位置对应的blockNumber不同table只在表格单元格里命中测试使用HTML方式能命中但font、gray不能命中。图片占位不用查文件名。你可以在插入图片后在图片旁边输入一个可见标记比如[duck]查找这个标记。这样查找结果和图片对象分开排查看起来更清楚。原文insertImage()把duck_dance.png放在 debug 目录这是资源路径问题不是查找问题。图片能不能显示和find能不能命中是两条线。5. 用 Codex 继续对照findNext输出块号、列号、选区5.1 让 Codex 解释blockNumber与columnNumber的真实含义把修正后的findNext和一段实际输出贴给 Codex让它解释每个数字。不要只问“为什么查不到”要给出上下文查找词、按钮、命中结果、selectedText、blockNumber、columnNumber。示例输出可以写成找到: char 块号: 0 列号: 5 找到: char 块号: 2 列号: 0 找到: char 块号: 5 列号: 12Codex 可以帮你判断这些块号是否合理列号是不是当前块内偏移表格单元格是否被算成独立文本块。它也能提醒你columnNumber()不是全局列号blockNumber()不是屏幕行号。原文showTextBlock()里的firstLineNumber()和length()可以和这些输出对照但不要混为一谈。如果selectedText()是char说明查找命中正确问题只是位置解释如果selectedText()是空或别的词说明光标和查找方向仍有问题。让 Codex 按这两个分支给排查路径不要让它直接改代码后不解释。5.2 把本地 Qt Creator 的运行结果贴回去而不是让 Codex 直接执行AI 编程工具不能替你直连生产库、生产机器去执行操作也不能替你在本地编译 QT 工程。Codex 在这个场景里只做三件事生成或解释代码、对照查找逻辑、分析你贴回的qDebug输出。编译、运行、点击按钮、复制输出都要在本地 Qt Creator 或你惯用的 QT 开发环境里完成。推荐流程是先在 Qt Creator 里编译运行打开查找对话框输入char点“查找下一个”把控制台输出复制出来再点“查找上一个”复制输出然后换成Char、character、table各试一次。把这些结果连同findNext、findPrevious代码一起交给 Codex。这样它看到的不是想象而是实际行为。它给出的修改建议再回到本地编译验证形成闭环。5.3 一个排查清单从找不到到找到要核对什么排查QTextEdit富文本查找可以按下面清单逐项过核对项要确认什么常见错误按钮文本“下一个”和“上一个”是否分开按钮写“上一个”槽连findNext查找标志findNext是否默认向前两个槽都用FindBackward光标起点查找前光标在哪里未命中后被移到末尾下一次从末尾找回绕逻辑找不到时是否从头或从尾重试没重试误以为文档里没有大小写是否需要区分大小写注释看反以为默认区分全词匹配是否只想匹配完整单词查char命中characterHTML 标签是否在查源码标签查font、gray查不到图片对象是否在查图片文件名图片不是文本find不命中表格文本是否查的是单元格里的可见文本blockNumber与普通段落不同输出信息是否打印selectedText只看行列号不知道命中了什么如果这份清单每项都过一遍还能从 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_end 的控制台确认 Key 和用量正常那么问题基本就落在 QT 查找逻辑本身而不是通道配置。6. 配通之后回控制台看这次调用继续改 QT 查找6.1 在模型对话里验证 KeyCodex 配置保存后先在 TaoToken 模型对话 里用同一把 Key 发一条测试消息确认模型 ID 和 Base URL 没填错。如果这里能正常返回再去 Codex 里贴findNext的代码和qDebug输出排查效率会高很多。模型对话里也可以先试问一句“QT QTextEdit 的find默认方向是什么” 看看返回是否正常。6.2 Coding Plan / 创建 Key / 文档 deep link如果后面要长期让 Codex 帮你追 QT 查找、语法高亮和富文本结构可以看 Coding Plan。Key 仍在 控制台 API Keys 创建模型与注册入口是 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_end 。如果这次调用在控制台里能看到记录说明 Key 和 https://taotoken.net/api 都没问题接着回到 Qt Creator 里点一次“查找下一个”把新的qDebug输出贴回 Codex继续对照findNext吧。
返回列表