ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

Delphi7 里 Image 与 SpeedButton 组件配 TaoToken:从零搭一个可复用的 AI 工具调用面板

Delphi7 里 Image 与 SpeedButton 组件配 TaoToken:从零搭一个可复用的 AI 工具调用面板 1. Delphi7 桌面端做 AI 工具调用面板为什么绕不开 Image 和 SpeedButton如果你手上还有一套 Delphi7 的老项目想给它加一个「AI 工具调用面板」最省事的做法不是换框架而是直接用 VCL 自带的 Image 和 SpeedButton 拼一个可视化面板。Image 负责状态图标空闲、请求中、成功、失败SpeedButton 负责触发按钮发请求、清空、复制结果两者配合就能做出一个能看、能点、能跑通真实调用的桌面小工具。这篇面向的是还在用 Delphi7 的桌面开发者尤其是那种「不想动主工程结构只想加一个独立面板」的场景。核心检索词就三个Delphi7、Image 组件、SpeedButton 组件。我会把 Image 的 Align 和 Stretch、SpeedButton 的 Flat、Cursor、Layout、Transparent、Margin、Spacing 这些属性讲清楚然后接上 TaoToken 的统一 Key/API 通道给出一份可复制的 settings.json 和 config.toml 骨架最后让 SpeedButton 点下去真的能拿到模型返回。老 IDE 不代表不能接新能力。Delphi7 的 VCL 控件虽然年代久但事件模型清晰、属性直观用来做「按钮触发 图标反馈」这种交互反而比很多新框架更直接。下面从面板布局开始一步步搭到真实请求返回。2. 前置准备TaoToken 统一 Key 与 API 通道在写 Delphi 代码之前先把通道准备好。TaoToken 的作用是把多家模型的调用收敛成一个统一的 Key 和统一的 API 入口这样你在 Delphi 里只需要维护一套请求逻辑不用为每个模型写不同的鉴权。你需要做三件事第一拿到 API Key。登录后进入控制台在 API Keys 页面创建一个 Key复制保存。这个 Key 就是 Delphi 里要填的凭证。第二确认 API 基地址。统一入口是https://taotoken.net/api注意这里不带任何查询参数代码里拼接路径时用这个前缀。第三选一个你要调用的模型名。模型对话页面可以看到当前可用的模型列表先记下一个后面写进配置。相关入口我列一下方便你对照操作控制台https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_contentconsoleutm_campaignrewriteAPI Keyshttps://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewrite接入文档https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite模型对话https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_contentchatutm_campaignrewrite注意Key 只放在本地配置文件里不要硬编码进 .pas 源码更不要提交到版本库。Delphi7 项目经常用 ini 或 json 存配置这里我们用 json toml 双份方便你按习惯选。如果你后面要做长期编码或 Agent 类任务可以了解 Coding Plan入口是 https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding-planutm_campaignrewrite 。本篇先聚焦单次调用面板。3. 可复制配置settings.json 与 config.toml 骨架Delphi7 本身没有内置 JSON 解析但你可以用 SuperObject 或者简单的字符串拼接。为了让你先跑通我把配置拆成两份一份 JSON 给程序读一份 TOML 给你自己看和改。先看settings.json放在 exe 同目录{ taotoken: { api_base: https://taotoken.net/api, api_key: sk-你的Key填这里, model: 你选定的模型名, timeout_ms: 30000 }, ui: { status_idle_icon: idle.ico, status_busy_icon: busy.ico, status_ok_icon: ok.ico, status_fail_icon: fail.ico } }再看config.toml这份是给你手动维护用的字段和 JSON 对齐[taotoken] api_base https://taotoken.net/api api_key sk-你的Key填这里 model 你选定的模型名 timeout_ms 30000 [ui] status_idle_icon idle.ico status_busy_icon busy.ico status_ok_icon ok.ico status_fail_icon fail.ico两份配置的字段含义一致api_base是统一入口api_key是凭证model是模型名timeout_ms是超时。UI 部分对应四个状态图标文件名放在 exe 同目录即可。在 Delphi7 里读取时你可以先用最简单的 TStringList 逐行解析或者引入 SuperObject。下面给一个不依赖第三方库的读取片段假设你只读 JSON 里的三个关键字段function ReadConfigValue(const AFile, AKey: string): string; var sl: TStringList; i: Integer; line, pattern: string; begin Result : ; sl : TStringList.Create; try sl.LoadFromFile(AFile); pattern : AKey ; for i : 0 to sl.Count - 1 do begin line : Trim(sl[i]); if Pos(pattern, line) 1 then begin // 形如 api_key: sk-xxx, Result : Trim(Copy(line, Pos(:, line) 1, Length(line))); Result : StringReplace(Result, , , [rfReplaceAll]); Result : StringReplace(Result, ,, , [rfReplaceAll]); Break; end; end; finally sl.Free; end; end;这段代码只做演示生产环境建议换成正规 JSON 库。重点是配置和代码分离换 Key 不用重新编译。4. 面板搭建Image 状态图标 SpeedButton 触发按钮现在进入 UI 部分。新建一个 Form放一个 Image 和三个 SpeedButton布局如下Image 放在左上角Align 设为alNone手动调成 32x32用来显示状态图标。SpeedButton1 做「发送」SpeedButton2 做「清空」SpeedButton3 做「复制结果」。右侧放一个 Memo 显示返回内容。4.1 Image 组件Align 与 Stretch 怎么设Image 有两个关键属性。Align常见设成alClient这样 Image 会充满整个窗体但我们的场景里 Image 只做状态图标所以保持alNone手动设 Width 和 Height 为 32。Stretch设为True时图片会自动缩放到 Image 选框大小。状态图标建议统一做成 32x32Stretch 设 True这样换图标不会因为尺寸不一致而变形。procedure TForm1.FormCreate(Sender: TObject); begin Image1.Width : 32; Image1.Height : 32; Image1.Stretch : True; Image1.Picture.LoadFromFile(idle.ico); end;切换状态时只需要换 Pictureprocedure TForm1.SetStatus(const AIconFile: string); begin if FileExists(AIconFile) then Image1.Picture.LoadFromFile(AIconFile); end;4.2 SpeedButton 组件Flat、Cursor、Layout、Transparent、Margin、SpacingSpeedButton 的属性比较多逐个说清楚Flat设为 True 时按钮是平铺外观False 是立体效果。面板风格建议 True看起来更干净。Cursor改成crHandPoint鼠标移上去变手型交互感更好。Layout控制位图在按钮上的位置比如blGlyphLeft。原文提到「虽然可以让位图居左但是还是不够左」这是因为还有Margin在起作用。Transparent设为 True 时按钮背景透明适合放在有底色的面板上。Margin设置边界像素想让图标更靠左就把 Margin 调小比如 2。Spacing指定图标和文字之间的距离默认是 4想让文字离图标远一点就调大。procedure TForm1.FormCreate(Sender: TObject); begin SpeedButton1.Flat : True; SpeedButton1.Cursor : crHandPoint; SpeedButton1.Layout : blGlyphLeft; SpeedButton1.Transparent : True; SpeedButton1.Margin : 2; SpeedButton1.Spacing : 6; SpeedButton1.Caption : 发送; end;关于NumGlyphs它用于指定按钮位图包含几个状态图比如正常、按下、禁用。如果你只用一张图保持默认 1 即可要用多状态就把位图做成横向排列的多帧NumGlyphs 设为帧数。新手常见问题是位图只做了一帧却把 NumGlyphs 设成 3结果按钮显示错位改回 1 就正常了。5. 按钮点击后发请求并验证返回UI 搭好后核心是 SpeedButton1 的 OnClick 里发 HTTP 请求。Delphi7 可以用 Indy 的 TIdHTTP或者用 WinINet。这里用 Indy因为大多数 Delphi7 环境都自带。uses IdHTTP, IdSSLOpenSSL, IdGlobal; function TForm1.CallTaoToken(const APrompt: string): string; var http: TIdHTTP; ssl: TIdSSLIOHandlerSocket; reqBody: TStringStream; respBody: TStringStream; json: string; begin http : TIdHTTP.Create(nil); ssl : TIdSSLIOHandlerSocket.Create(nil); reqBody : TStringStream.Create(); respBody : TStringStream.Create(); try ssl.SSLOptions.Method : sslvTLSv1_2; http.IOHandler : ssl; http.Request.ContentType : application/json; http.Request.CustomHeaders.Values[Authorization] : Bearer ReadConfigValue(settings.json, api_key); http.ReadTimeout : 30000; json : {model: ReadConfigValue(settings.json, model) , messages:[{role:user,content: APrompt }]}; reqBody.WriteString(UTF8Encode(json)); http.Post(https://taotoken.net/api/v1/chat/completions, reqBody, respBody); Result : UTF8Decode(respBody.DataString); finally reqBody.Free; respBody.Free; ssl.Free; http.Free; end; end;按钮点击事件procedure TForm1.SpeedButton1Click(Sender: TObject); begin SetStatus(busy.ico); SpeedButton1.Enabled : False; try Memo1.Lines.Text : CallTaoToken(Memo1.Lines.Text); SetStatus(ok.ico); except on E: Exception do begin Memo1.Lines.Text : 请求失败: E.Message; SetStatus(fail.ico); end; end; SpeedButton1.Enabled : True; end;验证成功的标志Memo 里出现模型返回的文本Image 从 busy 切到 ok。如果失败Image 切到 failMemo 显示错误信息。这一步跑通说明 Key、API 地址、模型名、网络都对了。6. 本篇常见错排查错误一请求返回 401。多半是 Key 没读到或者 Authorization 头拼错。检查ReadConfigValue是否真的读到了值可以在调试时把 Key 前几位打印出来。注意 Bearer 后面有一个空格。错误二返回 404。检查 URL 路径。基地址是https://taotoken.net/api聊天补全路径是/v1/chat/completions拼起来是https://taotoken.net/api/v1/chat/completions。不要多加斜杠。错误三中文乱码。Delphi7 的字符串是 ANSI请求体要 UTF8Encode返回要 UTF8Decode。Memo 显示前确认解码正确。错误四SSL 握手失败。Delphi7 自带的 Indy 版本较老需要确认IdSSLOpenSSL已安装并且 OpenSSL 的 dll 在 exe 同目录。TLS 版本设成 1.2。错误五SpeedButton 图标不显示。检查Glyph是否加载NumGlyphs是否和位图帧数一致Margin是否把图标挤出去了。错误六Image 图标切换无效。确认图标文件路径正确Stretch为 True 时图片会缩放如果原图比例不对会变形建议统一 32x32。排障时优先看 API Keys 和接入文档两个入口对照请求头和路径API Keyshttps://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewrite接入文档https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite7. 继续往下走从单次调用到可复用面板面板跑通一次真实调用后你可以把它做成可复用的把 CallTaoToken 抽成独立单元配置读取抽成 Config 类Image 和 SpeedButton 封装成一个 TAIStatusPanel 组件。这样在别的 Form 上直接放一个面板就能用。如果后面要做更长的编码任务或 Agent 流程单次请求面板就不够了可以看 Coding Plan入口是 https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding-planutm_campaignrewrite 。模型对话入口是 https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_contentchatutm_campaignrewrite 可以先用它验证模型名和返回格式再写进 Delphi 配置。我试过在 Delphi7 里把 SpeedButton 的 Margin 调到 0、Spacing 调到 8图标和文字的组合最舒服。另外一个小技巧把四个状态图标做成同一套配色Image 切换时视觉上不会跳。面板虽小但状态反馈清楚用起来比纯文本框踏实得多。
返回列表