1

I can't quite figure out how the save and restore are suppose to work, so that I may save the dockwidgets geometrics, when the application is closed and opened again. I have 5 dockwidgets, which I'd like to have this feature.

I assume I have to use both restoreState and saveState respectively in init and close. But how do I configure it?

MainWindow class

import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from DockWindowGraph import Dock

class Window(QMainWindow):
    def __init__(self, parent=None):
        super(Window, self).__init__(parent)

        self.centralWindow_ = QFrame() 
        self.setCentralWidget(None)

        self.CreateWidgets()

        self.settings = QSettings()
        self.restoreState()

    def CreateWidgets(self):        
        self.toolbar = self.addToolBar('Toolbar')
        self.toolbar.setMovable(False)    

        exitA = QAction(QIcon('Images/gj.png'), 'Exit', self)
        exitA.setShortcut('Ctrl+Q')
        exitA.setStatusTip('Exit application')
        exitA.triggered.connect(self.close)   
        self.toolbar.addAction(exitA)

        openDock_ = QAction(QIcon('Images/gj.png'), 'Open', self)
        openDock_.setShortcut('Ctrl+E')
        openDock_.setStatusTip('Open Dock')
        openDock_.triggered.connect(self.OpenDockWindow)   
        self.toolbar.addAction(openDock_)

        self.setWindowTitle("We do not sow")
        self.showFullScreen()

        self.firstDock_ = Dock(self, 'First')
        self.firstDock_.setObjectName('First')
        self.addDockWidget(Qt.LeftDockWidgetArea, self.firstDock_)     

        self.secondDock_ = Dock(self, 'Second')
        self.firstDock_.setObjectName('Second')
        self.addDockWidget(Qt.LeftDockWidgetArea, self.secondDock_)

        self.thirdDock_ = Dock(self, 'Third')
        self.thirdDock_.setObjectName('Third')
        self.splitDockWidget(self.firstDock_, self.thirdDock_, Qt.Horizontal)

        self.fDock_ = Dock(self, 'Fourth')
        self.fDock_.setObjectName('Fourth')
        self.splitDockWidget(self.firstDock_, self.fDock_, Qt.Horizontal)

        self.fiDock_ = Dock(self, 'Fifth')
        self.fiDock_.setObjectName('Fifth')
        self.splitDockWidget(self.firstDock_, self.fiDock_, Qt.Vertical)

        self.setTabPosition(Qt.AllDockWidgetAreas, QTabWidget.North)

    def OpenDockWindow(self):
        dock_ = Dock((self.frameGeometry().width() / 2), self.firstDock_)

        self.addDockWidget(Qt.RightDockWidgetArea, dock_)
        self.tabifyDockWidget(self.secondDock_, dock_)

    def closeEvent(self, event):
        print('closing')

        settings_ = QSettings()
        self.saveState()


app = QApplication(sys.argv)
app.setOrganizationDomain('ltd')
app.setOrganizationName('Alg')
w = Window()
sys.exit(app.exec_())

my Dock class:

from PyQt4.QtCore import *
from PyQt4.QtGui import *
from DockWindowFrame import Frame

class Dock(QDockWidget):
    def __init__(self, title, parent=None):
        super(Dock, self).__init__(parent)

        self.setAllowedAreas(Qt.RightDockWidgetArea | Qt.LeftDockWidgetArea | Qt.TopDockWidgetArea | Qt.BottomDockWidgetArea)
        self.setFeatures(QDockWidget.DockWidgetFloatable | QDockWidget.DockWidgetMovable )

        self.frame = Frame()
        self.frame.setStyleSheet("QWidget { background-color: rgba(0,220,0,100%)}")
        self.setWidget(self.frame)

    def ReturnFrame(self):
        return self.frame

EDIT: Error after trying below answer.

Traceback (most recent call last):
  File "C:\Users\Rasmus\workspace\PyQtLearning\src\gg.py", line 90, in <module>
    main()
  File "C:\Users\Rasmus\workspace\PyQtLearning\src\gg.py", line 86, in main
    w = Window()
  File "C:\Users\Rasmus\workspace\PyQtLearning\src\gg.py", line 14, in __init__
    self.readSettings()
  File "C:\Users\Rasmus\workspace\PyQtLearning\src\gg.py", line 72, in readSettings
    self.restoreGeometry(settings.value("geometry").toByteArray())
AttributeError: 'NoneType' object has no attribute 'toByteArray'
vandelay
  • 1,965
  • 8
  • 35
  • 52

1 Answers1

4

This works here:

def __init__(self):
    self.readSettings()

def closeEvent(self, event):
    print('closing')
    settings = QSettings()
    settings.setValue('geometry',self.saveGeometry())
    settings.setValue('windowState',self.saveState())
    super(Window, self).closeEvent(event)

