Qt:如何在两个不同的 QGridLayout 中对齐小部件?
Qt: How can I align widgets in two different QGridLayouts?
我正在尝试排列来自两个不同 QGridLayout 的小部件。这个想法如下:我在滚动框架的 QGridLayout 中有很多行小部件。每行可能包含 8 列其他小部件(因此 8xN 小部件的网格,N = 行数)。该行中的第一个小部件是一个 show/hide 按钮,选中该按钮后,将在该行下方显示具有相同布局的另一个小部件(即,显示的小部件有几行小部件,每行有 7 列小部件)。因此,显示的小部件最初将被插入,并在切换显示按钮时 shown/hidden。
下图说明了我的设置。标记为 "A" 的红色括号指示的小部件是我在选中左侧复选框时显示的小部件(它们没有自己的显示按钮)。
我需要解决的问题是如何让显示的小部件与所有其他小部件对齐。我在这里想到了两个选择:
- 将所有小部件放在同一布局中,只循环遍历我需要 show/hide 的小部件。这样做的好处是所有小部件都排成一行,因为它们位于同一布局中。糟糕的是,如果我有数百行小部件(这很常见),则需要很长时间才能全部显示出来。
- 将子小部件放在它们自己的容器小部件中,并让 show/hide 按钮只是 show/hide 那个小部件。好处是这比 showing/hiding 每个单独的小部件快得多,但不好的一面是小部件现在没有排列,因为子小部件处于不同的布局中。我认为这是更好的选择。我只需要弄清楚如何对齐所有类似的小部件。
希望这很清楚。我正在使用 Qt 5.11。提前感谢您的帮助。
好吧,如果您有太多的小部件,以至于在现代计算机上加载速度很慢,您可能想要采用完全不同的策略来加载实际的小部件 "lazily." 即使是隐藏的,它们也需要时间来加载生成,内存存储,等等。 OTOH 类似于 model/view 框架的东西在请求编辑之前显示相对轻量级的仅显示标签,然后才绘制(相对)复杂的编辑器小部件。并且视图具有按需加载额外数据的规定(延迟加载),这正是您正在寻找的。
但无论如何要回答您的问题,您基本上需要跟踪 "reference" 网格(可能是您的第一个网格)的宽度,并在任何其他网格上手动设置网格列。这并不难,因为您可以轻松遍历列并调用 QGridLayout::setColumnMinimumWidth()
。 "reference grid" 的另一种选择是自己计算列宽(当然,如果您想适应内容宽度,这会涉及更多)。
QGridLayout gl1;
gl1.setSizeConstraint(QLayout::SetMinimumSize); // maybe
gl1.addWidget(..., 0, 0);
gl1.addWidget(..., 0, 1);
gl1.addWidget(..., 0, 2);
gl1.activate(); // or show it or something... it needs to calculate its sizeHint().
QVector<int> colWidths;
for (int i=0; i < gl1.columnCount(); ++i)
colWidths << gl1.columnMinimumWidth(i);
QGridLayout gl2;
gl2.addWidget(..., 0, 0);
gl2.addWidget(..., 0, 1);
gl2.addWidget(..., 0, 2);
for (int i : colWidths)
gl2.setColumnMinimumWidth(i);
这可能过于简单,但本质上您需要一种 "brute force" 方法来使用单独的布局。如果布局中的小部件具有固定宽度,这将有很大帮助,如果您提前知道它们,那么它会变得更加容易。对布局类型进行子类化、滚动自己的布局类型或 assemble 从单独的 H/V 框布局中提取网格也可能会有所帮助。
但是真的,你一说"hundreds of widgets"我就觉得"no."BTDT。我会看一下 model/view 框架,如果情况真的那么绝望,也许会考虑实施我自己的 QAbstractItemView
。 :)
我正在尝试排列来自两个不同 QGridLayout 的小部件。这个想法如下:我在滚动框架的 QGridLayout 中有很多行小部件。每行可能包含 8 列其他小部件(因此 8xN 小部件的网格,N = 行数)。该行中的第一个小部件是一个 show/hide 按钮,选中该按钮后,将在该行下方显示具有相同布局的另一个小部件(即,显示的小部件有几行小部件,每行有 7 列小部件)。因此,显示的小部件最初将被插入,并在切换显示按钮时 shown/hidden。
下图说明了我的设置。标记为 "A" 的红色括号指示的小部件是我在选中左侧复选框时显示的小部件(它们没有自己的显示按钮)。
我需要解决的问题是如何让显示的小部件与所有其他小部件对齐。我在这里想到了两个选择:
- 将所有小部件放在同一布局中,只循环遍历我需要 show/hide 的小部件。这样做的好处是所有小部件都排成一行,因为它们位于同一布局中。糟糕的是,如果我有数百行小部件(这很常见),则需要很长时间才能全部显示出来。
- 将子小部件放在它们自己的容器小部件中,并让 show/hide 按钮只是 show/hide 那个小部件。好处是这比 showing/hiding 每个单独的小部件快得多,但不好的一面是小部件现在没有排列,因为子小部件处于不同的布局中。我认为这是更好的选择。我只需要弄清楚如何对齐所有类似的小部件。
希望这很清楚。我正在使用 Qt 5.11。提前感谢您的帮助。
好吧,如果您有太多的小部件,以至于在现代计算机上加载速度很慢,您可能想要采用完全不同的策略来加载实际的小部件 "lazily." 即使是隐藏的,它们也需要时间来加载生成,内存存储,等等。 OTOH 类似于 model/view 框架的东西在请求编辑之前显示相对轻量级的仅显示标签,然后才绘制(相对)复杂的编辑器小部件。并且视图具有按需加载额外数据的规定(延迟加载),这正是您正在寻找的。
但无论如何要回答您的问题,您基本上需要跟踪 "reference" 网格(可能是您的第一个网格)的宽度,并在任何其他网格上手动设置网格列。这并不难,因为您可以轻松遍历列并调用 QGridLayout::setColumnMinimumWidth()
。 "reference grid" 的另一种选择是自己计算列宽(当然,如果您想适应内容宽度,这会涉及更多)。
QGridLayout gl1;
gl1.setSizeConstraint(QLayout::SetMinimumSize); // maybe
gl1.addWidget(..., 0, 0);
gl1.addWidget(..., 0, 1);
gl1.addWidget(..., 0, 2);
gl1.activate(); // or show it or something... it needs to calculate its sizeHint().
QVector<int> colWidths;
for (int i=0; i < gl1.columnCount(); ++i)
colWidths << gl1.columnMinimumWidth(i);
QGridLayout gl2;
gl2.addWidget(..., 0, 0);
gl2.addWidget(..., 0, 1);
gl2.addWidget(..., 0, 2);
for (int i : colWidths)
gl2.setColumnMinimumWidth(i);
这可能过于简单,但本质上您需要一种 "brute force" 方法来使用单独的布局。如果布局中的小部件具有固定宽度,这将有很大帮助,如果您提前知道它们,那么它会变得更加容易。对布局类型进行子类化、滚动自己的布局类型或 assemble 从单独的 H/V 框布局中提取网格也可能会有所帮助。
但是真的,你一说"hundreds of widgets"我就觉得"no."BTDT。我会看一下 model/view 框架,如果情况真的那么绝望,也许会考虑实施我自己的 QAbstractItemView
。 :)