样本表,隐藏的小部件和Qt中的大小

时间:2014-01-23 18:32:13

标签: qt resize qt4 stylesheet qtstylesheets

样式表存在很大问题。

如果你通过样式表设置大小,方法是设置max和min值相同(固定大小)或者其他,然后尝试使用widget上的size()获取它们,如果widget永远不会已经证明你得到的尺寸很奇怪。

但是你也无法从样式表中获取它们,因此你必须显示所有小部件调整大小或获取位置。

在我的情况下,我从一个窗口开始。但是此窗口下的小部件将在稍后出现,并且必须在出现之前将它们定位在正确的位置。我有浮动小部件,它们没有作为QMainWindow的孩子集成,所以我用手移动它们并定位它们......但是如果我不知道它们是怎么做的话我该怎么办呢?

您是否知道获取样式表中存储的大小的其他方法?。

1 个答案:

答案 0 :(得分:5)

到目前为止,我知道有三种解决方案:

  1. 修改小部件:致电widget->ensurePolished()

  2. 通过样式打磨小部件:调用qApp->style()->polish(widget)

  3. 在小部件显示之前,将小部件上发布的事件发送到小部件:QCoreApplication::sendPostedEvents(widget, 0)。使用Qt 5,您不需要第二个参数,因为它现在具有默认值0。

  4. 您的问题的另一个解决方案是根本不写任何同步代码。在第一次显示时放置顶级窗口小部件:

    1. 在小部件上安装事件过滤器。

    2. 当show事件到达窗口小部件时:

      1. 从小部件中卸载事件过滤器。

      2. 发送所有窗口的事件,直到没有剩下:

        while (widget->d_ptr->postedEvents)
          QCoreApplication::sendPostedEvents(widget, 0);
        

        现在可以保证小部件可见并且大小正确。

      3. 使用小部件的几何体并移动它。如果您需要来自所有小部件的信息来做出决定,请将其存储在某些数据结构中,并仅在所有小部件都存在时对其进行处理。

    3. 如果您希望阻止小部件在错误位置的临时可见性,您可能希望代替调整大小事件。布局和样式系统将适当调整顶级窗口小部件的大小以适应其内容。您应该卸载事件过滤器并仅在从调用返回到sendPostedEvents时不再为该对象传递事件时处理最新几何。

      以下演示了强制抛光方法,并在Qt 4.8.5和5.2.0下工作。我已经在OS X上的64位构建和Windows上的32位构建上进行了测试。

      请注意,l1l2均未显示,但它们都报告了正确的尺寸。显示l3,但在显示之前查询时,报告的大小错误。

      screenshot

      #include <QApplication>
      #include <QLabel>
      #include <QStyle>
      
      int main(int argc, char *argv[])
      {
          QApplication a(argc, argv);
          QString style("QLabel { min-height:100px; max-height:100px; min-width: 300px; max-width:300px }");
          a.setStyleSheet(style);
          QLabel l1, l2, l3;
          l1.ensurePolished(); // equivalent first/second methods
          QCoreApplication::sendPostedEvents(&l2, 0); // third method
          l3.setText(QString("l1: %1 x %2 l2: %3 x %4 l3: %5 x %6")
                     .arg(l1.width()).arg(l1.height())
                     .arg(l2.width()).arg(l2.height())
                     .arg(l3.width()).arg(l3.height()));
          l3.setAlignment(Qt::AlignCenter);
          l3.show();
          return a.exec();
      }