【问题标题】:How disable and enable Button Click event depending on some variable in Delphi?如何根据 Delphi 中的某些变量禁用和启用按钮单击事件?
【发布时间】:2018-05-07 15:11:24
【问题描述】:

我有一个 Delphi 10.0 Seattle 项目将一些文件通过 FTP 传输到服务器。

我会做以下事情:

  1. 在 Button1 OnClick 事件中,我将计算一些东西并制作一个文本文件。 Edit1 将保存文件名。

  2. 在 Button2 OnClick 事件中,文件名的最后 4 个字符将被删除。该文件将使用新名称重命名。 Edit2 将保留新名称,并将其上传到一台服务器。

  3. 在文件上传过程中,没有任何按钮单击将起作用,并且无法关闭表单。我使用了一个布尔变量FileToBeTranferred。在创建表单时是false

我写了以下代码:

unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, System.Math;

type
  TForm1 = class(TForm)
    Edit1: TEdit;
    Edit2: TEdit;
    Button1: TButton;
    Button2: TButton;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}
var
  FileToBeTranferred: boolean;

procedure TForm1.Button1Click(Sender: TObject);
begin
  if FileToBeTranferred = false then
    begin
      //Do some calculation
      //Edit1.Text := Output File Name
      FileToBeTranferred := true;
    end
  else
    begin
      Button1.Click(nil);
    end;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  if FileToBeTranferred = true then
  begin
    Edit2.Text := delete(Edit1.Text, (length(Edit1.Text)-4), 4);
    //Upload to Server
    Button2.Click(self);
  end
  else
  begin
    //Upload finished
    FileToBeTranferred := false;
    Button2.Click(nil);
  end;
end;

procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
 if FileToBeTranferred = true then CanClose := false
 else CanClose := true;

end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  FileToBeTranferred := false;
end;

end.

我什么都做不了。我收到太多错误。错误如下:

  1. [dcc32 Error] Unit1.pas(44): E2197 Constant object cannot be passed as var parameter in Edit2.Text := delete(Edit1.Text, (length(Edit1.Text)-4), 4); - 用于删除文件重命名的最后 4 个字符。

  2. [dcc32 Error] Unit1.pas(47): E2034 Too many actual parameters in Button2.Click(nil); - 由于 FTP 正在进行,因此不允许对文件进行更多修改。 Button1.Click 不会执行任何操作。

  3. [dcc32 Error] Unit1.pas(47): E2034 Too many actual parameters in Button2.Click(self);- 随着 FTP 进度完成,文件已准备好追加。 Button2.Click 不会执行其通常的工作。

解决办法是什么?

【问题讨论】:

  • 这里有各种各样的问题。首先,不要假设文件扩展名是三个字符长。不要假设文件甚至有扩展名。使用适当的功能删除文件扩展名。您不能在属性上使用 Delete。它需要一个变量。这就是错误消息所说的。太多的参数意味着,呃,太多的参数。阅读错误消息非常重要,而不仅仅是假设它们不携带任何信息。不要使用全局变量来获取与表单实例状态相关的信息。这就是实例变量的用途。
  • 不要使用默认组件名称。 Button1 和 Button2 传递什么信息。不要测试 = true 或 = false。分别执行if someBool thenif not someBool then。确保您知道您使用的是什么版本的 Delphi。没有XE10这样的东西。从 IDE 的标题栏中读取版本。从 Button2 单击事件处理程序调用 Button2,Click 势必会导致未终止的递归。
  • 我别无选择。我必须删除文件名的最后 4 个字符。我还尝试使用变量 procedure TForm1.Button2Click(Sender: TObject); var MyText : string; TextLength : integer; NewText : string; begin MyText := Edit1.Text; TextLength := length(MyText); NewText := delete(MyText, (TextLength-4),4); Edit2.Text := NewText; if FileToBeTranferred = true then end; 来删除文件名的最后 4 个字符。它也不起作用。
  • 版本是 RAD Studio XE10 Seattle。
  • 好吧,这完全是在浪费我们的时间。那不是那个版本。没有 XE10 西雅图之类的东西。阅读 IDE 标题栏。它说什么?上面写着“XE10西雅图”吗?不,不是的。至于文件名的最后 4 个字符,你有没有看我的评论?在我看来,你似乎已经放弃了试图理解这一点,只是希望别人为你做这件事。展望未来,这对您有何帮助?你会学到什么?再读一遍我的cmets,再努力一点。

