我想从用户那里获取多个不同类型的值(时间、压力、名称……)。我想自定义我的输入框。但它只取一个值。
有什么办法可以解决这种情况,或者使用任何组件吗?
我想从用户那里获取多个不同类型的值(时间、压力、名称……)。我想自定义我的输入框。但它只取一个值。
有什么办法可以解决这种情况,或者使用任何组件吗?
弗朗索瓦是对的。你已经达到了你得到的工具的极限。InputBox
根本不是为复杂输入而设计的,也不是为了处理多个值而设计的。
您在评论中链接到的页面有一个示例,但它的呈现效果很差,所以我不怪您误解它。我也读了几本书才明白。它的核心是MyAsk
底部的功能。(忽略TAppendThread
顶部的类声明。它没用。)MyAsk
接受带有提示和值的记录列表,并且对于每条记录,它调用InputBox
以向用户请求一个值。没有记录可能更容易理解。可以这样重写:
procedure MultiInputBox(const Prompts: array of string; var Values: array of string]);
var
i: Integer;
begin
Assert(Length(Prompts) = Length(Values));
for i := 0 to High(Prompts) do begin
Values[i] := InputBox(Application.Title, Prompts[i], Values[i]);
end;
end;
像这样称呼它:
TempTime := TimeToStr(DefaultTime);
TempPressure := IntToStr(DefaultPressure);
TempName := DefaultName;
MultiInputBox(['Time', 'Pressure', 'Name'], [TempTime, TempPressure, TempName]);
TimeToUse := StrToTime(TempTime);
PressureToUse := StrToInt(TempPressure);
NameToUse := TempName;
不过,这对用户来说是一个糟糕的界面。没有办法回去,没有办法取消,没有迹象表明询问将持续多长时间,也没有办法强制某些数据类型的格式。如果您设计一个能够准确获取所需信息的自定义表单,您的情况会好得多。您正在使用一种工具来设计一个关于世界上最简单的事情的表单。不要抗拒。
如果您需要获取时间、压力和名称,则制作一个具有三个输入控件的表单。使用 aTDateTimePicker
作为时间,考虑使用 aTSpinEdit
作为数字输入,使用 aTEdit
作为名称。将TLabel
控件放在每个输入旁边,以便用户知道每个输入的用途。将确定和取消按钮放在表单上。设置各种其他表单属性,例如边框样式和标题。几乎没有代码可以以这种形式编写。不过,您可以自由添加代码来验证输入值,以确保它们有意义。
要使用它,只需创建它,填充它的初始值,以模态方式显示它,并在它关闭时读出新值。
var
form: TDatePressureNameDialog;
begin
form := TDatePressureNameDialog.Create(nil);
try
form.TimePicker.Value := DefaultTime;
form.PressureEdit.Value := DefaultPressure;
form.NameEdit.Text := DefaultName;
if form.ShowModal = mrOK then begin
TimeToUse := Frac(form.TimePicker.Value);
PressureToUse := form.PressureEdit.Value;
NameToUse := form.NameEdit.Text;
end;
finally
form.Free;
end;
end;
还要注意我如何检查ShowModal
方法的结果。这让您知道用户是否按下了确定或取消来关闭表单。你不能这样做InputBox
,它总是返回一个字符串。(InputQuery
可以告诉您该信息,这是这两个函数之间的主要区别,但仅此一点并不能真正使这两个函数在您的情况下值得使用。)
不要担心这个新的表单类会影响您的项目。对项目规模影响最大的两件事是SysUtils和Forms单元。你已经包括了那些,所以最糟糕的已经过去了。将表单添加到已经至少有一个表单的项目中,根本不会影响项目大小,尤其是我上面描述的表单,它只有八个控件。
“输入框”到底是什么意思 - TEdit?有许多不同种类的输入组件,它们可以做许多不同的事情。对于名称,TEdit 非常好 - 但对于时间,您可能想要一个日历控件,对于压力,您可能想要使用一个看起来非常适合数字的控件。
是的,设计一个表格!
Dialogs.InputBox 旨在从用户那里获取 1 个字符串,快速而简单。
如果你想要更多,你必须设计一个参赛表格。
如果您想要一个基本对话框,您可以查看 Dialogs.InputQuery 中的代码,并将其用作编写您自己的过程的起点。
如果你想要真正的交易,你必须深入挖掘并编写一个真正的表单。
Rob 的 Kennedy 是对的。输入框不是一个好的选择...您到底想保存什么?Exe 空间、资源或源代码?或者你只是想用你的“绿色”代码来拯救环境?
如果您看一下 InputQuery 函数,您会发现它所做的是创建一个 TForm 并创建一些 TButtons/TLabels/TEdit,定位并显示模态表单。
您将使用添加到项目中的新表单来做什么......除此之外,您还可以验证、自定义控件并定位它们,甚至添加提示......
使用新表格...
您不必将每个表单都设置为自动创建,在创建表单后进入项目选项,选择表单选项并将所有您不希望自动创建的表单移到右侧。
我最常用于这些非自动创建表单的模式如下所示:
Function GetValuesFromDialog : boolean;
var
dlg : tValuesDialog;
begin
result := false;
dlg := tValuesDialog.Create(nil);
try
// set initial values in dialog
dlg.SetValues( rData );
// show the dialog
result := dlg.ShowModal = mrOk;
// pull values from dialog
if result then
dlg.GetValues( rData );
finally
dlg.free;
end;
end;
GetValues/SetValues 方法从保存例程中使用的值的记录或类填充对话框。我从不尝试从表单外部操作表单上的控件,而是编写例程在表单本身中进行操作。