动态创建 Delphi 按钮的完整指南:基于配置文件的 `TGridPanel` 实现
在 Delphi 开发中,我们经常需要根据不同的配置动态生成 UI 元素。本文将带你通过一个完整的示例,演示如何根据配置文件动态创建按钮,并将它们排列在一个 TGridPanel 中。每个按钮的标题、链接、颜色和大小都将从配置文件中读取。
“C:\myApp\delphi编写的shortcut工具\Project1.dproj”
项目背景
假设你正在开发一个应用程序,它需要根据用户指定的配置文件生成多个按钮。每个按钮不仅具有不同的标题,还会在点击时打开一个指定的链接。同时,按钮的颜色和大小也可以配置。我们将使用 TGridPanel 来自动排列这些按钮,使界面布局美观且具有响应性。
全部代码
unit Unit3;interfaceusesWinapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ComCtrls, Vcl.ExtCtrls,
System.IniFiles, ShellAPI,Math;typeTForm3 = class(TForm)procedure FormCreate(Sender: TObject);private{ Private declarations }procedure CreateButtonsFromConfig;procedure ButtonClick(Sender: TObject);public{ Public declarations }end;varForm3: TForm3;implementation{$R *.dfm}
procedure TForm3.CreateButtonsFromConfig;
varIni: TIniFile;SectionList: TStringList;GridPanel: TGridPanel;i, Rows, Cols: Integer;Button: TButton;Caption, Link: string;Color: TColor;Width, Height: Integer;
begin// 加载配置文件Ini := TIniFile.Create(ExtractFilePath(Application.ExeName) + 'buttons.ini');SectionList := TStringList.Create;try// 获取所有按钮的配置节Ini.ReadSections(SectionList);// 动态创建 GridPanelGridPanel := TGridPanel.Create(Self);GridPanel.Parent := Self;GridPanel.Align := alClient;GridPanel.RowCollection.Clear;GridPanel.ColumnCollection.Clear;// 计算行和列数Rows := Ceil(Sqrt(SectionList.Count)); // 根据按钮数量计算行列数Cols := Rows;// 创建 GridPanel 的行和列for i := 0 to Rows - 1 doGridPanel.RowCollection.Add;for i := 0 to Cols - 1 doGridPanel.ColumnCollection.Add;// 在每个单元格中添加按钮for i := 0 to SectionList.Count - 1 dobegin// 读取按钮的属性Caption := Ini.ReadString(SectionList[i], 'Caption', 'Default');Link := Ini.ReadString(SectionList[i], 'Link', '');Color := StringToColor(Ini.ReadString(SectionList[i], 'Color', 'clBtnFace'));Width := Ini.ReadInteger(SectionList[i], 'Width', 100);Height := Ini.ReadInteger(SectionList[i], 'Height', 50);// 创建按钮Button := TButton.Create(Self);Button.Parent := GridPanel;Button.Caption := Caption;
// Button.Width := Width;
// Button.Height := Height;Button.Font.Color := Color;Button.Align:=alClient;
// Button.fontColor := Color;Button.Tag := i; // 用于区分不同的按钮Button.OnClick := ButtonClick; // 分配点击事件// 将链接存储在按钮的 Hint 属性中,便于在事件中使用Button.Hint := Link;// 将按钮放置到 GridPanel 的单元格中GridPanel.ControlCollection.AddControl(Button, i mod Cols, i div Cols);end;finallyIni.Free;SectionList.Free;end;
end;procedure TForm3.FormCreate(Sender: TObject);
begin
CreateButtonsFromConfig;
end;procedure TForm3.ButtonClick(Sender: TObject);
varLink: string;
beginLink := (Sender as TButton).Hint;if Link <> '' thenShellExecute(0, 'open', PChar(Link), nil, nil, SW_SHOWNORMAL);
end;
end.
准备工作
我们首先需要创建一个简单的 .ini 配置文件,其中包含每个按钮的配置信息:
配置文件示例 (buttons.ini)
[Button1]
Caption=Google
Link=https://www.google.com
Color=clRed
Width=100
Height=50[Button2]
Caption=YouTube
Link=https://www.youtube.com
Color=clBlue
Width=120
Height=60[Button3]
Caption=OpenAI
Link=https://www.openai.com
Color=clGreen
Width=150
Height=70
这个配置文件定义了三个按钮,每个按钮的标题、链接、颜色、宽度和高度都可以在文件中轻松配置。
实现步骤
-
创建 Delphi 项目:
- 在 Delphi IDE 中创建一个新的 VCL Forms Application 项目。
- 将
FormCreate事件与我们的核心函数CreateButtonsFromConfig关联。
-
动态创建
TGridPanel和按钮:- 通过
TGridPanel控件将按钮自动排列在网格中。 - 从配置文件中读取按钮的属性并动态创建按钮。
- 通过
-
实现按钮点击事件:
- 在点击按钮时,通过调用
ShellExecute函数打开与按钮相关联的链接。
- 在点击按钮时,通过调用
代码实现
以下是完整的 Delphi 代码示例:
usesSystem.IniFiles, ShellAPI, Vcl.ExtCtrls, Vcl.StdCtrls, System.SysUtils, Vcl.Graphics, Math;procedure TForm1.CreateButtonsFromConfig;
varIni: TIniFile;SectionList: TStringList;GridPanel: TGridPanel;i, Rows, Cols: Integer;Button: TButton;Caption, Link: string;Color: TColor;Width, Height: Integer;
begin// 加载配置文件Ini := TIniFile.Create(ExtractFilePath(Application.ExeName) + 'buttons.ini');SectionList := TStringList.Create;try// 获取所有按钮的配置节Ini.ReadSections(SectionList);// 动态创建 GridPanelGridPanel := TGridPanel.Create(Self);GridPanel.Parent := Self;GridPanel.Align := alClient;GridPanel.RowCollection.Clear;GridPanel.ColumnCollection.Clear;// 计算行和列数Rows := Ceil(Sqrt(SectionList.Count)); // 根据按钮数量计算行列数Cols := Rows;// 创建 GridPanel 的行和列for i := 0 to Rows - 1 doGridPanel.RowCollection.Add;for i := 0 to Cols - 1 doGridPanel.ColumnCollection.Add;// 在每个单元格中添加按钮for i := 0 to SectionList.Count - 1 dobegin// 读取按钮的属性Caption := Ini.ReadString(SectionList[i], 'Caption', 'Default');Link := Ini.ReadString(SectionList[i], 'Link', '');Color := StringToColor(Ini.ReadString(SectionList[i], 'Color', 'clBtnFace'));Width := Ini.ReadInteger(SectionList[i], 'Width', 100);Height := Ini.ReadInteger(SectionList[i], 'Height', 50);// 创建按钮Button := TButton.Create(Self);Button.Parent := GridPanel;Button.Caption := Caption;Button.Width := Width;Button.Height := Height;Button.Font.Color := clWhite;Button.Color := Color;Button.Tag := i; // 用于区分不同的按钮Button.OnClick := ButtonClick; // 分配点击事件// 将链接存储在按钮的 Hint 属性中,便于在事件中使用Button.Hint := Link;// 将按钮放置到 GridPanel 的单元格中GridPanel.ControlCollection.AddControl(Button, i mod Cols, i div Cols);end;finallyIni.Free;SectionList.Free;end;
end;procedure TForm1.ButtonClick(Sender: TObject);
varLink: string;
beginLink := (Sender as TButton).Hint;if Link <> '' thenShellExecute(0, 'open', PChar(Link), nil, nil, SW_SHOWNORMAL);
end;procedure TForm1.FormCreate(Sender: TObject);
beginCreateButtonsFromConfig;
end;
代码解析
-
读取配置文件:
- 使用
TIniFile类读取buttons.ini配置文件。 SectionList用于存储配置文件中的节名(即按钮的配置部分)。
- 使用
-
动态创建
TGridPanel:- 创建
TGridPanel,并根据按钮数量动态设置网格的行和列。 Ceil(Sqrt(SectionList.Count))用于计算合适的行列数,以确保按钮均匀分布。
- 创建
-
生成按钮:
- 遍历每个配置节,为每个按钮设置标题、颜色、大小等属性,并将它们添加到
TGridPanel的指定单元格中。
- 遍历每个配置节,为每个按钮设置标题、颜色、大小等属性,并将它们添加到
-
按钮点击事件:
ButtonClick方法使用ShellExecute打开与按钮关联的链接。
运行效果
当程序运行时,按钮会根据配置文件中的信息动态生成,并在 TGridPanel 中自动排列。每个按钮的外观和功能都可以通过简单地修改配置文件来调整,非常适合需要灵活配置 UI 元素的场景。
结果如下

