Delphi和Lazarus之间的表单初始化差异?

6

MainForm在运行时创建一些次要的Frame对象以显示各种选项面板。

以下是这些框架类的典型构造函数之一(它们都扩展了TFrame):

constructor Tframe2.Create(AOwner: TComponent);
begin
    inherited;
    edTime.Text := '12:00pm'; //edTime is a TEdit control. this line is where it throws the exception
    //etc.
end;

在Delphi中这段代码可以正常工作(无论做事情的方式是否正确),但是在Lazarus中,同样的代码会抛出EInvalidOperation异常,因为控件(TEdit)尚未分配父“窗口”(rsControlHasNoParentWindow),当我检查代码时,实际上这种情况有点合理,因为父类似乎直到构造函数调用后才被分配。

以下是在MainForm中初始化次要框架的代码:

if Assigned(frame) then FreeAndNil(frame);
case Node.AbsoluteIndex of
    optInterval: frame := Tframe2.Create(Self); //here's where the constructor gets called.
    //etc
end;
frame := TframeOther.Create(Self); 
if Assigned(frame) then
begin
    frame.Parent := panOptions; //here's where Tframe2's parent gets set
    frame.Align := alClient;
end;  

有没有人能解释一下 Delphi 和 Lazarus 在窗体初始化顺序方面是否有任何重要的区别?

对于这种初始化顺序问题,最常见的解决方法是什么?与我更熟悉的其他语言相比,可能会有不同的解决策略。我可以向构造函数添加另一个参数,或者如果有一个在构造函数和绘制屏幕之前调用的方法可以被覆盖,我也可以移动那段代码,或者只需创建一个辅助方法并在 setParent 被调用后调用它。这里有特定的最佳实践吗?

编辑:看起来这可能是与 TEdit 有关的特定问题。看起来初始化复选框状态的行没有出现同样的问题。这只是 Lazarus 中的一个 bug 吗?


我不知道那是否能解决问题,但在创建过程中设置继承的Create(AOwner)。 - Ravaut123
尝试简单的代码 TEdit.Create(nil).Text := '12345'; 这段代码创建了一个没有父级的编辑框并为其分配了一些标题。 如果在VCL中可以工作但在LCL中不行 - 那么这正好意味着它们在具有父级方面是不同的。还要注意,LCL只是对某个工具包库的包装器。有基于GTK+的LCL、基于Qt的LCL以及其他什么的。也许您可以将LCL后端切换到另一个库并进行修复。或者也许不行。 - Arioch 'The
我尝试了一下,但是无法复制这个问题(lazarus 0.9.30.4)。 - Sertac Akyuz
我尝试在一个全新的应用程序中重新创建错误,但是无法像在从Delphi导入的项目中那样发生。我猜测在我从Delphi导入的项目中可能存在不同的项目设置或编译器选项。 - Jessica Brown
1个回答

1
经过进一步的实验,我已经成功解决了大部分崩溃问题,通过添加一行代码将TEdit的父级设置为Frame(而不是Frame的父级)。就像这样:
edTime.Parent := Self;
edTime.Text := '12:00';

但我仍然希望更好地理解为什么有时候需要这样做。

编辑:虽然这可以解决在 TEdit 上设置文本的问题,但它并不能解决我拥有的自动调整大小代码,该代码遍历组件并调整任何可能是复选框的组件。显然,表单没有设置其父级仍然是“有点”问题。

编辑2:向构造函数添加第二个参数,并在构造函数中为整个表单设置父级似乎消除了完全设置 TEdit 的父级的需要。


2
当您创建一个可视控件(如TEdit)时,几乎总是需要这样做。它具有可视内容,因此需要在Parent.Canvas上绘制该内容。DFM流式传输方法会自动执行此操作(您可以在结构视图中查看子控件的lineageparent order,或通过查看DFM文本并观察缩进级别来查看)。当您在运行时使用代码创建控件时,必须自己完成此操作(正如您已经发现的那样)。 - Ken White

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接