def readSettings(self):
    settings = QSettings()
    self.restoreGeometry(settings.value("geometry").toByteArray())
    self.restoreState(settings.value("windowState").toByteArray())

Reference: QMainWindow.saveState() QMainWindow.restoreState()

Full code:

# coding = u8
import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *

class Window(QMainWindow):
    def __init__(self, parent=None):
        super(Window, self).__init__(parent)

        self.centralWindow_ = QFrame() 
        self.setCentralWidget(None)

        self.CreateWidgets()
        self.readSettings()

    def CreateWidgets(self):        
        self.toolbar = self.addToolBar('Toolbar')
        self.toolbar.setMovable(False)    

        exitA = QAction(QIcon('Images/gj.png'), 'Exit', self)
        exitA.setShortcut('Ctrl+Q')
        exitA.setStatusTip('Exit application')
        exitA.triggered.connect(self.close)   
        self.toolbar.addAction(exitA)

        openDock_ = QAction(QIcon('Images/gj.png'), 'Open', self)
        openDock_.setShortcut('Ctrl+E')
        openDock_.setStatusTip('Open Dock')
        openDock_.triggered.connect(self.OpenDockWindow)   
        self.toolbar.addAction(openDock_)

        self.setWindowTitle("We do not sow")
        self.showFullScreen()

        self.firstDock_ = Dock(self, 'First')
        self.firstDock_.setObjectName('First')
        self.addDockWidget(Qt.LeftDockWidgetArea, self.firstDock_)     

        self.secondDock_ = Dock(self, 'Second')
        self.firstDock_.setObjectName('Second')
        self.addDockWidget(Qt.LeftDockWidgetArea, self.secondDock_)

        self.thirdDock_ = Dock(self, 'Third')
        self.thirdDock_.setObjectName('Third')
        self.splitDockWidget(self.firstDock_, self.thirdDock_, Qt.Horizontal)

        self.fDock_ = Dock(self, 'Fourth')
        self.fDock_.setObjectName('Fourth')
        self.splitDockWidget(self.firstDock_, self.fDock_, Qt.Horizontal)

        self.fiDock_ = Dock(self, 'Fifth')
        self.fiDock_.setObjectName('Fifth')
        self.splitDockWidget(self.firstDock_, self.fiDock_, Qt.Vertical)

        self.setTabPosition(Qt.AllDockWidgetAreas, QTabWidget.North)

    def OpenDockWindow(self):
        dock_ = Dock((self.frameGeometry().width() / 2), self.firstDock_)

        self.addDockWidget(Qt.RightDockWidgetArea, dock_)
        self.tabifyDockWidget(self.secondDock_, dock_)

    def closeEvent(self, event):
        print('closing')
        settings = QSettings()
        settings.setValue('geometry',self.saveGeometry())
        settings.setValue('windowState',self.saveState())
        super(Window, self).closeEvent(event)

    def readSettings(self):
        settings = QSettings()
        self.restoreGeometry(settings.value("geometry").toByteArray())
        self.restoreState(settings.value("windowState").toByteArray())

class Dock(QDockWidget):
    def __init__(self, title, parent=None):
        super(Dock, self).__init__(parent)

        self.setAllowedAreas(Qt.RightDockWidgetArea | Qt.LeftDockWidgetArea | Qt.TopDockWidgetArea | Qt.BottomDockWidgetArea)
        self.setFeatures(QDockWidget.DockWidgetFloatable | QDockWidget.DockWidgetMovable )

def main():
    app = QApplication(sys.argv)
    app.setOrganizationDomain('ltd')
    app.setOrganizationName('Alg')
    w = Window()
    sys.exit(app.exec_())

if __name__ == '__main__':
    main()
pingze
  • 973
  • 2
  • 9
  • 18
  • I got a None type. But found a possible solution at http://stackoverflow.com/questions/11352157/pyqt-window-i-want-to-remember-the-location-it-was-closed-at for it. But when I shot down my app and try to open it again. It won't open at all. – vandelay Aug 23 '16 at 12:47
  • @vandelay - Your code works fine in my place. I post them in may answer. – pingze Aug 23 '16 at 12:56
  • I tried copy pasting the full code, but it'll give me a 'NoneType'. If I place a if not settings.value() == None. It will run the first time. But if I start the application the second time, I will get a window with "Python has stopped working". Can this have something to do with eclipse/pydev? – vandelay Aug 23 '16 at 13:37
  • 1
    I have read the QSettings [Documentation](http://doc.qt.io/qt-4.8/qsettings.html) and found that Qsettings use different API in different way in different OS.`settings = QSettings()` can successfully read settings in my Win10(Build 10586), but it may works bad in some other conditions, that's why you got a "NoneType". You may try to use `QSettings(,)`, or check the API of your OS. Creating functions to save and load docks' pos/size/option in a .pkl file manully is another way. – pingze Aug 24 '16 at 02:37