结论
通过本文的示例,你应该能够掌握如何在 Delphi 中根据配置文件动态生成按钮,并将它们排列在 TGridPanel 中。这种方法不仅增强了程序的可配置性,还使得 UI 的调整变得更加简单和直观。希望本文对你的 Delphi 开发之旅有所帮助!
相关文章:
动态创建 Delphi 按钮的完整指南:基于配置文件的 `TGridPanel` 实现
在 Delphi 开发中,我们经常需要根据不同的配置动态生成 UI 元素。本文将带你通过一个完整的示例,演示如何根据配置文件动态创建按钮,并将它们排列在一个 TGridPanel 中。每个按钮的标题、链接、颜色和大小都将从配置文件中读取。 “C:\myApp\…...
【设计模式】工厂模式和抽象工厂模式
工厂模式 function User(role, pages) {this.role role;this.pages pages; }// new User(admin, [home, user, setting]); // new User(user, [home, user]); // new User(guest, [home]);function UserFactory(role) {switch (role) {case admin:return new User(role, [ho…...
【xilinx】Versal Adaptive SoC DDRMC - NoC QoS 选项卡未出现
在 2024.1 之前的 Vivado 版本中,用户在使用 NoC 验证块设计时可以访问 NoC 对象窗口和 QoS 选项卡。 Vivado 2024.1 中存在一个已知问题,即 NoC 对象窗口和 QoS 选项卡不出现。 要显示 NoC 对象窗口和 QoS 选项卡,请保存块设计,…...
融合创新:EasyCVR视频汇聚平台云计算技术与AI技术共筑雪亮工程智能防线
随着信息技术的飞速发展,视频云计算技术作为云计算领域的一个重要分支,正逐步在公共安全、社会治理等领域展现出其独特的优势。特别是在雪亮工程这一群众性治安防控工程中,视频云计算技术更是发挥了不可替代的作用。本文将从视频云计算技术的…...
keepalived的技术原理及其在负载均衡场景中的应用
keepalived的技术原理及其在负载均衡场景中的应用 深入探讨Keepalived及其在负载均衡场景中的应用1. **Keepalived概述**2. **Keepalived的技术原理**2.1 **VRRP协议**2.2 **健康检查机制**2.3 **脚本管理** 3. **Keepalived与LVS的结合应用**3.1 **LVS优缺点** 4. **Nginx与HA…...
树的重心 by江河湖海
引入 重心是什么? 想象你有一个由线悬挂的秋千,秋千的两端坐着两个人,如果这两个人坐在秋千的重心上,秋千就会保持平衡。在树的结构中,重心就是那个让所有节点到它那里的“距离”(可以理解为线的长度)总和最小的点。 重心为什么最多只有两个? 假设树的重心有两个,…...
MySQL存储过程深入指南
MySQL存储过程深入指南 存储过程是MySQL中一个强大的功能,能够显著提升数据库操作的效率和灵活性。本文将全面介绍存储过程的概念、语法、使用方法及最佳实践,帮助读者熟练掌握存储过程的使用。 1. 什么是存储过程? 存储过程(Stored Procedure)是预先编译并存储在数据库…...
牛客算法小题
目录 牛客.求和编辑 牛客.abb 牛客.合并k个有序链表 牛客.滑雪(暴力->递归->记忆化搜索) 牛客.旋转字符串 牛客.求和 我没想到是dfs,另外我的dfs能力确实也不强,另外难度大的是他的那个输出 import java.util.Scanne…...
小米SU7销量超特斯拉,新车明年上半年发布
小米 SU7,一款国内新能源车品牌纯血新势力旗下首款轿车,上市短短 4 个月卖出超 4 万台,月均销量过万。 该说不说,这放在整个新能源汽车工业史上也足以称得上是一件小刀喇拍屁股,让人开了眼的事儿。 就在本月初&#x…...
基于Java语言的光伏监控系统+光伏发电预测+光伏项目+光伏运维+光伏储能项目
基于Java语言的光伏监控系统光伏发电预测光伏项目光伏运维光伏储能项目 介绍 基于Java语言的光伏监控系统光伏发电系统光伏软件系统光伏监控系统源码光伏发电系统源码 基于Java语言的光伏监控系统光伏发电预测光伏项目光伏运维光伏储能项目 安装教程...
unity json 处理
1. c#对象 -> json public class Item {public int id;public int num;public Item(int id, int num){this.id id;this.num num;} } public class PlayerInfo {public string name;public int atk;public int def;public float moveSpeed;public double roundSpeed;publi…...
如何使用DataGear零编码快速制作MQTT物联网实时数据看板
DataGear是一个开源免费的数据可视化分析平台,企业版在开源版基础上开发,新增了诸多企业级特性,包括:MySQL及更多部署数据库支持、MQTT/WebSocket/Redis/MongoDB数据集、OAuth2.0/CAS/JWT/LDAP统一登录支持、前后端敏感信息加密传…...
Mysql查询日志
Mysql查询日志 Mysql查询日志默认是关闭状态的。 mysql> show variables like %general_log%; --------------------------------------- | Variable_name | Value | --------------------------------------- | general_log | OFF …...
Airtest 的使用
Airtest 介绍 Airtest Project 是网易游戏推出的一款自动化测试框架,其项目由以下几个部分构成 Airtest : 一个跨平台的,基于图像识别的 UI 自动化测试框架,适用于游戏和 App , 支持 Windows, Android 和 iOS 平台,…...
Android更改包名和签名
一、更改包名 1、包名——鼠标右键——Refactor——Rename 修改自己想更改的包名和选择更改范围后点击Refactor就可以了 2.手动修改app的build.gradle文件中的applicationId(改成和我们之前修改的包名相同) 3.修改AndroidManifest.xml文件中的packag…...
tortoisegit下载及其使用流程
下载 官方下载链接:Download – TortoiseGit – Windows Shell Interface to Git 选择适合自己的电脑位数的版本:一般64的兼容32的 按照就不介绍了怎么开心怎么来,本篇暂时为了支持一位粉丝的疑惑 安装的话没有特殊配置暂不介绍,…...
Anrdoir 13 关于设置静态IP后,突然断电,在上电开机卡动画
bug描述:设置静态IP成功后,机器突然断电,然后在上电开机,发现机器一直卡在开机动画,无法成功进入桌面 第一时间抓取日志分析,Log如下: 08-13 11:26:42.455 2803 2803 I EthernetServiceImpl: Starting Ethernet service 08-13 11:26:42.457 2803 2924 D ConnectivityServ…...
multimodel ocr dataset
InternLM-XComposer2-4KHD InternLM-XComposer2-4KHD a light-weight Vision Encoder OpenAI ViT-Large/14Large Language Model InternLM2-7B, 这篇论文采用的是一种动态分辨率的输入; 全图有一个global view,resize到336*336; 然后把图片resize再pad…...
兼容并蓄,高效集成:EasyCVR视频综合接入能力助力多元化项目需求
随着视频技术的不断进步,视频监控、视频直播、执法记录仪、语音可视对讲、无人机等视频资源的应用场景日益丰富。这些视频资源不仅在数量上快速增长,而且在质量、格式、编码标准等方面也呈现出多样化的特点。因此,为了有效整合这些资源&#…...
linux 部署YUM仓库及NFS共享服务
目录 简介 一、YUM仓库服务 1.1 YUM概述 1.2 linux系统各家厂家用的安装源 1.3 yum命令 1.4 yum下载方式 1.5 部署YUM软件仓库 二、NFS共享存储服务 2.1 NFS共享存储服务概念 2.2 NFS配置环境 2.3 使用NFS发布共享资源 2.4 在客户端访问NFS共享 简介 yumÿ…...
【网络】每天掌握一个Linux命令 - iftop
在Linux系统中,iftop是网络管理的得力助手,能实时监控网络流量、连接情况等,帮助排查网络异常。接下来从多方面详细介绍它。 目录 【网络】每天掌握一个Linux命令 - iftop工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景…...
R语言AI模型部署方案:精准离线运行详解
R语言AI模型部署方案:精准离线运行详解 一、项目概述 本文将构建一个完整的R语言AI部署解决方案,实现鸢尾花分类模型的训练、保存、离线部署和预测功能。核心特点: 100%离线运行能力自包含环境依赖生产级错误处理跨平台兼容性模型版本管理# 文件结构说明 Iris_AI_Deployme…...
java 实现excel文件转pdf | 无水印 | 无限制
文章目录 目录 文章目录 前言 1.项目远程仓库配置 2.pom文件引入相关依赖 3.代码破解 二、Excel转PDF 1.代码实现 2.Aspose.License.xml 授权文件 总结 前言 java处理excel转pdf一直没找到什么好用的免费jar包工具,自己手写的难度,恐怕高级程序员花费一年的事件,也…...
java调用dll出现unsatisfiedLinkError以及JNA和JNI的区别
UnsatisfiedLinkError 在对接硬件设备中,我们会遇到使用 java 调用 dll文件 的情况,此时大概率出现UnsatisfiedLinkError链接错误,原因可能有如下几种 类名错误包名错误方法名参数错误使用 JNI 协议调用,结果 dll 未实现 JNI 协…...
【android bluetooth 框架分析 04】【bt-framework 层详解 1】【BluetoothProperties介绍】
1. BluetoothProperties介绍 libsysprop/srcs/android/sysprop/BluetoothProperties.sysprop BluetoothProperties.sysprop 是 Android AOSP 中的一种 系统属性定义文件(System Property Definition File),用于声明和管理 Bluetooth 模块相…...
鱼香ros docker配置镜像报错:https://registry-1.docker.io/v2/
使用鱼香ros一件安装docker时的https://registry-1.docker.io/v2/问题 一键安装指令 wget http://fishros.com/install -O fishros && . fishros出现问题:docker pull 失败 网络不同,需要使用镜像源 按照如下步骤操作 sudo vi /etc/docker/dae…...
Docker 本地安装 mysql 数据库
Docker: Accelerated Container Application Development 下载对应操作系统版本的 docker ;并安装。 基础操作不再赘述。 打开 macOS 终端,开始 docker 安装mysql之旅 第一步 docker search mysql 》〉docker search mysql NAME DE…...
[大语言模型]在个人电脑上部署ollama 并进行管理,最后配置AI程序开发助手.
ollama官网: 下载 https://ollama.com/ 安装 查看可以使用的模型 https://ollama.com/search 例如 https://ollama.com/library/deepseek-r1/tags # deepseek-r1:7bollama pull deepseek-r1:7b改token数量为409622 16384 ollama命令说明 ollama serve #:…...
WEB3全栈开发——面试专业技能点P7前端与链上集成
一、Next.js技术栈 ✅ 概念介绍 Next.js 是一个基于 React 的 服务端渲染(SSR)与静态网站生成(SSG) 框架,由 Vercel 开发。它简化了构建生产级 React 应用的过程,并内置了很多特性: ✅ 文件系…...
规则与人性的天平——由高考迟到事件引发的思考
当那位身着校服的考生在考场关闭1分钟后狂奔而至,他涨红的脸上写满绝望。铁门内秒针划过的弧度,成为改变人生的残酷抛物线。家长声嘶力竭的哀求与考务人员机械的"这是规定",构成当代中国教育最尖锐的隐喻。 一、刚性规则的必要性 …...