标签: delphi delphi-10-seattle


【解决方案1】:

您显示的代码只是各种错误。不仅仅是语法错误,还有逻辑错误。即使代码已编译,如果FileToBeTranferred 为真,您的Button1 点击处理程序将陷入无限递归循环,而您的Button2 点击处理程序将陷入无限递归循环,而不管FileToBeTranferred

尝试类似的方法:

unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, System.Math;

type
  TForm1 = class(TForm)
    Edit1: TEdit;
    Edit2: TEdit;
    Button1: TButton;
    Button2: TButton;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
  private
    { Private declarations }
    FileToBeTranferred: boolean;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
  if not FileToBeTranferred then
  begin
    //Do some calculation
    //Edit1.Text := Output File Name
    FileToBeTranferred := True;
  end;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  if FileToBeTranferred then
  begin
    Edit2.Text := Copy(Edit1.Text, 1, Edit1.GetTextLen-4);
    //Upload to Server, wait for completion
    FileToBeTranferred := False;
  end;
end;

procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
  CanClose := not FileToBeTranferred;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  FileToBeTranferred := False;
end;

end.

话虽如此,您可能会考虑另一种方法。例如,根本不需要 FileToBeTranferred 布尔值:

unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, System.Math;

type
  TForm1 = class(TForm)
    Edit1: TEdit;
    Edit2: TEdit;
    Button1: TButton;
    Button2: TButton;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
  Button1.Enabled := False;
  //Do some calculation
  //Edit1.Text := Output File Name
  Button2.Enabled := True;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  Button2.Enabled := False;
  Edit2.Text := Copy(Edit1.Text, 1, Edit1.GetTextLen-4);
  //Upload to Server
  Button1.Enabled := True;
end;

procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
  CanClose := Button1.Enabled;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  Button1.Enabled := True;
  Button2.Enabled := False;
end;

end.

或者,您可以结合这两种方法,在任何给定时刻根据FileToBeTranferred 的当前值启用/禁用TButton 对象。

您可以覆盖表单的虚拟UpdateActions() 方法:

unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, System.Math;

type
  TForm1 = class(TForm)
    Edit1: TEdit;
    Edit2: TEdit;
    Button1: TButton;
    Button2: TButton;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
  protected
    procedure UpdateActions; override;
  private
    { Private declarations }
    FileToBeTranferred: boolean;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
  //Do some calculation
  //Edit1.Text := Output File Name
  FileToBeTranferred := True;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  Edit2.Text := Copy(Edit1.Text, 1, Edit1.GetTextLen-4);
  //Upload to Server, wait for completion
  FileToBeTranferred := False;
end;

procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
  CanClose := not FileToBeTranferred;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  FileToBeTranferred := False;
end;

procedure TForm1.UpdateActions;
begin
  inherited;
  Button1.Enabled := not FileToBeTranferred;
  Button2.Enabled := FileToBeTranferred;
end;

end.

或者,您可以将TActionList 拖放到表单上并为每个TButton 分配一个TAction,然后在其OnUpdate 事件中启用/禁用TAction 对象:

unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, System.Math, Vcl.ActnList;

type
  TForm1 = class(TForm)
    Edit1: TEdit;
    Edit2: TEdit;
    Button1: TButton;
    Button2: TButton;
    ActionList1: TActionList;
    Action1: TAction;
    Action2: TAction;
    procedure Action1Update(Sender: TObject);
    procedure Action2Update(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private declarations }
    FileToBeTranferred : Boolean;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Action1Update(Sender: TObject);
begin
  Action1.Enabled := not FileToBeTranferred;
end;

procedure TForm1.Action2Update(Sender: TObject);
begin
  Action2.Enabled := FileToBeTranferred;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  //Do some calculation
  //Edit1.Text := Output File Name
  FileToBeTranferred := True;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  Edit2.Text := Copy(Edit1.Text, 1, Edit1.GetTextLen-4);
  //Upload to Server, wait for completion
  FileToBeTranferred := False;
end;

end.

【讨论】:

    猜你喜欢
    • 2015-08-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-27
    • 1970-01-01
    • 2020-11-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多