Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Preserving/Restoring QDockWidget size
Qt 6.12 LTS is out! See what's new in the release blog

Preserving/Restoring QDockWidget size

Scheduled Pinned Locked Moved Unsolved General and Desktop
27 Posts 4 Posters 9.1k Views 3 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • PerdrixP Perdrix

    @Axel-Spoerl Oh! No wonder I was having trouble getting that to work. I thought that's what restoreDockWidget() did given the windowState of the main window!

    If I need to save the geometry of the dock widget (whether docked or not) how should I do that?

    I just checked the documentation again and it clearly says:

    QByteArray QWidget::saveGeometry() const

    Saves the current geometry and state for top-level widgets.
    To save the geometry when the window closes, you can implement a close event like this:
    void MyWidget::closeEvent(QCloseEvent *event)
    {
    QSettings settings("MyCompany", "MyApp");
    settings.setValue("geometry", saveGeometry());
    QWidget::closeEvent(event);
    }

    See the Window Geometry documentation for an overview of geometry issues with windows.
    Use QMainWindow::saveState() to save the geometry and the state of toolbars and dock widgets.

    Axel SpoerlA Offline
    Axel SpoerlA Offline
    Axel Spoerl
    Moderators
    wrote on last edited by
    #6

    @Perdrix
    restoreDockWidget() is a mixed bag IMHO. It basically restores what the main window needs to know about its dock widgets. Their geometry doesn't fall into that category.

    The code snippet you mention is meant to be included in a class inheriting from QWidget. As far as I know your app, you are using generic dock widgets.

    So the question is, is the dock widgets' geometry the right one at the moment, where you call QMainWindow::saveState()? If so, just loop over the dock widgets and do as laid out in the code snippet. If not (because they might have been closed manually at an earlier time), you would have to install an event filter on each dock widget and intercept the event that hides, closes or resizes a dock widget. If you don't wanna write into the settings file from an event, you could store the returned QByteArray in a QHashand use that to restore geometries at run time. When saving settings, you could translate the hashed pointer into an object name, store the hash in the settings and rebuild it on next application startup.

    Software Engineer
    The Qt Company, Oslo

    PerdrixP 1 Reply Last reply
    2
    • Axel SpoerlA Axel Spoerl

      @Perdrix
      restoreDockWidget() is a mixed bag IMHO. It basically restores what the main window needs to know about its dock widgets. Their geometry doesn't fall into that category.

      The code snippet you mention is meant to be included in a class inheriting from QWidget. As far as I know your app, you are using generic dock widgets.

      So the question is, is the dock widgets' geometry the right one at the moment, where you call QMainWindow::saveState()? If so, just loop over the dock widgets and do as laid out in the code snippet. If not (because they might have been closed manually at an earlier time), you would have to install an event filter on each dock widget and intercept the event that hides, closes or resizes a dock widget. If you don't wanna write into the settings file from an event, you could store the returned QByteArray in a QHashand use that to restore geometries at run time. When saving settings, you could translate the hashed pointer into an object name, store the hash in the settings and rebuild it on next application startup.

      PerdrixP Offline
      PerdrixP Offline
      Perdrix
      wrote on last edited by
      #7

      @Axel-Spoerl But that's my complaint - it doesn't restore the size of the docked dock widget to what it was when the application closed.

      So I have to ask again how can this be made to work? I'm prepared to add extra code enquire on the geometry of the dock widget and restore it after open, but only if that has some chance to work.

      PerdrixP 1 Reply Last reply
      0
      • PerdrixP Perdrix

        @Axel-Spoerl But that's my complaint - it doesn't restore the size of the docked dock widget to what it was when the application closed.

        So I have to ask again how can this be made to work? I'm prepared to add extra code enquire on the geometry of the dock widget and restore it after open, but only if that has some chance to work.

        PerdrixP Offline
        PerdrixP Offline
        Perdrix
        wrote on last edited by
        #8

        @Axel-Spoerl I tried this:

        	//
        	// Now save the geometry of the Picture List dock widget
        	//
        	settings.beginGroup("PictureList");
        	geometry = pictureList->saveGeometry();
        #ifndef NDEBUG	
        	ZTRACE_RUNTIME("Hex dump of Picture List geometry:");
        	ZTrace::dumpHex(geometry.constData(), geometry.length());
        #endif 
        	settings.endGroup();
        
        	if (windowState.length())
        	{
        		restoreState(windowState);
        		restoreDockWidget(pictureList);
        
        		settings.beginGroup("PictureList");
        		geometry = settings.value("geometry", QByteArray()).toByteArray();
        		settings.endGroup();
        
        		if (geometry.length())
        		{
        			pictureList->restoreGeometry(geometry);
        		}
        	}
        
        

        But even though I saved the dock widget's geometry explicitly restoring it didn't change the size to match what it was when the application closed.

        :(
        David

        Axel SpoerlA 1 Reply Last reply
        0
        • PerdrixP Perdrix

          @Axel-Spoerl I tried this:

          	//
          	// Now save the geometry of the Picture List dock widget
          	//
          	settings.beginGroup("PictureList");
          	geometry = pictureList->saveGeometry();
          #ifndef NDEBUG	
          	ZTRACE_RUNTIME("Hex dump of Picture List geometry:");
          	ZTrace::dumpHex(geometry.constData(), geometry.length());
          #endif 
          	settings.endGroup();
          
          	if (windowState.length())
          	{
          		restoreState(windowState);
          		restoreDockWidget(pictureList);
          
          		settings.beginGroup("PictureList");
          		geometry = settings.value("geometry", QByteArray()).toByteArray();
          		settings.endGroup();
          
          		if (geometry.length())
          		{
          			pictureList->restoreGeometry(geometry);
          		}
          	}
          
          

          But even though I saved the dock widget's geometry explicitly restoring it didn't change the size to match what it was when the application closed.

          :(
          David

          Axel SpoerlA Offline
          Axel SpoerlA Offline
          Axel Spoerl
          Moderators
          wrote on last edited by
          #9

          @Perdrix
          Hi David,
          I shall have a look and revert back to you asap.
          cheers
          Axel

          Software Engineer
          The Qt Company, Oslo

          PerdrixP 1 Reply Last reply
          0
          • Axel SpoerlA Axel Spoerl

            @Perdrix
            Hi David,
            I shall have a look and revert back to you asap.
            cheers
            Axel

            PerdrixP Offline
            PerdrixP Offline
            Perdrix
            wrote on last edited by
            #10

            @Axel-Spoerl Thank you Axel.

            FYI I also tried:

            	//
            	// Now save the height of the Picture List dock widget
            	//
            	settings.beginGroup("PictureList");
            	auto height = pictureList->height();
            	settings.setValue("Height", height);
            #ifndef NDEBUG	
            	ZTRACE_RUNTIME("Height of Picture List was %d pixels", height);
            #endif 
            	settings.endGroup();
            

            and

            if (windowState.length())
            	{
            		restoreState(windowState);
            		restoreDockWidget(pictureList);
            
            		settings.beginGroup("PictureList");
            		auto height = settings.value("Height", 0).toInt();
            		settings.endGroup();
            
            		if (height)
            		{
            			resizeDocks({ pictureList }, { height }, Qt::Vertical);
            		}
            	}
            

            which also didn't work :(

            PerdrixP 1 Reply Last reply
            0
            • PerdrixP Perdrix

              @Axel-Spoerl Thank you Axel.

              FYI I also tried:

              	//
              	// Now save the height of the Picture List dock widget
              	//
              	settings.beginGroup("PictureList");
              	auto height = pictureList->height();
              	settings.setValue("Height", height);
              #ifndef NDEBUG	
              	ZTRACE_RUNTIME("Height of Picture List was %d pixels", height);
              #endif 
              	settings.endGroup();
              

              and

              if (windowState.length())
              	{
              		restoreState(windowState);
              		restoreDockWidget(pictureList);
              
              		settings.beginGroup("PictureList");
              		auto height = settings.value("Height", 0).toInt();
              		settings.endGroup();
              
              		if (height)
              		{
              			resizeDocks({ pictureList }, { height }, Qt::Vertical);
              		}
              	}
              

              which also didn't work :(

              PerdrixP Offline
              PerdrixP Offline
              Perdrix
              wrote on last edited by Perdrix
              #11

              @Axel-Spoerl Odd

              This code looks as if it is saving the sizes of the dock widgets ...

              void QDockAreaLayout::saveState(QDataStream &stream) const
              {
                  stream << (uchar) DockWidgetStateMarker;
                  int cnt = 0;
                  for (int i = 0; i < QInternal::DockCount; ++i) {
                      if (!docks[i].item_list.isEmpty())
                          ++cnt;
                  }
                  stream << cnt;
                  for (int i = 0; i < QInternal::DockCount; ++i) {
                      if (docks[i].item_list.isEmpty())
                          continue;
                      stream << i << docks[i].rect.size();
                      docks[i].saveState(stream);
                  }
              
                  stream << centralWidgetRect.size();
              
                  for (int i = 0; i < 4; ++i)
                      stream << static_cast<int>(corners[i]);
              }
              
              Axel SpoerlA 1 Reply Last reply
              0
              • PerdrixP Perdrix

                @Axel-Spoerl Odd

                This code looks as if it is saving the sizes of the dock widgets ...

                void QDockAreaLayout::saveState(QDataStream &stream) const
                {
                    stream << (uchar) DockWidgetStateMarker;
                    int cnt = 0;
                    for (int i = 0; i < QInternal::DockCount; ++i) {
                        if (!docks[i].item_list.isEmpty())
                            ++cnt;
                    }
                    stream << cnt;
                    for (int i = 0; i < QInternal::DockCount; ++i) {
                        if (docks[i].item_list.isEmpty())
                            continue;
                        stream << i << docks[i].rect.size();
                        docks[i].saveState(stream);
                    }
                
                    stream << centralWidgetRect.size();
                
                    for (int i = 0; i < 4; ++i)
                        stream << static_cast<int>(corners[i]);
                }
                
                Axel SpoerlA Offline
                Axel SpoerlA Offline
                Axel Spoerl
                Moderators
                wrote on last edited by
                #12

                @Perdrix
                Hi David,
                making sure we're on the same page.
                The workflow is:

                • application starts with a docked dock widget.
                • dock widget is unplugged programmatically by setFloating(true).
                • dock widget is resized, either manually or programmatically.
                • application is closed, state and geometry are saved.
                • application is started again, state and geometry are restored.
                • problem: dock widget bounces back to default geometry.

                Cheers
                Axel

                Software Engineer
                The Qt Company, Oslo

                Axel SpoerlA 1 Reply Last reply
                0
                • Axel SpoerlA Axel Spoerl

                  @Perdrix
                  Hi David,
                  making sure we're on the same page.
                  The workflow is:

                  • application starts with a docked dock widget.
                  • dock widget is unplugged programmatically by setFloating(true).
                  • dock widget is resized, either manually or programmatically.
                  • application is closed, state and geometry are saved.
                  • application is started again, state and geometry are restored.
                  • problem: dock widget bounces back to default geometry.

                  Cheers
                  Axel

                  Axel SpoerlA Offline
                  Axel SpoerlA Offline
                  Axel Spoerl
                  Moderators
                  wrote on last edited by
                  #13

                  @Axel-Spoerl
                  Ok, I must apologize, you have found a bug, a missing feature, whatever you wanna call it.

                  If I understand you correctly, the issue is the undocked geometry.
                  It is held by QDockWidgetPrivate::undockedGeometryand unfortunately not saved anywhere.
                  I'll look into a fix. It is, however, not an easy patch. QWidget::saveGeometry() is not virtual, so the straight forward approach of overriding it in QDockWidgetwon't fly. The undocked geometry is held in the private header, without public accessors, so a stright forward workaround won't fly either.

                  • The fix will probably be a version bump of QDockAreaLayout::saveState(). But that'll kick be available in the next release of 6.5 at the earliest.
                  • The workaround is a bit of plumbing. When the application closes, all dock widgets need to be made floating, after the main window state was saved. Then their undocked geometry becomes available in geometry()and needs to be saved as well. I'll be back with a suggestion.

                  Software Engineer
                  The Qt Company, Oslo

                  PerdrixP 1 Reply Last reply
                  0
                  • Axel SpoerlA Axel Spoerl

                    @Axel-Spoerl
                    Ok, I must apologize, you have found a bug, a missing feature, whatever you wanna call it.

                    If I understand you correctly, the issue is the undocked geometry.
                    It is held by QDockWidgetPrivate::undockedGeometryand unfortunately not saved anywhere.
                    I'll look into a fix. It is, however, not an easy patch. QWidget::saveGeometry() is not virtual, so the straight forward approach of overriding it in QDockWidgetwon't fly. The undocked geometry is held in the private header, without public accessors, so a stright forward workaround won't fly either.

                    • The fix will probably be a version bump of QDockAreaLayout::saveState(). But that'll kick be available in the next release of 6.5 at the earliest.
                    • The workaround is a bit of plumbing. When the application closes, all dock widgets need to be made floating, after the main window state was saved. Then their undocked geometry becomes available in geometry()and needs to be saved as well. I'll be back with a suggestion.
                    PerdrixP Offline
                    PerdrixP Offline
                    Perdrix
                    wrote on last edited by
                    #14

                    @Axel-Spoerl Nope this is the DOCKED size.

                    So work flow is:

                    • Open application
                      6ee9c494-fce0-4947-a69c-92c56fba517d-image.png
                    • Adjust vertical height of lower dock widget
                      08dc0861-5191-4bf2-b7ec-5994599c8868-image.png
                    • Close application
                    • Reopen application. Size lower dock widget is same as if lower dock widget hadn't been resized.
                      e7553192-017e-4b40-87c9-53f6c62f13fc-image.png
                    Axel SpoerlA 1 Reply Last reply
                    0
                    • PerdrixP Perdrix

                      @Axel-Spoerl Nope this is the DOCKED size.

                      So work flow is:

                      • Open application
                        6ee9c494-fce0-4947-a69c-92c56fba517d-image.png
                      • Adjust vertical height of lower dock widget
                        08dc0861-5191-4bf2-b7ec-5994599c8868-image.png
                      • Close application
                      • Reopen application. Size lower dock widget is same as if lower dock widget hadn't been resized.
                        e7553192-017e-4b40-87c9-53f6c62f13fc-image.png
                      Axel SpoerlA Offline
                      Axel SpoerlA Offline
                      Axel Spoerl
                      Moderators
                      wrote on last edited by
                      #15

                      @Perdrix
                      Hi David,

                      so we're not talking about undocked dock widgets' geometry?
                      In that case, you're not affected by the bug, that the undocked geometry is not saved.

                      I have the feeling that something is wrong in the application code.

                      Just tried to demonstrate the problem in a simple reproducer. But there is no problem, it works perfectly

                      mainwindow.h

                      #ifndef MAINWINDOW_H
                      #define MAINWINDOW_H
                      
                      #include <QMainWindow>
                      #include <QDockWidget>
                      
                      QT_BEGIN_NAMESPACE
                      namespace Ui { class MainWindow; }
                      QT_END_NAMESPACE
                      
                      class MainWindow : public QMainWindow
                      {
                          Q_OBJECT
                      
                      public:
                          MainWindow(QWidget *parent = nullptr);
                          ~MainWindow();
                      
                      private:
                          void readSettings();
                          void writeSettings() const;
                          Ui::MainWindow *ui;
                      };
                      #endif // MAINWINDOW_H
                      

                      mainwindow.cpp

                      #include "mainwindow.h"
                      #include "./ui_mainwindow.h"
                      #include <QSettings>
                      
                      MainWindow::MainWindow(QWidget *parent)
                          : QMainWindow(parent)
                          , ui(new Ui::MainWindow)
                      {
                          ui->setupUi(this);
                      
                          for (int i = 0; i < 4; ++i) {
                              const QString name = "DockWidget-" + QString::number(i);
                              QDockWidget *dw = new QDockWidget(name, this);
                              dw->setObjectName(name);
                              addDockWidget(static_cast<Qt::DockWidgetArea>(i << 2), dw);
                          }
                          readSettings();
                      }
                      
                      MainWindow::~MainWindow()
                      {
                          writeSettings();
                          delete ui;
                      }
                      
                      void MainWindow::readSettings()
                      {
                          const QSettings s("Test", "DockWidgetGeometry");
                          if (!s.contains("MainWindowState"))
                              return;
                      
                          const QByteArray array = s.value("MainWindowState").toByteArray();
                          restoreState(array);
                      }
                      
                      void MainWindow::writeSettings() const
                      {
                          QSettings s("Test", "DockWidgetGeometry");
                          s.setValue("MainWindowState", saveState());
                      }
                      

                      main.cpp

                      #include "mainwindow.h"
                      
                      #include <QApplication>
                      
                      int main(int argc, char *argv[])
                      {
                          QApplication a(argc, argv);
                          MainWindow w;
                          w.show();
                          return a.exec();
                      }
                      

                      I start the application, move all dock widgets to the left dock, join two as floating tabs, change their sizes. Whatever I do is exactly recovered after closing and re-starting the app.

                      22674419-3425-4bb8-adbb-9b35f1c08c49-image.png

                      So I suspect that your application touches the docked dockwidgets' size after the state is restored.

                      Cheers
                      Axel

                      Software Engineer
                      The Qt Company, Oslo

                      PerdrixP 1 Reply Last reply
                      0
                      • Axel SpoerlA Axel Spoerl

                        @Perdrix
                        Hi David,

                        so we're not talking about undocked dock widgets' geometry?
                        In that case, you're not affected by the bug, that the undocked geometry is not saved.

                        I have the feeling that something is wrong in the application code.

                        Just tried to demonstrate the problem in a simple reproducer. But there is no problem, it works perfectly

                        mainwindow.h

                        #ifndef MAINWINDOW_H
                        #define MAINWINDOW_H
                        
                        #include <QMainWindow>
                        #include <QDockWidget>
                        
                        QT_BEGIN_NAMESPACE
                        namespace Ui { class MainWindow; }
                        QT_END_NAMESPACE
                        
                        class MainWindow : public QMainWindow
                        {
                            Q_OBJECT
                        
                        public:
                            MainWindow(QWidget *parent = nullptr);
                            ~MainWindow();
                        
                        private:
                            void readSettings();
                            void writeSettings() const;
                            Ui::MainWindow *ui;
                        };
                        #endif // MAINWINDOW_H
                        

                        mainwindow.cpp

                        #include "mainwindow.h"
                        #include "./ui_mainwindow.h"
                        #include <QSettings>
                        
                        MainWindow::MainWindow(QWidget *parent)
                            : QMainWindow(parent)
                            , ui(new Ui::MainWindow)
                        {
                            ui->setupUi(this);
                        
                            for (int i = 0; i < 4; ++i) {
                                const QString name = "DockWidget-" + QString::number(i);
                                QDockWidget *dw = new QDockWidget(name, this);
                                dw->setObjectName(name);
                                addDockWidget(static_cast<Qt::DockWidgetArea>(i << 2), dw);
                            }
                            readSettings();
                        }
                        
                        MainWindow::~MainWindow()
                        {
                            writeSettings();
                            delete ui;
                        }
                        
                        void MainWindow::readSettings()
                        {
                            const QSettings s("Test", "DockWidgetGeometry");
                            if (!s.contains("MainWindowState"))
                                return;
                        
                            const QByteArray array = s.value("MainWindowState").toByteArray();
                            restoreState(array);
                        }
                        
                        void MainWindow::writeSettings() const
                        {
                            QSettings s("Test", "DockWidgetGeometry");
                            s.setValue("MainWindowState", saveState());
                        }
                        

                        main.cpp

                        #include "mainwindow.h"
                        
                        #include <QApplication>
                        
                        int main(int argc, char *argv[])
                        {
                            QApplication a(argc, argv);
                            MainWindow w;
                            w.show();
                            return a.exec();
                        }
                        

                        I start the application, move all dock widgets to the left dock, join two as floating tabs, change their sizes. Whatever I do is exactly recovered after closing and re-starting the app.

                        22674419-3425-4bb8-adbb-9b35f1c08c49-image.png

                        So I suspect that your application touches the docked dockwidgets' size after the state is restored.

                        Cheers
                        Axel

                        PerdrixP Offline
                        PerdrixP Offline
                        Perdrix
                        wrote on last edited by
                        #16

                        @Axel-Spoerl The only code I have the messes with its size is in SetupUi, and that is done before the code that tries to restore its size.

                            void setupUi(QDockWidget *PictureList)
                            {
                                if (PictureList->objectName().isEmpty())
                                    PictureList->setObjectName("PictureList");
                                PictureList->resize(618, 156);
                                QSizePolicy sizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
                                sizePolicy.setHorizontalStretch(0);
                                sizePolicy.setVerticalStretch(0);
                                sizePolicy.setHeightForWidth(PictureList->sizePolicy().hasHeightForWidth());
                                PictureList->setSizePolicy(sizePolicy);
                                PictureList->setMinimumSize(QSize(618, 156));
                                PictureList->setStyleSheet(QString::fromUtf8(""));
                                PictureList->setFeatures(QDockWidget::DockWidgetFloatable|QDockWidget::DockWidgetMovable);
                                PictureList->setAllowedAreas(Qt::BottomDockWidgetArea|Qt::RightDockWidgetArea);
                                PictureList->setWindowTitle(QString::fromUtf8("Light Frames: 0      -      Dark Frames: 0      -      Flat Frames: 0      -   Dark Flat Frames: 0   -      Offset/Bias Frames: 0"));
                                dockWidgetContents = new QWidget();
                                dockWidgetContents->setObjectName("dockWidgetContents");
                                QSizePolicy sizePolicy1(QSizePolicy::Expanding, QSizePolicy::Expanding);
                                sizePolicy1.setHorizontalStretch(0);
                                sizePolicy1.setVerticalStretch(0);
                                sizePolicy1.setHeightForWidth(dockWidgetContents->sizePolicy().hasHeightForWidth());
                                dockWidgetContents->setSizePolicy(sizePolicy1);
                                verticalLayout = new QVBoxLayout(dockWidgetContents);
                                verticalLayout->setObjectName("verticalLayout");
                                tableView = new QTableView(dockWidgetContents);
                                tableView->setObjectName("tableView");
                        
                                verticalLayout->addWidget(tableView);
                        
                                tabBar = new QTabBar(dockWidgetContents);
                                tabBar->setObjectName("tabBar");
                                QSizePolicy sizePolicy2(QSizePolicy::Expanding, QSizePolicy::Minimum);
                                sizePolicy2.setHorizontalStretch(0);
                                sizePolicy2.setVerticalStretch(0);
                                sizePolicy2.setHeightForWidth(tabBar->sizePolicy().hasHeightForWidth());
                                tabBar->setSizePolicy(sizePolicy2);
                                tabBar->setMinimumSize(QSize(0, 28));
                                tabBar->setMaximumSize(QSize(16777215, 28));
                        
                                verticalLayout->addWidget(tabBar);
                        
                                PictureList->setWidget(dockWidgetContents);
                        
                                retranslateUi(PictureList);
                        
                                QMetaObject::connectSlotsByName(PictureList);
                            } // setupUi
                        

                        What's more is that if the QSettings values for geometry and windowState aren't present, the only code that I have to adjust the size is at the start of the code I posted earlier where it does

                        resizeDocks({ pictureList }, { 150 }, Qt::Vertical);
                        

                        and that appears to set the size just fine for the FIRST time open:

                        8ecf38f6-9e36-437b-a5b3-b25cac6c19fb-image.png

                        Subsequent opens always open to a large size that appears related to the main window size.

                        PerdrixP 1 Reply Last reply
                        0
                        • PerdrixP Perdrix

                          @Axel-Spoerl The only code I have the messes with its size is in SetupUi, and that is done before the code that tries to restore its size.

                              void setupUi(QDockWidget *PictureList)
                              {
                                  if (PictureList->objectName().isEmpty())
                                      PictureList->setObjectName("PictureList");
                                  PictureList->resize(618, 156);
                                  QSizePolicy sizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
                                  sizePolicy.setHorizontalStretch(0);
                                  sizePolicy.setVerticalStretch(0);
                                  sizePolicy.setHeightForWidth(PictureList->sizePolicy().hasHeightForWidth());
                                  PictureList->setSizePolicy(sizePolicy);
                                  PictureList->setMinimumSize(QSize(618, 156));
                                  PictureList->setStyleSheet(QString::fromUtf8(""));
                                  PictureList->setFeatures(QDockWidget::DockWidgetFloatable|QDockWidget::DockWidgetMovable);
                                  PictureList->setAllowedAreas(Qt::BottomDockWidgetArea|Qt::RightDockWidgetArea);
                                  PictureList->setWindowTitle(QString::fromUtf8("Light Frames: 0      -      Dark Frames: 0      -      Flat Frames: 0      -   Dark Flat Frames: 0   -      Offset/Bias Frames: 0"));
                                  dockWidgetContents = new QWidget();
                                  dockWidgetContents->setObjectName("dockWidgetContents");
                                  QSizePolicy sizePolicy1(QSizePolicy::Expanding, QSizePolicy::Expanding);
                                  sizePolicy1.setHorizontalStretch(0);
                                  sizePolicy1.setVerticalStretch(0);
                                  sizePolicy1.setHeightForWidth(dockWidgetContents->sizePolicy().hasHeightForWidth());
                                  dockWidgetContents->setSizePolicy(sizePolicy1);
                                  verticalLayout = new QVBoxLayout(dockWidgetContents);
                                  verticalLayout->setObjectName("verticalLayout");
                                  tableView = new QTableView(dockWidgetContents);
                                  tableView->setObjectName("tableView");
                          
                                  verticalLayout->addWidget(tableView);
                          
                                  tabBar = new QTabBar(dockWidgetContents);
                                  tabBar->setObjectName("tabBar");
                                  QSizePolicy sizePolicy2(QSizePolicy::Expanding, QSizePolicy::Minimum);
                                  sizePolicy2.setHorizontalStretch(0);
                                  sizePolicy2.setVerticalStretch(0);
                                  sizePolicy2.setHeightForWidth(tabBar->sizePolicy().hasHeightForWidth());
                                  tabBar->setSizePolicy(sizePolicy2);
                                  tabBar->setMinimumSize(QSize(0, 28));
                                  tabBar->setMaximumSize(QSize(16777215, 28));
                          
                                  verticalLayout->addWidget(tabBar);
                          
                                  PictureList->setWidget(dockWidgetContents);
                          
                                  retranslateUi(PictureList);
                          
                                  QMetaObject::connectSlotsByName(PictureList);
                              } // setupUi
                          

                          What's more is that if the QSettings values for geometry and windowState aren't present, the only code that I have to adjust the size is at the start of the code I posted earlier where it does

                          resizeDocks({ pictureList }, { 150 }, Qt::Vertical);
                          

                          and that appears to set the size just fine for the FIRST time open:

                          8ecf38f6-9e36-437b-a5b3-b25cac6c19fb-image.png

                          Subsequent opens always open to a large size that appears related to the main window size.

                          PerdrixP Offline
                          PerdrixP Offline
                          Perdrix
                          wrote on last edited by Perdrix
                          #17

                          @Perdrix Maybe I am trying to restore the geometry and window state at the wrong time? I am doing it in code invoked from showEvent()

                          void DeepSkyStacker::showEvent(QShowEvent* event)
                          {
                          	if (!event->spontaneous())
                          	{
                          		if (!initialised)
                          		{
                          			initialised = true;
                          			onInitialise();
                          		}
                          	}
                          	// Invoke base class showEvent()
                          	return Inherited::showEvent(event);
                          }
                          
                          Axel SpoerlA 1 Reply Last reply
                          0
                          • PerdrixP Perdrix

                            @Perdrix Maybe I am trying to restore the geometry and window state at the wrong time? I am doing it in code invoked from showEvent()

                            void DeepSkyStacker::showEvent(QShowEvent* event)
                            {
                            	if (!event->spontaneous())
                            	{
                            		if (!initialised)
                            		{
                            			initialised = true;
                            			onInitialise();
                            		}
                            	}
                            	// Invoke base class showEvent()
                            	return Inherited::showEvent(event);
                            }
                            
                            Axel SpoerlA Offline
                            Axel SpoerlA Offline
                            Axel Spoerl
                            Moderators
                            wrote on last edited by
                            #18

                            @Perdrix
                            Hi David,
                            If I tweak the reproducer and override QMainWindow::showEvent(QShowEvent *event), it works as well.

                            I don't know about the DeepSkyStacker class, where it inherits from and when its first non-spontaneuous show event is consumed. My gut feeling tells me to put some pocket money on the show event. It's an unusual place to call QMainWindow::restoreState(): Are the dock widgets are already constructed and added to the main window, when the show event is consumed? The dock widget part of the call will be a no-op, if the dock widgets aren't in place or don't have an object name.

                            I'd happily look into the code of DSS, because it's a great piece of software (have I ever mentioned that? Apologies if I haven't). It's a VS project, however, and I only use Qt Creator.

                            I'd try the following:

                            • play with the reproducer in my earlier post, to see if the issue can be isolated
                            • play with the dock widgets: Tab them, undock them, close and restart the app => see if anything is restored at all.
                            • move the the code calling QMainWindow::restoreState() right after the construction of the dock widgets.

                            Cheers
                            Axel

                            Software Engineer
                            The Qt Company, Oslo

                            PerdrixP 1 Reply Last reply
                            0
                            • Axel SpoerlA Axel Spoerl

                              @Perdrix
                              Hi David,
                              If I tweak the reproducer and override QMainWindow::showEvent(QShowEvent *event), it works as well.

                              I don't know about the DeepSkyStacker class, where it inherits from and when its first non-spontaneuous show event is consumed. My gut feeling tells me to put some pocket money on the show event. It's an unusual place to call QMainWindow::restoreState(): Are the dock widgets are already constructed and added to the main window, when the show event is consumed? The dock widget part of the call will be a no-op, if the dock widgets aren't in place or don't have an object name.

                              I'd happily look into the code of DSS, because it's a great piece of software (have I ever mentioned that? Apologies if I haven't). It's a VS project, however, and I only use Qt Creator.

                              I'd try the following:

                              • play with the reproducer in my earlier post, to see if the issue can be isolated
                              • play with the dock widgets: Tab them, undock them, close and restart the app => see if anything is restored at all.
                              • move the the code calling QMainWindow::restoreState() right after the construction of the dock widgets.

                              Cheers
                              Axel

                              PerdrixP Offline
                              PerdrixP Offline
                              Perdrix
                              wrote on last edited by Perdrix
                              #19

                              @Axel-Spoerl The widgets are also constructed in onInitialise().

                              You suggest that showEvent() is an unusual place from which to call restoreState(). Where would you normally put it? At the end of the ctor as you did in you small example?

                              Axel SpoerlA 1 Reply Last reply
                              0
                              • PerdrixP Perdrix

                                @Axel-Spoerl The widgets are also constructed in onInitialise().

                                You suggest that showEvent() is an unusual place from which to call restoreState(). Where would you normally put it? At the end of the ctor as you did in you small example?

                                Axel SpoerlA Offline
                                Axel SpoerlA Offline
                                Axel Spoerl
                                Moderators
                                wrote on last edited by
                                #20

                                @Perdrix said in Preserving/Restoring QDockWidget size:

                                At the end of the ctor as you did in you small example?

                                The c'tor is definitely a good spot, but it has to be called after the dock widgets are fully created.

                                Software Engineer
                                The Qt Company, Oslo

                                PerdrixP 1 Reply Last reply
                                0
                                • Axel SpoerlA Axel Spoerl

                                  @Perdrix said in Preserving/Restoring QDockWidget size:

                                  At the end of the ctor as you did in you small example?

                                  The c'tor is definitely a good spot, but it has to be called after the dock widgets are fully created.

                                  PerdrixP Offline
                                  PerdrixP Offline
                                  Perdrix
                                  wrote on last edited by
                                  #21

                                  @Axel-Spoerl Moved the code to the ctor and all now works!

                                  The final code now reads:

                                  	ZTRACE_RUNTIME("Restoring Window State and Position");
                                  	QSettings settings{};
                                  	settings.beginGroup("MainWindow");
                                  
                                  	if (settings.contains("geometry") && settings.contains("maximised"))
                                  	{
                                  		const QByteArray geometry{ settings.value("geometry").toByteArray() };
                                  		const bool maximised{ settings.value("maximised").toBool() };
                                  
                                  		if (maximised)
                                  		{
                                  			showMaximized();
                                  			setGeometry(screen()->availableGeometry());
                                  		}
                                  		else
                                  		{
                                  			restoreGeometry(geometry);
                                  		}
                                  	}
                                  
                                  	if (settings.contains("windowState"))
                                  	{
                                  		auto windowState{ settings.value("windowState").toByteArray() };
                                  
                                  		restoreState(windowState);
                                  	}
                                  
                                  	settings.endGroup();
                                  

                                  Thanks
                                  David

                                  Axel SpoerlA 1 Reply Last reply
                                  0
                                  • PerdrixP Perdrix

                                    @Axel-Spoerl Moved the code to the ctor and all now works!

                                    The final code now reads:

                                    	ZTRACE_RUNTIME("Restoring Window State and Position");
                                    	QSettings settings{};
                                    	settings.beginGroup("MainWindow");
                                    
                                    	if (settings.contains("geometry") && settings.contains("maximised"))
                                    	{
                                    		const QByteArray geometry{ settings.value("geometry").toByteArray() };
                                    		const bool maximised{ settings.value("maximised").toBool() };
                                    
                                    		if (maximised)
                                    		{
                                    			showMaximized();
                                    			setGeometry(screen()->availableGeometry());
                                    		}
                                    		else
                                    		{
                                    			restoreGeometry(geometry);
                                    		}
                                    	}
                                    
                                    	if (settings.contains("windowState"))
                                    	{
                                    		auto windowState{ settings.value("windowState").toByteArray() };
                                    
                                    		restoreState(windowState);
                                    	}
                                    
                                    	settings.endGroup();
                                    

                                    Thanks
                                    David

                                    Axel SpoerlA Offline
                                    Axel SpoerlA Offline
                                    Axel Spoerl
                                    Moderators
                                    wrote on last edited by
                                    #22

                                    @Perdrix
                                    Hey David! Great! Glad that it works!
                                    Just two minor nitpicks:

                                    • no need to instantiate settings with curly braces.
                                    • if the settings object is meant to be only for reading settings, I would constify it. I've had strange bugs where settings became automagically written. E.g. in your case, an empty "MainWindow" group would be created. Such things are hard to debug, hence my constification paranoia.

                                    Software Engineer
                                    The Qt Company, Oslo

                                    PerdrixP 1 Reply Last reply
                                    0
                                    • Axel SpoerlA Axel Spoerl

                                      @Perdrix
                                      Hey David! Great! Glad that it works!
                                      Just two minor nitpicks:

                                      • no need to instantiate settings with curly braces.
                                      • if the settings object is meant to be only for reading settings, I would constify it. I've had strange bugs where settings became automagically written. E.g. in your case, an empty "MainWindow" group would be created. Such things are hard to debug, hence my constification paranoia.
                                      PerdrixP Offline
                                      PerdrixP Offline
                                      Perdrix
                                      wrote on last edited by Perdrix
                                      #23

                                      @Axel-Spoerl Thanks for all the help.

                                      If I made the settings object const, I suspect I couldn't issue settings.beginGroup()? Or does that change a mutable member of the class?

                                      Axel SpoerlA 1 Reply Last reply
                                      0
                                      • PerdrixP Perdrix

                                        @Axel-Spoerl Thanks for all the help.

                                        If I made the settings object const, I suspect I couldn't issue settings.beginGroup()? Or does that change a mutable member of the class?

                                        Axel SpoerlA Offline
                                        Axel SpoerlA Offline
                                        Axel Spoerl
                                        Moderators
                                        wrote on last edited by
                                        #24

                                        @Perdrix
                                        Good point, you are right. beginGroup()isn't const. So my advice is bad. Apologies, I'll take it back.

                                        Software Engineer
                                        The Qt Company, Oslo

                                        JonBJ 1 Reply Last reply
                                        0
                                        • Axel SpoerlA Axel Spoerl

                                          @Perdrix
                                          Good point, you are right. beginGroup()isn't const. So my advice is bad. Apologies, I'll take it back.

                                          JonBJ Offline
                                          JonBJ Offline
                                          JonB
                                          wrote on last edited by
                                          #25

                                          @Axel-Spoerl
                                          There is something wrong (lacking) in QSettings if the only reason a non-const can't be used to read is that you are forced to use beginGroup().

                                          Can one make a key to pass to value() to bypass the need to beginGroup()?

                                          Axel SpoerlA 1 Reply Last reply
                                          0

                                          • Login

                                          • Login or register to search.
                                          • First post
                                            Last post
                                          0
                                          • Categories
                                          • Recent
                                          • Tags
                                          • Popular
                                          • Users
                                          • Groups
                                          • Search
                                          • Get Qt
                                          • Unsolved