当前位置: 首页 > news >正文

动态创建 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

这个配置文件定义了三个按钮,每个按钮的标题、链接、颜色、宽度和高度都可以在文件中轻松配置。

实现步骤
  1. 创建 Delphi 项目

    • 在 Delphi IDE 中创建一个新的 VCL Forms Application 项目。
    • FormCreate 事件与我们的核心函数 CreateButtonsFromConfig 关联。
  2. 动态创建 TGridPanel 和按钮

    • 通过 TGridPanel 控件将按钮自动排列在网格中。
    • 从配置文件中读取按钮的属性并动态创建按钮。
  3. 实现按钮点击事件

    • 在点击按钮时,通过调用 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;
代码解析
  1. 读取配置文件

    • 使用 TIniFile 类读取 buttons.ini 配置文件。
    • SectionList 用于存储配置文件中的节名(即按钮的配置部分)。
  2. 动态创建 TGridPanel

    • 创建 TGridPanel,并根据按钮数量动态设置网格的行和列。
    • Ceil(Sqrt(SectionList.Count)) 用于计算合适的行列数,以确保按钮均匀分布。
  3. 生成按钮

    • 遍历每个配置节,为每个按钮设置标题、颜色、大小等属性,并将它们添加到 TGridPanel 的指定单元格中。
  4. 按钮点击事件

    • ButtonClick 方法使用 ShellExecute 打开与按钮关联的链接。
运行效果

当程序运行时,按钮会根据配置文件中的信息动态生成,并在 TGridPanel 中自动排列。每个按钮的外观和功能都可以通过简单地修改配置文件来调整,非常适合需要灵活配置 UI 元素的场景。

结果如下

在这里插入图片描述

结论

通过本文的示例,你应该能够掌握如何在 Delphi 中根据配置文件动态生成按钮,并将它们排列在 TGridPanel 中。这种方法不仅增强了程序的可配置性,还使得 UI 的调整变得更加简单和直观。希望本文对你的 Delphi 开发之旅有所帮助!

相关文章:

动态创建 Delphi 按钮的完整指南:基于配置文件的 `TGridPanel` 实现

在 Delphi 开发中&#xff0c;我们经常需要根据不同的配置动态生成 UI 元素。本文将带你通过一个完整的示例&#xff0c;演示如何根据配置文件动态创建按钮&#xff0c;并将它们排列在一个 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 版本中&#xff0c;用户在使用 NoC 验证块设计时可以访问 NoC 对象窗口和 QoS 选项卡。 Vivado 2024.1 中存在一个已知问题&#xff0c;即 NoC 对象窗口和 QoS 选项卡不出现。 要显示 NoC 对象窗口和 QoS 选项卡&#xff0c;请保存块设计&#xff0c;…...

融合创新:EasyCVR视频汇聚平台云计算技术与AI技术共筑雪亮工程智能防线

随着信息技术的飞速发展&#xff0c;视频云计算技术作为云计算领域的一个重要分支&#xff0c;正逐步在公共安全、社会治理等领域展现出其独特的优势。特别是在雪亮工程这一群众性治安防控工程中&#xff0c;视频云计算技术更是发挥了不可替代的作用。本文将从视频云计算技术的…...

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个有序链表 牛客.滑雪&#xff08;暴力->递归->记忆化搜索&#xff09; 牛客.旋转字符串 牛客.求和 我没想到是dfs&#xff0c;另外我的dfs能力确实也不强&#xff0c;另外难度大的是他的那个输出 import java.util.Scanne…...

小米SU7销量超特斯拉,新车明年上半年发布

小米 SU7&#xff0c;一款国内新能源车品牌纯血新势力旗下首款轿车&#xff0c;上市短短 4 个月卖出超 4 万台&#xff0c;月均销量过万。 该说不说&#xff0c;这放在整个新能源汽车工业史上也足以称得上是一件小刀喇拍屁股&#xff0c;让人开了眼的事儿。 就在本月初&#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是一个开源免费的数据可视化分析平台&#xff0c;企业版在开源版基础上开发&#xff0c;新增了诸多企业级特性&#xff0c;包括&#xff1a;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 是网易游戏推出的一款自动化测试框架&#xff0c;其项目由以下几个部分构成 Airtest : 一个跨平台的&#xff0c;基于图像识别的 UI 自动化测试框架&#xff0c;适用于游戏和 App &#xff0c; 支持 Windows, Android 和 iOS 平台&#xff0c…...

Android更改包名和签名

一、更改包名 1、包名——鼠标右键——Refactor——Rename 修改自己想更改的包名和选择更改范围后点击Refactor就可以了 2.手动修改app的build.gradle文件中的applicationId&#xff08;改成和我们之前修改的包名相同&#xff09; 3.修改AndroidManifest.xml文件中的packag…...

tortoisegit下载及其使用流程

