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

在 Delphi 开发中,我们经常需要根据不同的配置动态生成 UI 元素。本文将带你通过一个完整的示例,演示如何根据配置文件动态创建按钮,并将它们排列在一个 TGridPanel 中。每个按钮的标题、链接、颜色和大小都将从配置文件中读取。

"C:\myApp\delphi编写的shortcut工具\Project1.dproj"

项目背景

假设你正在开发一个应用程序,它需要根据用户指定的配置文件生成多个按钮。每个按钮不仅具有不同的标题,还会在点击时打开一个指定的链接。同时,按钮的颜色和大小也可以配置。我们将使用 TGridPanel 来自动排列这些按钮,使界面布局美观且具有响应性。

全部代码

delphi 复制代码
unit Unit3;

interface

uses
 Winapi.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;

type
  TForm3 = class(TForm)
    procedure FormCreate(Sender: TObject);

  private
    { Private declarations }
    procedure CreateButtonsFromConfig;
    procedure ButtonClick(Sender: TObject);
  public

    { Public declarations }
  end;

var
  Form3: TForm3;

implementation

{$R *.dfm}
procedure TForm3.CreateButtonsFromConfig;
var
  Ini: 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);

    // 动态创建 GridPanel
    GridPanel := 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 do
      GridPanel.RowCollection.Add;

    for i := 0 to Cols - 1 do
      GridPanel.ColumnCollection.Add;

    // 在每个单元格中添加按钮
    for i := 0 to SectionList.Count - 1 do
    begin
      // 读取按钮的属性
      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;
  finally
    Ini.Free;
    SectionList.Free;
  end;
end;

procedure TForm3.FormCreate(Sender: TObject);
begin
CreateButtonsFromConfig;
end;

procedure TForm3.ButtonClick(Sender: TObject);
var
  Link: string;
begin
  Link := (Sender as TButton).Hint;
  if Link <> '' then
    ShellExecute(0, 'open', PChar(Link), nil, nil, SW_SHOWNORMAL);
end;
end.
准备工作

我们首先需要创建一个简单的 .ini 配置文件,其中包含每个按钮的配置信息:

配置文件示例 (buttons.ini)
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 代码示例:

delphi 复制代码
uses
  System.IniFiles, ShellAPI, Vcl.ExtCtrls, Vcl.StdCtrls, System.SysUtils, Vcl.Graphics, Math;

procedure TForm1.CreateButtonsFromConfig;
var
  Ini: 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);

    // 动态创建 GridPanel
    GridPanel := 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 do
      GridPanel.RowCollection.Add;

    for i := 0 to Cols - 1 do
      GridPanel.ColumnCollection.Add;

    // 在每个单元格中添加按钮
    for i := 0 to SectionList.Count - 1 do
    begin
      // 读取按钮的属性
      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;
  finally
    Ini.Free;
    SectionList.Free;
  end;
end;

procedure TForm1.ButtonClick(Sender: TObject);
var
  Link: string;
begin
  Link := (Sender as TButton).Hint;
  if Link <> '' then
    ShellExecute(0, 'open', PChar(Link), nil, nil, SW_SHOWNORMAL);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  CreateButtonsFromConfig;
end;
代码解析
  1. 读取配置文件

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

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

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

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

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

结果如下

结论

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

相关推荐
Amd7942 天前
Nuxt.js 应用中的 prerender:routes 事件钩子详解
路由·nuxt·seo·钩子·ssg·动态·预渲染
亿牛云爬虫专家3 天前
动态与静态网站抓取的区别:从抓取策略到性能优化
爬虫·爬虫代理·网站·代理ip·抓取·动态·静态
花开莫与流年错_4 天前
C#读取.ini配置文件
开发语言·数据库·c#·配置·配置文件·ini
Amd7947 天前
Nuxt.js 应用中的 components:extend 事件钩子详解
vue·生命周期·组件·nuxt·扩展·钩子·动态
侠亦狐7 天前
Android:ViewPaper动态添加移除第一页
android·viewpager·动态·移除·第一项
Amd7948 天前
Nuxt.js 应用中的 components:dirs 事件钩子详解
解析·组件·nuxt·目录·扩展·钩子·动态
Amd79410 天前
Nuxt.js 应用中的 imports:context 事件钩子详解
配置·nuxt·导入·钩子·上下文·动态·灵活
Amd79411 天前
Nuxt.js 应用中的 imports:extend 事件钩子详解
组件·模块·nuxt·导入·扩展·钩子·动态
衣舞晨风14 天前
Spring boot 配置文件的加载顺序
spring boot·加载·配置文件·顺序·1024程序员节
艾伦~耶格尔24 天前
Spring Boot 之三大配置文件.properties、.yml、.yaml 及其优先级解析
java·spring boot·后端·spring·配置文件