Ширина и высота QPushButton не соответствуют после применения qstylesheet [duplicate]

4
задан darkgaze 23 January 2014 в 20:32
поделиться

1 ответ

До сих пор я знаю три варианта:

  1. Польский виджет: вызывать widget->ensurePolished().
  2. Польский виджет через стиль: call qApp->style()->polish(widget).
  3. Отправьте события, отправленные в виджет: QCoreApplication::sendPostedEvents(widget, 0) в виджетах до его показа. С Qt 5 вам не нужен второй аргумент, так как теперь он имеет значение по умолчанию 0.

Другим решением вашей проблемы было бы просто не писать синхронный код вообще. Чтобы отобразить виджет верхнего уровня, когда он впервые показан:

  1. Установите фильтр фильтра в виджет.
  2. Когда событие show прибывает в виджет: Удалите событие фильтр от виджета. Доставьте все события окна до тех пор, пока их не осталось:
    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, но при запросе перед его показанием он сообщает о неправильном размере.

screenshot [/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();
}
5
ответ дан Kuba Ober 19 August 2018 в 03:48
поделиться
  • 1
    Спасибо за хороший ответ. Я не знал об этой функции. Но не работает для меня. Таблица стилей назначается перед созданием пользовательского интерфейса. Затем, создав скрытый виджет, я вывожу размер (он огромен). Затем я использую эту функцию. Размер остается прежним. Затем, после показа виджета, он становится меньше, как сказано в таблице стилей. Не работай для меня. – darkgaze 24 January 2014 в 11:34
  • 2
    На самом деле, как говорят документы: «QWidget вызывает эту функцию после того, как она была полностью построена, но до того, как она будет показана в первый раз». Таким образом, он называется DEFAULT. – darkgaze 24 January 2014 в 11:41
  • 3
    @darkgaze Вы неправильно понимаете, что говорят документы. Есть два раза, когда Qt может делать важные вещи с помощью виджета в этом случае: при построении и в то время, когда вы вызываете show(). Это однопоточный код, и вы не будете делать что-то для себя, когда вы вызываете size()! Таким образом, эту функцию можно вызывать только при вызове show(), но , прежде чем она станет видимой еще . show() делает кучу вещей, прежде чем виджет станет видимым. Документы действительно означают это: мы назовем это, когда вы назовете show(), но прежде чем электроны попадут в люминофор на экране :) – Kuba Ober 24 January 2014 в 14:28
  • 4
    @darkgaze Ну, я не могу выполнить вашу отладку для вас. Решение проблем при разработке программного обеспечения требует сужения его до наименьшего воспроизводимого случая. Вам будет легко скопировать проект и начать бросать нерелевантные вещи. Он должен работать, поэтому ваша проблема не здесь, это где-то еще в коде, который, вероятно, не имеет ничего общего с таблицами стилей и т. Д. – Kuba Ober 27 January 2014 в 11:36
  • 5
    @darkgaze Да. Ничто в документации не утверждает, что setStyleSheet имеет непосредственные последствия. Все, что гарантировано, заключается в том, что after , когда цикл события исчерпал очередь событий, эффекты установки стиля вступят в силу и будут видны. В Qt обновление отображения выполняется асинхронно из цикла событий. Поскольку вы не можете рисовать по требованию, не имеет никакого смысла, чтобы механизм стилизации делал вид, что вы можете. Визуальные и невизуальные эффекты стиля устанавливаются в одной и той же точке, асинхронно, поскольку соответствующие события сливаются из очереди. – Kuba Ober 29 January 2014 в 20:32
Другие вопросы по тегам:

Похожие вопросы: