До сих пор я знаю три варианта:
widget->ensurePolished()
. qApp->style()->polish(widget)
. QCoreApplication::sendPostedEvents(widget, 0)
в виджетах до его показа. С Qt 5 вам не нужен второй аргумент, так как теперь он имеет значение по умолчанию 0. Другим решением вашей проблемы было бы просто не писать синхронный код вообще. Чтобы отобразить виджет верхнего уровня, когда он впервые показан:
while (widget->d_ptr->postedEvents)
QCoreApplication::sendPostedEvents(widget, 0);
Теперь вам гарантировано, что виджет виден и имеет правильный размер. Используйте геометрию виджета и переместите ее. Если вам нужна информация из всех виджетов, чтобы принять это решение, сохраните его в некоторой структуре данных и обработайте его только тогда, когда все виджеты есть. Если вы хотите предотвратить временную видимость виджетов в неправильных положениях, вы можете захотеть действовать вместо события изменения размера. Система компоновки и стилизации изменяет размер виджета верхнего уровня, подходящего для его содержимого. Вам необходимо удалить фильтр событий и обработать самую последнюю геометрию только тогда, когда больше нет событий для этого объекта после возврата из вызова sendPostedEvents
.
Следующее демонстрирует подход принудительной полировки и работает как в Qt 4.8.5, так и в 5.2.0. Я тестировал его как на 64-битной сборке на OS X, так и на 32-битной сборке на Windows.
Обратите внимание, что ни l1
, ни l2
не отображаются, но оба они сообщают правильный размер. l3
, но при запросе перед его показанием он сообщает о неправильном размере.
[/g0]
#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();
}