Fix conflict between QMainWindow::restoreState() and QWidget::setStylesheet()
authorDebao Zhang <dbzhang800@gmail.com>
Sat, 24 Dec 2011 16:47:41 +0000 (00:47 +0800)
committerQt by Nokia <qt-info@nokia.com>
Thu, 23 Feb 2012 09:14:24 +0000 (10:14 +0100)
If QMainWindow::restoreState() then QWidget::setStylesheet() were called
before the QMainWindow is shown, the size of QDockWidget can not be
restored.

QWidget::setStylesheet() will generate QEvent::StyleChange event, which will
cause the function QDockAreaLayout::fitLayout() to be called before the layout
of MainWindow is activated. Although the state info has been stored in
a QMainWindowLayoutState variable by QMainWindow::restoreState(), but
QMainWindowLayout::setGeometry() still isn't called at present. So
QDockAreaLayout::fitLayout() will force the size of dockwidgets
and centralwidget to be calculated using the wrong geometry, which will
break the state restored by QMainWindow::restoreState().

This is a side effect of 692e9103ebb85b90e79377206d5d03b704d43d42.

Task-number: QTBUG-15080

Change-Id: I8cda6a529d178f7467a59b780db80df0a44d4769
Reviewed-by: Olivier Goffart <ogoffart@woboq.com>
src/widgets/widgets/qdockarealayout.cpp
tests/auto/widgets/widgets/qmainwindow/tst_qmainwindow.cpp

index df083cc..a07ab73 100644 (file)
@@ -3321,7 +3321,8 @@ void QDockAreaLayout::keepSize(QDockWidget *w)
 void QDockAreaLayout::styleChangedEvent()
 {
     sep = mainWindow->style()->pixelMetric(QStyle::PM_DockWidgetSeparatorExtent, 0, mainWindow);
-    fitLayout();
+    if (isValid())
+        fitLayout();
 }
 
 QT_END_NAMESPACE
index 1354035..0f07546 100644 (file)
@@ -101,6 +101,7 @@ private slots:
     void centralWidgetSize();
     void dockWidgetSize();
     void QTBUG2774_stylechange();
+    void QTBUG15080_restoreState();
     void toggleUnifiedTitleAndToolBarOnMac();
 };
 
@@ -1705,6 +1706,41 @@ void tst_QMainWindow::QTBUG2774_stylechange()
     }
 }
 
+void tst_QMainWindow::QTBUG15080_restoreState()
+{
+    QByteArray state;
+
+    //save state
+    {
+        QMainWindow mw1;
+        QDockWidget * dw1 = new  QDockWidget();
+        dw1->setObjectName("Left DockWidget");
+        mw1.addDockWidget(Qt::LeftDockWidgetArea, dw1);
+        mw1.setCentralWidget(new QTextEdit());
+        mw1.show();
+        QApplication::processEvents();
+        dw1->setFixedWidth(101);
+        QApplication::processEvents();
+
+        state = mw1.saveState();
+    }
+
+    //restore state
+
+    QMainWindow mw2;
+    QDockWidget * dw2 = new  QDockWidget();
+    dw2->setObjectName("Left DockWidget");
+    mw2.addDockWidget(Qt::LeftDockWidgetArea, dw2);
+    mw2.setCentralWidget(new QTextEdit());
+    mw2.restoreState(state);
+    //QTBUG15080 caused by setStyleSheet
+    mw2.setStyleSheet("color:red");
+    mw2.show();
+    QApplication::processEvents();
+
+    QCOMPARE(dw2->width(), 101);
+}
+
 void tst_QMainWindow::toggleUnifiedTitleAndToolBarOnMac()
 {
 #ifdef Q_OS_MAC