Не работает setGeometry для QDockWidget при размещении его в QMainWindow PyQt6

Надо установить положение и размер для QDockWidget, который находиться в QMainWindow.

В QMainWindow, 7 QDockWidget.

Создание QDock:

self.dock = QDockWidget('Фильтр')
self.dock.setAllowedAreas(Qt.DockWidgetArea.AllDockWidgetAreas)
_window.addDockWidget(Qt.DockWidgetArea.RightDockWidgetArea, self.dock)
self.dock.setWidget(self.Table_filter)

self.dock = QDockWidget('История изменений выделенной накладной')
self.dock.setAllowedAreas(Qt.DockWidgetArea.AllDockWidgetAreas)
_window.addDockWidget(Qt.DockWidgetArea.RightDockWidgetArea, self.dock)
self.dock.setWidget(self.Table_history__select_Nacl_history_Orders)
                            

При активации приложения применение размеров:

sql_file_settings._cursor.execute("SELECT x, y, width, height, state FROM dock_data WHERE dock_name = ?", (name,))
data = sql_file_settings._cursor.fetchone()
if data:
    x, y, width, height, state = data
    self.dock.setGeometry(x, y, width, height)


_window = QMainWindow

self.dock.setGeometry(0,0,200,260) 

не работает, размер и положение не изменяются.


Вообще мне надо сделать сохранение положения и размеров нескольких QDockWidget (расположенных в одном QMainWindow) при закрытии приложения.
Для того чтобы при следующей активации приложения они были такими какими их настроил пользователь.


Ответы (1 шт):

Автор решения: S. Nick

Пожалуйста, ВСЕГДА предоставьте минимальный воспроизводимый пример, который демонстрирует проблему.

Sorry, у меня PyQt5.

Класс QSettings обеспечивает постоянные, независимые от платформы настройки приложения.

А выглядеть, то что вы хотите сделать, примерно так:

from PyQt5.Qt import *


class DockWidget(QDockWidget):
    def __init__(self, title, parent):
        super(DockWidget, self).__init__(title, parent)
        self.win_name = title
        self.parent = parent
        self.setObjectName(self.win_name)   
        self.can_close = False

    def restore_window(self) -> bool:
        try:
            settings = QSettings("MySoftExamples", "DockWidgets")
            self.restoreGeometry(settings.value(f'{self.win_name} Geometry'))
            self.restoreState(settings.value(f'{self.win_name} State'))
            return True
        except:
            return False
            
    def closeEvent(self, event):   
        if not self.can_close:
            event.ignore()
        else:
            settings = QSettings("MySoftExamples", "DockWidgets")
            settings.setValue(f'{self.win_name} Geometry', self.saveGeometry())
            settings.setValue(f'{self.win_name} State', self.parent.saveState())
            QDockWidget.closeEvent(self, event)
            

class RememberWin(QMainWindow):
    def __init__(self, win_name: str):
        super(RememberWin, self).__init__()
        self.win_name = win_name
        self.setObjectName(win_name)                        
        self.setWindowTitle(win_name)
        self.can_close = False

    def restore_window(self) -> bool:
        try:
            settings = QSettings("MySoftExamples", "DockWidgets")
            self.restoreGeometry(settings.value(f'{self.win_name} Geometry'))
            self.restoreState(settings.value(f'{self.win_name} State'))
            return True
        except:
            return False

    def closeEvent(self, event: QCloseEvent):
        if not self.can_close:
            event.ignore()
        else:
            settings = QSettings("MySoftExamples", "DockWidgets")
            settings.setValue(f'{self.win_name} Geometry', self.saveGeometry())
            settings.setValue(f'{self.win_name} State', self.saveState())
            super().closeEvent(event)
    
     
class ControlWindow(RememberWin):
    def __init__(self, win_name: str="ControlWindow"):
        super(ControlWindow, self).__init__(win_name=win_name)
        self.can_close = True        

        self.textEdit = QTextEdit('Вы можете закрыть только это окно.')
        self.setCentralWidget(self.textEdit)

        self.dockAble()
        
        if not self.restore_window():
            self.setGeometry(200, 290, 600, 300)
        if not self.dock1.restore_window():
            self.dock1.setGeometry(700, 100, 200, 200)
        if not self.dock2.restore_window():
            self.dock2.setGeometry(950, 100, 200, 200)

        self.dock1.show()
        self.dock2.show()
      
        self.settings = QSettings("MySoftExamples", "DockWidgets")
        self.zOrder = []
        QApplication.instance().focusObjectChanged.connect(self.focusChanged)

        windowOrder = self.settings.value('windowOrder', type='QStringList')
        topLevelWindows = QApplication.topLevelWidgets()
        if windowOrder:
            for objName in windowOrder:
                for win in topLevelWindows:
                    if win.objectName() == objName:
                        win.show()
        else:
            self.dock1.show()
            self.dock2.show()

    def focusChanged(self, obj):
        if not obj or obj.window() == self.window():
            return
        if obj.window() in self.zOrder[:-1]:
            self.zOrder.remove(obj.window())
        self.zOrder.append(obj.window())

    def closeEvent(self, event: QCloseEvent):
        for win in (self.dock1, self.dock2):
            win.can_close = True
            win.close()
        self.settings.setValue('windowOrder', 
            [w.window().objectName() for w in self.zOrder])
        super(ControlWindow, self).closeEvent(event)

    def dockAble(self):
        self.dock1 = DockWidget("Fruits", self)
        self.dock1.setAllowedAreas(Qt.DockWidgetArea.AllDockWidgetAreas)

        self.myfruit = ["Груша", "Айва", "Персик", "Яблоко"]
        self.listwidget1 = QListWidget(self.dock1)
        self.listwidget1.addItems(self.myfruit)
        self.listwidget1.itemClicked.connect(self.clickedItemListwidget1)
        self.dock1.setWidget(self.listwidget1)
        self.addDockWidget(Qt.DockWidgetArea.RightDockWidgetArea, self.dock1) 

        self.dock2 = DockWidget("Vegetables", self)
        self.dock2.setAllowedAreas(Qt.DockWidgetArea.AllDockWidgetAreas)
        self.myvegetables = ["Капуста", "Лук", "Морковь", "Огкрец"]
        self.listwidget2 = QListWidget(self.dock2)
        self.listwidget2.addItems(self.myvegetables)
        self.listwidget2.itemClicked.connect(self.clickedItemListwidget1)
        self.dock2.setWidget(self.listwidget2)
        self.addDockWidget(Qt.DockWidgetArea.RightDockWidgetArea, self.dock2)
        
    def clickedItemListwidget1(self, item):
        self.textEdit.append(item.text())


if __name__ == '__main__':
    import sys
    app = QApplication(sys.argv)
    w = ControlWindow(win_name='ControlWindow')
    w.show()
    sys.exit(app.exec())

введите сюда описание изображения

введите сюда описание изображения

→ Ссылка