【问题标题】:How to equally distribute the width of QSplitter如何平均分配QSplitter的宽度
【发布时间】:2017-05-07 12:30:45
【问题描述】:

我在调整QSplitter 的宽度时遇到问题。我在 Qt Designer 中准备了 UI,现在看起来像这样:

设计器视图

这是我的对象检查器

我的问题是如何将QSplitter 的宽度平均划分为左右区域。我想将这种效果作为初始尺寸,然后客户可以做任何他想做的事情。

我想要的效果如下:

在其他世界中,我正在寻找一种方法来将左右区域的拆分器初始划分指定为窗口宽度的 50%/50%。有没有办法获得它?

感谢您的帮助,请见谅,我刚开始学习Qt。

【问题讨论】:

    标签: qt qt-designer


    【解决方案1】:

    简答

    splitter->setSizes(QList<int>({INT_MAX, INT_MAX}));
    

    注意:如果您需要其他比率,微调部分可能包含基本信息。

    说明

    QSpacer?没有。

    在这种情况下,您不需要QSpacer。间隔器的目标是填充所有可用空间。

    QSplitter 提供了两种方法来指定其子项的大小:

    1。 QSplitter::setStretchFactor?没有。

    虽然 拉伸因子 似乎是您正在寻找的用于指定子小部件的相对大小的东西,但对于您的情况而言,它的缺点是这些因子相对于子小部件:

    stretch 不是有效的拉伸因子;有效伸展 因子是通过获取小部件的初始大小来计算的,并且 将它与 stretch 相乘。

    因此,将两个孩子的拉伸因子设置为相同的值(例如1)将无法正常工作:

    splitter->setStretchFactor(0, 1);
    splitter->setStretchFactor(1, 1);
    

    2。 QSplitter::setSizes?是的。

    更好的选择是使用 setSizes,因为只有相对大小很重要:

    拆分器小部件的整体大小不受影响。相反,任何 额外/缺失的空间根据小部件分布在 相对于尺寸的权重。

    因此,人们可能会认为将两个尺寸都设置为一个会将总尺寸平均分配给两个孩子:

    splitter->setSizes(QList<int>({1, 1}));
    

    不,因为您应该考虑到将通过用最小尺寸替换太小的值来强制执行最小尺寸政策:

    小部件的尺寸策略被保留。也就是说,一个值 小于相应小部件的最小尺寸提示将是 替换为提示的值。

    因此,您应该使用大于您孩子的最小尺寸的值,例如可以用int 表示的最大数字,即INT_MAX

    splitter->setSizes(QList<int>({INT_MAX, INT_MAX}));
    

    微调

    正如 cmets 中所建议的,INT_MAX 可能会导致一些溢出问题,具体取决于 Qt 对这些值所做的计算。因此,屏幕宽度/高度可能是一个更明智的大值。

    // Horizontal splitter
    int largeWidth = QGuiApplication::primaryScreen ()->size ().width ();
    splitter->setSizes(QList<int>({largeWidth , largeWidth}));
    
    // Vertical splitter
    int largeHeight = QGuiApplication::primaryScreen ()->size ().height ();
    splitter->setSizes(QList<int>({largeHeight , largeHeight}));
    

    进一步阅读

    大多数时候,Qt 可以很好地为所有小部件提供适当的大小,但调整它可能会变得非常困难,需要一些反复试验。因此,我想提供一些额外的资源,这些资源在 Qt 中使用布局管理时可能很有用:

    【讨论】:

    • 我不建议在 QSplitter 大小的上下文中使用 INT_MAX。在某些情况下它运作良好,在某些情况下则不行。如果您想最大化一个部分并最小化另一个部分,使用 QList({INT_MAX, 1}) 将不起作用。因为它在 qlayoutengine.cpp 中调用 qGeomCalc,并且有计算拉伸因子总和的“int sumStretch”变量。对于像 INT_MAX 这样的巨大数字,它可能会溢出并产生错误的结果。
    • @Vladislav,你有什么建议?当所有值都设置为 INT_MAX 时是否有问题?如果你试图最大化一个部分并最小化另一个部分,设置QSizePolicy::Policy(分别为Maximum/PreferredMinimumExpanding)不是更合适吗?
    • 想象一下用于 2 个小部件的拆分器。如果你 setSizes({INT_MAX, INT_MAX}) 它分成 2 个相等的部分。如果你 setSizes({INT_MAX, 1}) - 它也会分成 2 个相等的部分。如果您调用 setSizes({99999, 1}) -它将最大化第一个小部件并最小化第二个小部件。关于 SizePolicy,是的,它是更合适的解决方案,但是如果您调用一次 QSplitter::setSizes() 方法,则该拆分器将不会对 SizePolicy 更改做出反应。
    【解决方案2】:

    基于m7913d's

    要等分拆分器,请使用QSplitter::setSizes,列表中的每个大小都应该相等。使用QWidget::minimumSizeHint() 确定要使用的大小。使用您添加到拆分器的每个小部件的最大宽度(对于水平拆分器)或最大高度(对于垂直拆分器)

    // Example for a horizontal splitter
    splitter = new QSplitter(Qt::Horizontal, this);
    splitter->addWidget(widgetLeft);
    splitter->addWidget(widgetRight);
    auto equalWidth = std::max(widgetLeft->minimumSizeHint().width(), 
                               widgetRight->minimumSizeHint().width());
    splitter->setSizes({ equalWidth, equalWidth });
    
    // Example for a vertical splitter
    splitter = new QSplitter(Qt::Vertical, this);
    splitter->addWidget(widgetTop);
    splitter->addWidget(widgetBottom);
    auto equalHeight = std::max(widgetTop->minimumSizeHint().height(),
                                widgetBottom->minimumSizeHint().height());
    splitter->setSizes({ equalHeight, equalHeight });
    

    【讨论】:

      【解决方案3】:

      我会建议进一步的变化。 m7913d 的点都成立并且很重要。但就我而言(Qt5.13.2),我发现设置足够大的尺寸仍然会导致一些变化。我不知道为什么,但是将所有拉伸因子设置为一个另外最终表现得像我想要的那样。

      另请注意,将所有拉伸因子设置为 1,但使用不相等(但仍足够大以避免最小尺寸限制)尺寸和 setSizes 也可以!例如:

      splitter->setStretchFactor(0,1);
      splitter->setStretchFactor(1,1);
      splitter->setSizes({static_cast<int>(10000 / 1.618), static_cast<int>(10000 - 10000 / 1.618)});
      

      设置黄金分割比例。

      【讨论】:

      • 请注意,这似乎也不是稳定的,它只是更稳定。在我的代码中,我不得不忍受相当多的跳跃……不知道为什么 Qt 解决得这么差
      猜你喜欢
      • 2021-05-18
      • 2016-01-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-16
      相关资源
      最近更新 更多