最小化窗口后小部件冻结 [英] widgets freezing after minimise window
问题描述
我正在为应用程序使用 Qt5 Creator,在主窗口的构造函数中,我调用了 this->setWindowState(Qt::WindowMaximized)
.当窗口最初最大化时,单选按钮和复选框工作正常(即轻松地在选中和未选中之间切换).
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.
我尝试在单选按钮和复选框的插槽中包含一个 this->update
,但没有奏效.任何帮助将不胜感激.
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.
推荐答案
我遇到了类似的问题
环境:Windows7 + Qt5.3 + Frameless QMainWindow
Environment: Windows7 + Qt5.3 + Frameless QMainWindow
我做了什么:使用 QMainWindow::showMinimized
最小化窗口然后再次显示它.
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:
从QMainWindow中删除最小化窗口属性Qt::WA_Mapped
后(您可以在qwidget.cpp
中将断点设置为setAttribute_internal
来检查它).但是显示窗口后没有再次设置此属性.这导致 QWidgetBackingStore::sync
中的条件 if (discardSyncRequest(tlw, tlwExtra))
不满足,并导致 dirtyWidgets
未被清除.在 Qt 更新系统的其他部分,这导致没有进行其他渲染.
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.
我所做的解决方法:子类化QMainWindow
并在窗口恢复时手动设置属性Qt::WA_Mapped
(处理changeEvent):
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);
}
}
}
这对我很有效.正确的解决方案可能是修复 Qt 中的错误.
This works for me well. Right solution would be probably fixing the bug in Qt.
有关问题的更多信息
我在 Qt 项目历史中发现了类似的错误(标记为已关闭):QTBUG-34147
I found similar bug in Qt project history (marked as closed): QTBUG-34147
Qt 论坛中也有类似问题:最小化无框窗口...
Also similar question in Qt forum: Minimizing frameless windows...
我在 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)已解决,但仍然存在一些问题.
It seems that there was a bug in Qt kernel (maybe mentioned QTBUG-34147) which was solved, but there remained some issues around it.
这篇关于最小化窗口后小部件冻结的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!