виджеты зависают после сворачивания окна

Я использую Qt5 Creator для приложения, и в конструкторе главного окна я вызываю this->setWindowState(Qt::WindowMaximized). Радиокнопки и флажок работают нормально (т. е. легко переключаются между отмеченным и неотмеченным), когда окно изначально развернуто.

Однако, если я сверну его и разверну, то переключатели и флажок, кажется, зависают и не переключаются свободно. Но если я снова восстановлюсь, все станет хорошо.

Я попытался включить this->update в слоты переключателей и флажков, но это не сработало. Любая помощь будет оценена по достоинству.


person rotating_image    schedule 28.01.2013    source источник
comment
У вас есть только графический интерфейс без какого-либо другого кода?   -  person hank    schedule 28.01.2013
comment
код есть... но это происходит без кода, также я использую Qt5 Creator   -  person rotating_image    schedule 28.01.2013
comment
Создатель Qt5? Вы имеете в виду Qt5 и QtCreator??   -  person UmNyobe    schedule 28.01.2013


Ответы (3)


столкнулся с похожей проблемой

Среда: Windows7 + Qt5.3 + бескаркасный QMainWindow

Что я сделал: свернул окно с QMainWindow::showMinimized, а затем снова отобразил его.

Что произошло: окно перестало перерисовываться. Оно выглядело замороженным.

Я отлаживал его и обнаружил следующее:

После минимизации атрибут окна Qt::WA_Mapped был удален из QMainWindow (вы можете установить точку останова на setAttribute_internal в qwidget.cpp, чтобы проверить это). Но этот атрибут больше не устанавливался после показа окна. Это привело к тому, что условие if (discardSyncRequest(tlw, tlwExtra)) в QWidgetBackingStore::sync не было выполнено, и это привело к тому, что dirtyWidgets не были очищены. В другой части системы обновления Qt это привело к тому, что другой рендеринг не производился.

Мой обходной путь: подкласс QMainWindow и установка атрибута Qt::WA_Mapped вручную при восстановлении окна (обработка changeEvent):

void MainWindow::changeEvent(QEvent *event) {
  if(event->type() == QEvent::WindowStateChange) {
    if(!isMinimized()) {
      setAttribute(Qt::WA_Mapped);
    }
  }
}

Это работает для меня хорошо. Правильным решением, вероятно, будет исправление ошибки в Qt.

Подробнее о проблеме

Я нашел аналогичную ошибку в истории проекта Qt (помечен как закрытую): QTBUG-34147

Также аналогичный вопрос на форуме Qt: Минимизация безрамочных окон...

Я нашел этот комментарий рядом с упомянутым условием в QWidgetBackingStore::sync

// If the top-level is minimized, it's not visible on the screen so we can delay the
// update until it's shown again. In order to do that we must keep the dirty states.
// These will be cleared when we receive the first expose after showNormal().
// However, if the widget is not visible (isVisible() returns false), everything will
// be invalidated once the widget is shown again, so clear all dirty states.

Кажется, в ядре Qt была ошибка (может быть, упомянутая QTBUG-34147), которая была решена, но вокруг нее остались некоторые проблемы.

person Johnny Thunderman    schedule 04.02.2015
comment
Очаровательный! Я только что обнаружил этот пост, и он решил проблему, с которой я имел дело целую вечность, спасибо! - person cbuchart; 16.12.2016
comment
У меня была эта проблема при добавлении libvlc в виджет даже без сворачивания. Я хотел бы дать более одного голоса. - person Ali; 24.06.2019

Когда вы используете this->setWindowState(Qt::WindowMaximized);, вы, возможно, переопределяете другие свойства состояний окон. В частности, вы удаляете Qt::WindowActive. Так что используйте любой из

this->setWindowState(this->windowState() | Qt::WindowMaximized);
this->setWindowState(Qt::WindowMaximized | Qt::WindowActive);

Но мне интересно, почему вы играете с состоянием окна. Разве вы не можете использовать show() в конструкторе, чтобы сделать ваше окно видимым?

person UmNyobe    schedule 28.01.2013

Вместо этого попробуйте this->showMaximized(). Состояние окна доступно для выполнения сложных действий, которые невозможны с помощью любого другого метода, но если другой метод обеспечивает желаемую функциональность (QWidget::showMaximized() в данном случае), используйте его вместо этого.

person Tom Panning    schedule 29.01.2013