【问题标题】:Are sizers a good way to deal with a form?sizers 是处理表单的好方法吗?
【发布时间】:2014-11-18 14:34:19
【问题描述】:

我正在将我的应用程序从旧的 GUI(我使用固定大小的地方)转移到 wxWidgets(我正在尝试学习 sizers 的基础)。

在应用程序中,我有几个结构相当复杂的表单。数据和工作流程的性质建议我将所有这些数据放在一个屏幕上。 但是这个屏幕必须经过适当的设计才能使用。

这是旧版本的表单...

...这或多或少是我使用 sizers 可以想出的...

请注意,我不能简单地使用 wxGridSizer,因为一些小部件跨越整个行,其他一些则脱离固定网格等。

显然我可以继续努力让它变得不那么难看,但我发现自己认为也许 sizers 不是正确的工具。为了实现我想要的,我需要类似于 wxGridSizer 的东西,具有某种 colspan/rowspan 机制,也许这还不够。

所以我开始考虑自己构建一个“Form Sizer”,它可能类似于

int w,h;
GetClientSize(&w,&h);
MyFormSizer *formSizer(w,h);
formSizer->SetDimension( widget1, 100, 20 );
formSizer->SetDimension( widget2, 500, 20 );
formSizer->newRow();
formSizer->SetDimension( widget3, 100, 20 );
formSizer->SetDimension( widget4, 250, 20 );
formSizer->SetDimension( widget5, 250, 20 );
formSizer->Layout();

用户将设置每个小部件的相对大小,以完全阻止表单的几何形状。为了使这个几何图形在调整大小时适合 wxPanel Layout() 将计算适当的缩放因子 f 然后将设置所有大小和位置做类似的事情

widget1->SetSize(CalculatedX, CalculatedY, 100/f, 20/f);
CalculatedX+=100/f;
widget2->SetSize(CalculatedX, CalculatedY, 500/f, 20/f);
CalculatedX+=0;
CalculatedY+=20/f;

等等(这只是一个划痕,把它当作一个粗略的想法;应该有机制来避免让所有东西都太小而无法适应小部件中的文本和/或相应地缩放字体大小等等) .

这看起来合理吗?你会如何面对这个话题?这个选择会影响我以后的发展,欢迎大家回答、批评和评论

【问题讨论】:

    标签: c++ wxwidgets sizer


    【解决方案1】:

    wxGridSizer 可能无法满足您的需求,但更灵活的类(例如 wxGridBagSizer)应该可以满足您的需求。此类允许您在调用wxGridBagSizer::Add 时通过设置wxGBSpan 将项目设置为跨越多行和多列。

    【讨论】:

    • 超级!我有点惭愧,我在浏览和阅读中从未发现过这个,这似乎真的是我的解决方案。给我一点测试,我会接受这个答案。
    • 我在实施您的建议时遇到了一些困难,但如果是因为工具或我对它缺乏信心,我不能说 jet。也就是说,我在管理列宽方面遇到了很大的困难:即使内容不同,它们也往往相同,而且我没有“比例”参数来处理它们。 wxSizer::SetItemMinSize() 做了一些工作,但例如我有一个列在所有行中跨行,但我有一个 20X20 按钮。您希望它是 20px 宽,而不是与其他列相同。我一直在测试!
    • 经过更多测试后,我决定接受您的回答。 wxGridBagSizer 并不完美,但它似乎是迄今为止满足我需求的最佳选择。
    【解决方案2】:

    正如@sjdowling 的回答中提到的,您可以使用wxGridBagSizer。但是我不推荐使用这个类,因为它存在一些绝对定位的问题,特别是它使得在它周围移动元素或添加它们非常困难,除非在最后。

    确实,wxWidgets sizer 缺乏对齐不同尺寸的元素的能力,如果你使用普通的 box 或 grid sizer,这就是你需要的,这很烦人。但是,您可以通过明确修复列的大小来解决它,或者只是硬编码它们(请至少使用对话框单元而不是像素,以避免破坏布局,尤其是在高 DPI 情况下),或者通过迭代所有标签并在所有标签上调用 GetTextExtent() 并选择最长的标签(这更可靠,尤其是在使用可以大幅改变字符串宽度(以像素为单位)的翻译时)。然后只需将此宽度分配给您创建的标签:由于初始宽度也是最小宽度,这将确保它们都具有此宽度并因此对齐,即使它们位于不同的尺寸器中。

    正如我所写,这有点烦人,但如果您在代码中创建布局,这确实不是那么糟糕。如果你在 GUI 设计器中做,那就更丑了,但你仍然可以从代码中调用wxSizer::SetItemMinSize()。当然,唯一真正的解决方案是添加对 inter-sizer 对齐的支持,但目前这仍然比使用 wxGridBagSizer IMO 更可取。

    【讨论】:

    • 不知道,我在实施@sjdowling 的建议时遇到了一些困难,但我不能说 jet 是因为工具还是我对它缺乏信心。请注意,我不打算使用绝对定位。你的建议很有趣,但看起来我必须创建一个 sizer 的包装器(我有大约 30 个表格,我不想把这个过程进行 30 次)并对其施加如此多的限制,这让我想知道为什么在这种情况下使用sizer - 请不要把我放在“拼命想重新发明轮子的人”列表中:-)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-05-06
    • 2020-04-20
    • 1970-01-01
    • 2023-03-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多