gpt4 book ai didi

delphi - 将子组件属性类型转换为 ini 文件

转载 作者:行者123 更新时间:2023-12-03 18:58:59 24 4
gpt4 key购买 nike

我目前对组件属性的类型转换非常头疼。

在我的表单上,我有一个名为“场景”的 TPanel。同样在表单上,​​我有一个创建 TSelection 的按钮, 并在其中 TSelection创建一个 TImage然后将图片加载到该 TImage 中。 TSelection 的名称是通过称为“ImgObjName”的 TEdit 分配的。然后它将这个名字写入一个inifile。 TSelection 的事件被分配给代码中其他地方的过程。如您所知,TSelection 组件可以在运行时移动(和调整大小)。 TImage 的 HitTest 关闭,而 TSelection 已打开。

以上工作如我所愿,但下一部分是我卡住的地方。本质上,在计时器上,我想将每个子组件的一些属性选择写入 TMemIniFile。我愿意这样做有两种方法;
1) 将每个 child 的属性写入单独的 TMemInifiles。
2) 将每个 child 的属性写入单个 TMemIniFile,但将 section确定该部分中的值与哪个组件相关。

我尝试了几种不同的方法,但它们都给我带来了一些重大问题(通常是“索引越界”)。

我目前的方法就是这样;
ChgPos是一个全局 bool 变量,当触发 TSelection 对象之一的 mousedown 事件时为 TRUE,当触发 MouseUp 事件时为 FALSE。这个 bool 过程非常适合这些目的,因此不需要进行任何更改。
TimerBarTTrackBar这是在设计时创建的。它的值根据计时器而变化。
AnimIni是前面代码中分配的 TMemIniFile。为此,我将其设置为不释放文件(因此没有访问冲突)。

var
i: Integer;
PosX, PosY: Integer;
begin
for i := 0 to Scene.ChildrenCount - 1 do
begin
if Scene.Components[i] is TSelection then
begin
PosX := AnimIni.ReadInteger(IntToStr(Round(TimerBar.Value)) + '_Object' +
IntToStr(i), 'PosX', PosX);
PosY := AnimIni.ReadInteger(IntToStr(Round(TimerBar.Value)) + '_Object' +
IntToStr(i), 'PosY', PosY);
end;
end;
if ChgPos = False then
begin
if Scene.Components[i] is TSelection then
begin
(Scene.Components[i] as TSelection).Position.X := PosX;
(Scene.Components[i] as TSelection).Position.Y := PosY;
end;
end
else if ChgPos = True then
begin
AnimIni.WriteInteger(IntToStr(Round(TimerBar.Value)) + '_Object' +
IntToStr(i), 'PosX', Round((Scene.Children[i] as TSelection).Position.X));
AnimIni.WriteInteger(IntToStr(Round(TimerBar.Value)) + '_Object' +
IntToStr(i), 'PosY', Round((Scene.Children[i] as TSelection).Position.Y));
end;
end;

我正在努力弄清楚该去哪里。我收到“索引超出范围”错误。我还需要保存 TImage 组件属性(尤其是父级和位图位置,但我觉得目前让代码与至少一个组件一起工作对我来说很重要)。

我对类型转换有点陌生(因为我以前的所有项目都不需要它),但到目前为止我所有的经验都非常成功。只是在这种特殊情况下,事实证明它变得比我在没有一些帮助的情况下可以解决的更复杂。

我试过 WriteComponentReadComponent并使用多个文件实时流式传输与 TimerBar 的值相关的数据,但对于我想要实现的目标(尤其是在写入功能上)来说太慢了。 inifile 方法在我之前的测试中确实有效,但它实际上是在对我遇到问题的运行时创建的多个组件进行类型转换。

任何人都可以阐明潜在的解决方案或我应该前进的方向吗?

最佳答案

  • 您正在混合组件和子项。如果您遍历面板的所有子面板,请不要在 Components 上使用该索引。属性(property),但 Children属性(property)。 (我假设您的代码已编译并且 XE2 具有 Children 属性,否则我认为您的意思是 ControlsControlCount )。
  • 就像已经评论过的 LU RD 一样,您正在使用 for 循环变量 i在for循环之外。我确定你想要它在里面。编译器还会警告您:

    FOR-loop variable 'i' may be undefined after loop



    始终确保你有零!编译器错误、警告和提示。
  • 我不明白你的例程逻辑,因为它会加载设置,即使你真的想写它们。我认为您只想在 ChgPos 时从 MeminiFile 加载设置是假的。

  • 没有给出任何保证,但我认为例程应该是这样的(包括一些语法改进):
    var
    i: Integer;
    Selection: TSelection;
    PosX, PosY: Integer;
    begin
    for i := 0 to Scene.ChildrenCount - 1 do
    if Scene.Children[i] is TSelection then
    begin
    Selection := Scene.Children[i] as TSelection;
    if ChgPos then
    begin
    AnimIni.WriteInteger(IntToStr(Round(TimerBar.Value)) + '_Object' +
    IntToStr(i), 'PosX', Round(Selection.Position.X));
    AnimIni.WriteInteger(IntToStr(Round(TimerBar.Value)) + '_Object' +
    IntToStr(i), 'PosY', Round(Selection.Position.Y));
    end
    else
    begin
    PosX := AnimIni.ReadInteger(IntToStr(Round(TimerBar.Value)) +
    '_Object' + IntToStr(i), 'PosX', PosX);
    PosY := AnimIni.ReadInteger(IntToStr(Round(TimerBar.Value)) +
    '_Object' + IntToStr(i), 'PosY', PosY);
    Selection.Position.X := PosX;
    Selection.Position.Y := PosY;
    end;
    end;
    end;

    虽然我严重怀疑 AnimIni.ReadInteger 的默认值函数, PosXPosY , 未赋值。如果在 ini 文件中没有找到任何节,则 PosXPosY将具有任意值。您应该将它们初始化为任何有意义的值。

    关于delphi - 将子组件属性类型转换为 ini 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9953059/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com