Results 1 to 15 of 15

Thread: Floating QDockWidget not re-docked by QMainWindow::restoreState

  1. #1
    Join Date
    Feb 2010
    Location
    Sydney, Australia
    Posts
    111
    Thanks
    18
    Thanked 5 Times in 5 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Floating QDockWidget not re-docked by QMainWindow::restoreState

    I'm having poblems with QMainWindow::saveState when QDockWidgets are nested or tabbed. If I float one of the nested/tabbed QDockWidgets and then call QMainWindow::restoreState, the floating QDockWidget state is not restored and it is left floating.

    So these are the steps:
    • Call QMainWindow::saveState on a main window with two docked QDockWidgets which are nested/tabbed
    • Float one of the nested/tabbed QDockWidgets, i.e. one is docked and the other is floating
    • Call QMainWindow::restoreState


    EXPECT: Both QDockWidgets to be nested/tabbed as they were when QMainWindow::saveState was called.
    ACTUAL: The nested/tabbed state of the QDockWidget is not restored - it's left floating.

    Has anyone noticed this behaviour before?

  2. #2
    Join Date
    Feb 2010
    Location
    Sydney, Australia
    Posts
    111
    Thanks
    18
    Thanked 5 Times in 5 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Floating QDockWidget not re-docked by QMainWindow::restoreState

    I put together some simple example code (using the Dock Widgets example) to demonstrate the problem and found that I was getting even less of the behaviour that I expected!

    This code creates a QMainWindow with two QDockWidgets. There is a File menu with "Save State" and Restore State" options which call saveState and restoreState respectively.

    If I save the state of the QMainWindow with the widgets both docked on the left side, then float both of them, then restore the state, both QDockWidgets are left floating. I would expect them to be restored to their docked state. Is this wrong?

    Qt Code:
    1. #include <QListWidget>
    2. #include <QMenu>
    3.  
    4. #include <QtGui/QMainWindow>
    5. #include "ui_testrestoredock.h"
    6.  
    7. class TestRestoreDock : public QMainWindow
    8. {
    9. Q_OBJECT
    10.  
    11. public:
    12. TestRestoreDock(QWidget *parent = 0, Qt::WFlags flags = 0);
    13. ~TestRestoreDock();
    14.  
    15. private:
    16. Ui::TestRestoreDockClass ui;
    17.  
    18. private slots:
    19. void SaveState();
    20. void RestoreState();
    21.  
    22. private:
    23. QListWidget* customerList;
    24. QListWidget* paragraphsList;
    25.  
    26. QMenu* fileMenu;
    27.  
    28. QAction* saveStateAction;
    29. QAction* restoreStateAction;
    30. };
    To copy to clipboard, switch view to plain text mode 

    Qt Code:
    1. #include <QDockWidget>
    2. #include <QSettings>
    3.  
    4. #include "testrestoredock.h"
    5.  
    6. TestRestoreDock::TestRestoreDock(QWidget *parent, Qt::WFlags flags)
    7. : QMainWindow(parent, flags)
    8. {
    9. ui.setupUi(this);
    10.  
    11. saveStateAction = new QAction(tr("&Save State"), this);
    12. connect(saveStateAction, SIGNAL(triggered()), this, SLOT(SaveState()));
    13.  
    14. restoreStateAction = new QAction(tr("&Restore State"), this);
    15. connect(restoreStateAction, SIGNAL(triggered()), this, SLOT(RestoreState()));
    16.  
    17. fileMenu = menuBar()->addMenu(tr("&File"));
    18. fileMenu->addAction(saveStateAction);
    19. fileMenu->addAction(restoreStateAction);
    20.  
    21. QDockWidget *dock = new QDockWidget(tr("Customers"), this);
    22. dock->setAllowedAreas(Qt::AllDockWidgetAreas);
    23. customerList = new QListWidget(dock);
    24. customerList->addItems(QStringList()
    25. << "John Doe, Harmony Enterprises, 12 Lakeside, Ambleton"
    26. << "Jane Doe, Memorabilia, 23 Watersedge, Beaton"
    27. << "Tammy Shea, Tiblanka, 38 Sea Views, Carlton"
    28. << "Tim Sheen, Caraba Gifts, 48 Ocean Way, Deal"
    29. << "Sol Harvey, Chicos Coffee, 53 New Springs, Eccleston"
    30. << "Sally Hobart, Tiroli Tea, 67 Long River, Fedula");
    31. dock->setWidget(customerList);
    32. addDockWidget(Qt::LeftDockWidgetArea, dock);
    33.  
    34. dock = new QDockWidget(tr("Paragraphs"), this);
    35. paragraphsList = new QListWidget(dock);
    36. paragraphsList->addItems(QStringList()
    37. << "Thank you for your payment which we have received today."
    38. << "Your order has been dispatched and should be with you "
    39. "within 28 days."
    40. << "We have dispatched those items that were in stock. The "
    41. "rest of your order will be dispatched once all the "
    42. "remaining items have arrived at our warehouse. No "
    43. "additional shipping charges will be made."
    44. << "You made a small overpayment (less than $5) which we "
    45. "will keep on account for you, or return at your request."
    46. << "You made a small underpayment (less than $1), but we have "
    47. "sent your order anyway. We'll add this underpayment to "
    48. "your next bill."
    49. << "Unfortunately you did not send enough money. Please remit "
    50. "an additional $. Your order will be dispatched as soon as "
    51. "the complete amount has been received."
    52. << "You made an overpayment (more than $5). Do you wish to "
    53. "buy more items, or should we return the excess to you?");
    54. dock->setWidget(paragraphsList);
    55. addDockWidget(Qt::LeftDockWidgetArea, dock);
    56. }
    57.  
    58. TestRestoreDock::~TestRestoreDock()
    59. {}
    60.  
    61. void TestRestoreDock::SaveState()
    62. {
    63. QSettings settings("Test", "Test Dock Problem");
    64. settings.setValue("MainWindow/State", saveState());
    65. settings.setValue("MainWindow/Geometry", saveGeometry());
    66. }
    67.  
    68. void TestRestoreDock::RestoreState()
    69. {
    70. QSettings settings("Test", "Test Dock Problem");
    71. restoreState(settings.value("MainWindow/State").toByteArray());
    72. restoreGeometry(settings.value("MainWindow/Geometry").toByteArray());
    73. }
    To copy to clipboard, switch view to plain text mode 

    Qt Code:
    1. #include "testrestoredock.h"
    2. #include <QtGui/QApplication>
    3.  
    4. int main(int argc, char *argv[])
    5. {
    6. QApplication a(argc, argv);
    7. TestRestoreDock w;
    8. w.show();
    9. return a.exec();
    10. }
    To copy to clipboard, switch view to plain text mode 

  3. #3
    Join Date
    Feb 2010
    Location
    Hyderabad, India
    Posts
    15
    Thanked 7 Times in 6 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Floating QDockWidget not re-docked by QMainWindow::restoreState

    For restoreState and saveState to work properly, we need to ensure that the objectname of each saved object is unique.

    Ensure that the objectname of both the dock widgets are different.

    eg. dock->setObjectName("Customers");

    and the second one can be

    dock->setObjectName("Paragraphs");

    Hope it helps.

  4. The following 2 users say thank you to mrvk for this useful post:

    carel (2nd March 2011), stefanadelbert (2nd March 2010)

  5. #4
    Join Date
    Feb 2010
    Location
    Sydney, Australia
    Posts
    111
    Thanks
    18
    Thanked 5 Times in 5 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Floating QDockWidget not re-docked by QMainWindow::restoreState

    Indeed, that makes a big difference. That now gets me to the point where I can actually demonstrate the problem that I'm having! I've made the relevant changes to the code and pasted it in below.

    So, back to my original problem:

    • Call QMainWindow::saveState on a main window with two docked QDockWidgets which are nested/tabbed
    • Float one of the nested/tabbed QDockWidgets, i.e. one will be docked and the other floating
    • Call QMainWindow::restoreState


    EXPECT: Both QDockWidgets to be nested/tabbed as they were when QMainWindow::saveState was called.
    ACTUAL: The nested/tabbed state of the QDockWidget is not restored - it's left floating.

    BTW: I've added the code to set the obecjetName for each dock below. I've also changed to setGeometry/restoreGeometry code - I'm on Win7 and the restore geometry doesn't work nicely for windows in the maximised state.

    Qt Code:
    1. #include <QListWidget>
    2. #include <QMenu>
    3.  
    4. #include <QtGui/QMainWindow>
    5. #include "ui_testrestoredock.h"
    6.  
    7. class TestRestoreDock : public QMainWindow
    8. {
    9. Q_OBJECT
    10.  
    11. public:
    12. TestRestoreDock(QWidget *parent = 0, Qt::WFlags flags = 0);
    13. ~TestRestoreDock();
    14.  
    15. private:
    16. Ui::TestRestoreDockClass ui;
    17.  
    18. private slots:
    19. void SaveState();
    20. void RestoreState();
    21.  
    22. private:
    23. QListWidget* customerList;
    24. QListWidget* paragraphsList;
    25.  
    26. QMenu* fileMenu;
    27.  
    28. QAction* saveStateAction;
    29. QAction* restoreStateAction;
    30. };
    To copy to clipboard, switch view to plain text mode 

    Qt Code:
    1. #include <QDockWidget>
    2. #include <QSettings>
    3.  
    4. #include "testrestoredock.h"
    5.  
    6. TestRestoreDock::TestRestoreDock(QWidget *parent, Qt::WFlags flags)
    7. : QMainWindow(parent, flags)
    8. {
    9. ui.setupUi(this);
    10.  
    11. saveStateAction = new QAction(tr("&Save State"), this);
    12. connect(saveStateAction, SIGNAL(triggered()), this, SLOT(SaveState()));
    13.  
    14. restoreStateAction = new QAction(tr("&Restore State"), this);
    15. connect(restoreStateAction, SIGNAL(triggered()), this, SLOT(RestoreState()));
    16.  
    17. fileMenu = menuBar()->addMenu(tr("&File"));
    18. fileMenu->addAction(saveStateAction);
    19. fileMenu->addAction(restoreStateAction);
    20.  
    21. QDockWidget *dock = new QDockWidget(tr("Customers"), this);
    22. dock->setObjectName(tr("Customers"));
    23. dock->setAllowedAreas(Qt::AllDockWidgetAreas);
    24. customerList = new QListWidget(dock);
    25. customerList->addItems(QStringList()
    26. << "John Doe, Harmony Enterprises, 12 Lakeside, Ambleton"
    27. << "Jane Doe, Memorabilia, 23 Watersedge, Beaton"
    28. << "Tammy Shea, Tiblanka, 38 Sea Views, Carlton"
    29. << "Tim Sheen, Caraba Gifts, 48 Ocean Way, Deal"
    30. << "Sol Harvey, Chicos Coffee, 53 New Springs, Eccleston"
    31. << "Sally Hobart, Tiroli Tea, 67 Long River, Fedula");
    32. dock->setWidget(customerList);
    33. addDockWidget(Qt::LeftDockWidgetArea, dock);
    34.  
    35. dock = new QDockWidget(tr("Paragraphs"), this);
    36. dock->setObjectName(tr("Paragraphs"));
    37. paragraphsList = new QListWidget(dock);
    38. paragraphsList->addItems(QStringList()
    39. << "Thank you for your payment which we have received today."
    40. << "Your order has been dispatched and should be with you "
    41. "within 28 days."
    42. << "We have dispatched those items that were in stock. The "
    43. "rest of your order will be dispatched once all the "
    44. "remaining items have arrived at our warehouse. No "
    45. "additional shipping charges will be made."
    46. << "You made a small overpayment (less than $5) which we "
    47. "will keep on account for you, or return at your request."
    48. << "You made a small underpayment (less than $1), but we have "
    49. "sent your order anyway. We'll add this underpayment to "
    50. "your next bill."
    51. << "Unfortunately you did not send enough money. Please remit "
    52. "an additional $. Your order will be dispatched as soon as "
    53. "the complete amount has been received."
    54. << "You made an overpayment (more than $5). Do you wish to "
    55. "buy more items, or should we return the excess to you?");
    56. dock->setWidget(paragraphsList);
    57. addDockWidget(Qt::LeftDockWidgetArea, dock);
    58. }
    59.  
    60. TestRestoreDock::~TestRestoreDock()
    61. {}
    62.  
    63. void TestRestoreDock::SaveState()
    64. {
    65. QSettings settings("Test", "Test Dock Problem");
    66. settings.setValue("MainWindow/State", saveState());
    67. settings.setValue("MainWindow/Geometry", geometry());
    68. }
    69.  
    70. void TestRestoreDock::RestoreState()
    71. {
    72. QSettings settings("Test", "Test Dock Problem");
    73. restoreState(settings.value("MainWindow/State").toByteArray());
    74. setGeometry(settings.value("MainWindow/Geometry").toRect());
    75. show();
    76. }
    To copy to clipboard, switch view to plain text mode 

    Qt Code:
    1. #include "testrestoredock.h"
    2. #include <QtGui/QApplication>
    3.  
    4. int main(int argc, char *argv[])
    5. {
    6. QApplication a(argc, argv);
    7. TestRestoreDock w;
    8. w.show();
    9. return a.exec();
    10. }
    To copy to clipboard, switch view to plain text mode 

  6. #5
    Join Date
    Feb 2008
    Posts
    491
    Thanks
    12
    Thanked 142 Times in 135 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11

    Default Re: Floating QDockWidget not re-docked by QMainWindow::restoreState

    I used the dockwidget example from Qt, added save settings & restore settings QActions to the File menu, copied your code for the slots, connected them and it worked like a charm.
    Are your slots being called? Stick the following statement at the end of your SaveState slot to see if there are any problems:
    Qt Code:
    1. qDebug()<< settings.status()
    To copy to clipboard, switch view to plain text mode 
    Other than the fact that I'm on Linux, I got nothing.

  7. The following user says thank you to norobro for this useful post:

    stefanadelbert (3rd March 2010)

  8. #6
    Join Date
    Feb 2010
    Location
    Sydney, Australia
    Posts
    111
    Thanks
    18
    Thanked 5 Times in 5 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Floating QDockWidget not re-docked by QMainWindow::restoreState

    I wish I could be doing this on Linux!

    I'm seeing some weirdness which I'm attributing to Win7 windows management:

    I've also changed to geometry()/restoreGeometry() - I'm on Win7 and the restore geometry doesn't work nicely for windows in the maximised state.
    I suppose that it's possible that this is a platform specific problem, but I would be surprised if it is. I reckon it's something that I'm doing wrong.

    I'll see if I can get something useful using qDebug and post back.

    Thanks for the response.
    Last edited by stefanadelbert; 3rd March 2010 at 06:13.

  9. #7
    Join Date
    Feb 2010
    Location
    Sydney, Australia
    Posts
    111
    Thanks
    18
    Thanked 5 Times in 5 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Floating QDockWidget not re-docked by QMainWindow::restoreState

    OK, I've done what you did. I took the dockwidgets example that comes with Qt 4.6.0 and I added the following:
    • State menu with Save and Restore actions
    • Save and Restore slots
    • Connections for Save and Restore actions to Save and Restore slots
    • setObjectName for both docks to ensure unique names


    I then do the following:
    • Stack one dock on top of the other so that they are tabbed
    • Save state
    • Float one of the docks
    • Restore state


    I would expect the floated dock to be restored to its tabbed state with with the other dock as it was when the state was saved. However it is left floating.

    I've attached the source files for the modified dockwidgets example.
    Attached Files Attached Files

  10. #8
    Join Date
    Feb 2008
    Posts
    491
    Thanks
    12
    Thanked 142 Times in 135 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11

    Default Re: Floating QDockWidget not re-docked by QMainWindow::restoreState

    As I've stated before on here, I need to work on my reading comprehension. I completely missed the fact that you said that you stacked the docks. Neither your code nor my code produce what I, too, consider the expected results.

    I'll keep pluggin'.

  11. #9
    Join Date
    Feb 2010
    Location
    Sydney, Australia
    Posts
    111
    Thanks
    18
    Thanked 5 Times in 5 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Floating QDockWidget not re-docked by QMainWindow::restoreState

    It feels like it might be time to call this a bug. Or maybe it's a feature, but it doesn't seem likely.

    What's the next step with this? Who do I report it to?

  12. #10
    Join Date
    Feb 2008
    Posts
    491
    Thanks
    12
    Thanked 142 Times in 135 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11

    Default Re: Floating QDockWidget not re-docked by QMainWindow::restoreState

    Looks like a bug to me too. But what do we know? Here is the info in the docs for the latest Qt version.

    One thing I did notice is (using your scenario):
    • Call QMainWindow::saveState on a main window with two docked QDockWidgets which are nested/tabbed
    • Float one of the nested/tabbed QDockWidgets, i.e. one will be docked and the other floating
    • Call QMainWindow::restoreState - doesn't work.

    If you then click the float button (or double click on the top bar) the floating widget will return to tabbed mode. So the app is retaining the information about the previous location of the floated tab. Apparently "saveState()" doesn't return that information to "QSettings.setValue".

    I've never filed a bug report either. I'd appreciate it if you'd post back about what happens.
    Last edited by norobro; 4th March 2010 at 01:53. Reason: Correct bad link

  13. #11
    Join Date
    Feb 2010
    Location
    Sydney, Australia
    Posts
    111
    Thanks
    18
    Thanked 5 Times in 5 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Floating QDockWidget not re-docked by QMainWindow::restoreState

    I get the same behaviour on my side when double clicking the QDockWidget titlebar.

    I'll go one step further though and say that it's not the previous state that is being "remembered" by the application. I think the application has the correct state stored for the QDockWidget, but it just isn't applying the "float" property correctly. I suspect this because I'm building an app that has a layout manager allowing the user to save an arbitrary number of layouts (or QMainWindow states) and then restore them from a list in the menu. When switching back to a layout that has tabbed QDockWidgets, the floating ones aren't restored (a la this bug), but double clicking their title bars does restore them correctly. So the app knows where they should be placed (i.e. QMainWindow state was actually restored correctly), but maybe just doesn't call QDockWidget::setFloating correctly.

  14. #12
    Join Date
    Feb 2010
    Location
    Sydney, Australia
    Posts
    111
    Thanks
    18
    Thanked 5 Times in 5 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Floating QDockWidget not re-docked by QMainWindow::restoreState

    Bug already logged (http://bugreports.qt.nokia.com/browse/QTBUG-7921). Would be great if some of you could vote for it to get fixed!

  15. #13
    Join Date
    Mar 2013
    Posts
    1
    Qt products
    Qt5
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Floating QDockWidget not re-docked by QMainWindow::restoreState

    Floating dock widget problem still exists in Qt 5.0.1 I found a workaround. After state restore do this:
    Qt Code:
    1. if(yourDockWidget->isFloating())
    2. {
    3. yourDockWidget->setFloating(true);
    4. }
    To copy to clipboard, switch view to plain text mode 
    And widget becomes dock able again.

  16. #14

    Default Re: Floating QDockWidget not re-docked by QMainWindow::restoreState

    Thank you for the useful post

  17. #15
    Join Date
    Sep 2013
    Posts
    9
    Thanks
    1
    Qt products

    Default Re: Floating QDockWidget not re-docked by QMainWindow::restoreState

    Not sure if it matter but in QT 5.5 and python 3.5 from my tests they all work fine when restoring/storing of QDockWidget.

Similar Threads

  1. QDockWidget saveState and restoreState
    By ^NyAw^ in forum Qt Programming
    Replies: 3
    Last Post: 28th January 2016, 10:56
  2. how to hide the title bar when a QDockWidget is docked?
    By oscar721 in forum Qt Programming
    Replies: 5
    Last Post: 23rd January 2014, 21:16
  3. QMainWindow ignores dynamically created, floating QDockWidget
    By stefanadelbert in forum Qt Programming
    Replies: 1
    Last Post: 2nd March 2010, 02:06
  4. QMainWindow : restorestate problems
    By fmariusd in forum Qt Programming
    Replies: 10
    Last Post: 30th October 2009, 09:05
  5. QMainWindow::restoreState
    By EnErGy[CSDX] in forum Qt Programming
    Replies: 3
    Last Post: 15th September 2008, 01:49

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.