下载 官方下载链接&#xff1a;Download – TortoiseGit – Windows Shell Interface to Git 选择适合自己的电脑位数的版本&#xff1a;一般64的兼容32的 按照就不介绍了怎么开心怎么来&#xff0c;本篇暂时为了支持一位粉丝的疑惑 安装的话没有特殊配置暂不介绍&#xff0c…...

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, 这篇论文采用的是一种动态分辨率的输入&#xff1b; 全图有一个global view,resize到336*336&#xff1b; 然后把图片resize再pad…...

兼容并蓄,高效集成:EasyCVR视频综合接入能力助力多元化项目需求

随着视频技术的不断进步&#xff0c;视频监控、视频直播、执法记录仪、语音可视对讲、无人机等视频资源的应用场景日益丰富。这些视频资源不仅在数量上快速增长&#xff0c;而且在质量、格式、编码标准等方面也呈现出多样化的特点。因此&#xff0c;为了有效整合这些资源&#…...

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&#xff…...

Python爬虫实战:研究MechanicalSoup库相关技术

一、MechanicalSoup 库概述 1.1 库简介 MechanicalSoup 是一个 Python 库,专为自动化交互网站而设计。它结合了 requests 的 HTTP 请求能力和 BeautifulSoup 的 HTML 解析能力,提供了直观的 API,让我们可以像人类用户一样浏览网页、填写表单和提交请求。 1.2 主要功能特点…...

Prompt Tuning、P-Tuning、Prefix Tuning的区别

一、Prompt Tuning、P-Tuning、Prefix Tuning的区别 1. Prompt Tuning(提示调优) 核心思想:固定预训练模型参数,仅学习额外的连续提示向量(通常是嵌入层的一部分)。实现方式:在输入文本前添加可训练的连续向量(软提示),模型只更新这些提示参数。优势:参数量少(仅提…...

树莓派超全系列教程文档--(62)使用rpicam-app通过网络流式传输视频

使用rpicam-app通过网络流式传输视频 使用 rpicam-app 通过网络流式传输视频UDPTCPRTSPlibavGStreamerRTPlibcamerasrc GStreamer 元素 文章来源&#xff1a; http://raspberry.dns8844.cn/documentation 原文网址 使用 rpicam-app 通过网络流式传输视频 本节介绍来自 rpica…...

简易版抽奖活动的设计技术方案

1.前言 本技术方案旨在设计一套完整且可靠的抽奖活动逻辑,确保抽奖活动能够公平、公正、公开地进行,同时满足高并发访问、数据安全存储与高效处理等需求,为用户提供流畅的抽奖体验,助力业务顺利开展。本方案将涵盖抽奖活动的整体架构设计、核心流程逻辑、关键功能实现以及…...

【论文笔记】若干矿井粉尘检测算法概述

总的来说&#xff0c;传统机器学习、传统机器学习与深度学习的结合、LSTM等算法所需要的数据集来源于矿井传感器测量的粉尘浓度&#xff0c;通过建立回归模型来预测未来矿井的粉尘浓度。传统机器学习算法性能易受数据中极端值的影响。YOLO等计算机视觉算法所需要的数据集来源于…...

WordPress插件:AI多语言写作与智能配图、免费AI模型、SEO文章生成

厌倦手动写WordPress文章&#xff1f;AI自动生成&#xff0c;效率提升10倍&#xff01; 支持多语言、自动配图、定时发布&#xff0c;让内容创作更轻松&#xff01; AI内容生成 → 不想每天写文章&#xff1f;AI一键生成高质量内容&#xff01;多语言支持 → 跨境电商必备&am…...

大模型多显卡多服务器并行计算方法与实践指南

一、分布式训练概述 大规模语言模型的训练通常需要分布式计算技术,以解决单机资源不足的问题。分布式训练主要分为两种模式: 数据并行:将数据分片到不同设备,每个设备拥有完整的模型副本 模型并行:将模型分割到不同设备,每个设备处理部分模型计算 现代大模型训练通常结合…...

Unit 1 深度强化学习简介

Deep RL Course ——Unit 1 Introduction 从理论和实践层面深入学习深度强化学习。学会使用知名的深度强化学习库&#xff0c;例如 Stable Baselines3、RL Baselines3 Zoo、Sample Factory 和 CleanRL。在独特的环境中训练智能体&#xff0c;比如 SnowballFight、Huggy the Do…...

dify打造数据可视化图表

一、概述 在日常工作和学习中&#xff0c;我们经常需要和数据打交道。无论是分析报告、项目展示&#xff0c;还是简单的数据洞察&#xff0c;一个清晰直观的图表&#xff0c;往往能胜过千言万语。 一款能让数据可视化变得超级简单的 MCP Server&#xff0c;由蚂蚁集团 AntV 团队…...

LLMs 系列实操科普(1)

写在前面&#xff1a; 本期内容我们继续 Andrej Karpathy 的《How I use LLMs》讲座内容&#xff0c;原视频时长 ~130 分钟&#xff0c;以实操演示主流的一些 LLMs 的使用&#xff0c;由于涉及到实操&#xff0c;实际上并不适合以文字整理&#xff0c;但还是决定尽量整理一份笔…...