widgets freezing after minimise window

2019-07-28 15:03发布

I am using Qt5 Creator for an app, and in the main window's constructor I call this->setWindowState(Qt::WindowMaximized). The radio buttons and the check box work fine (i.e. easily toggle between checked and unchecked) when the window is initially maximized.

However, if I minimize it and maximize it then the radio buttons and the check box seem to freeze and don't freely toggle. But if I do restore down again things become fine.

I tried including a this->update in the slots of the radio buttons and check box but that didn't work. Any help would be appreciated.

3条回答
神经病院院长
2楼-- · 2019-07-28 15:50

When you use this->setWindowState(Qt::WindowMaximized); you are possibly overriding other states property of the windows. In particular, you are removing Qt::WindowActive. So use either of

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

But I wonder why you are playing around with window state. Can't you use show() in the constructor to make your window visible?

查看更多
对你真心纯属浪费
3楼-- · 2019-07-28 15:54

Try this->showMaximized() instead. The window state is available for doing tricky things that aren't possible through any other method, but if another method provides the desired functionality (QWidget::showMaximized() in this case) use that instead.

查看更多
疯言疯语
4楼-- · 2019-07-28 16:07

I encountered similar problem

Environment: Windows7 + Qt5.3 + Frameless QMainWindow

What I did: Minimized window with QMainWindow::showMinimized then shown it again.

What happened: Window stopped redrawing. It looked frozen.

I was debugging it and found out following:

After minimizing window attribute Qt::WA_Mapped was removed from QMainWindow (you can set breakpoint to setAttribute_internal in qwidget.cpp to check it). But this attribute was not set again after showing window. This caused that condition if (discardSyncRequest(tlw, tlwExtra)) in QWidgetBackingStore::sync was not met and it caused dirtyWidgets are not cleared. In other part of Qt updating system this caused that no other rendering was made.

Workaround I did: Subclassed QMainWindow and set attribute Qt::WA_Mapped manually when window was restored (handling changeEvent):

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

This works for me well. Right solution would be probably fixing the bug in Qt.

More about the problem

I found similar bug in Qt project history (marked as closed): QTBUG-34147

Also similar question in Qt forum: Minimizing frameless windows...

I found this comment beside the mentioned condition in 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.

It seems that there was a bug in Qt kernel (maybe mentioned QTBUG-34147) which was solved, but there remained some issues around it.

查看更多
登录 后发表回答