繁体   English   中英

PyQt5:如何调整主窗口的大小以适合 Stackedwidget 或 Stackedlayout

[英]PyQt5: How to Resize mainwindow to fit a Stackedwidget or Stackedlayout

我有一个带有DockwidgetMainWindow ,其唯一目的是在多个Stackedwidget/StackedLayout之间切换

我遇到的问题是StackedLayout包含一个特定的小部件,该小部件显示一个大图像,该图像按预期调整MainWindow大小,但是当使用docked widget从该Widget切换到另一个docked widgetMainWindow仍然使用来自大小部件的SizeHint ,即使在调用了MainWindow.Resize(stackedwidget)使窗口大于当前窗口小部件所需的视图

这是代码:

from PyQt5 import QtCore, QtGui, QtWidgets

class Mainwindow(QtWidgets.QMainWindow):
    def __init__(self):
        super(Mainwindow, self).__init__()

        # window setting
        self.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)

        # window central widget
        self.centerwidget = QtWidgets.QWidget()
        self.setCentralWidget(self.centerwidget)

        # stack for page/widget management
        self.stack = QtWidgets.QStackedLayout(self.centerwidget)

        # widgets or page management
        self.widgeta = None
        self.dockWidget = None
        self.widgetb= None

    def pageManager(self, widget):

        # switching stack widgets 
        self.stack.setCurrentWidget(widget)
        widget.updateGeometry()
        widget.layout.update()
        self.centerwidget.updateGeometry()
        self.updateGeometry()
        self.resize(widget.layout.totalSizeHint())

    def load(self):
        # basically startup
        # stack settings
        self.widgeta= Widgeta()
        self.widgetb= Widgetb()
        self.stack.addWidget(self.widgeta)
        self.stack.addWidget(self.widgetb)
        self.stack.setStackingMode(QtWidgets.QStackedLayout.StackOne)
        self.stack.setCurrentWidget(self.widgeta)

        # dock widget
        self.dockWidget = Duck()
        self.addDockWidget(QtCore.Qt.TopDockWidgetArea, self.dockWidget)

        # show mainwindow
        self.show()

class Duck(QtWidgets.QDockWidget):
    def __init__(self, parent=None):
        super(Duck, self).__init__(parent)
        # create subwidget assign layout to subwidget
        self.dockCentralWidget = QtWidgets.QWidget()
        self.dockCentralWidgetlayout = QtWidgets.QHBoxLayout()
        self.dockCentralWidgetlayout.setContentsMargins(QtCore.QMargins(1,1,1,1))
        self.dockCentralWidgetlayout.setSpacing(1)
        self.dockCentralWidget.setLayout(self.dockCentralWidgetlayout)
        self.dockCentralWidget.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed)
        self.setStyleSheet("background-color: #354465;")
        # subwidget elements
        self.Ui()
        # add subwidget and elements
        self.setWidget(self.dockCentralWidget)
        self.dockCentralWidgetlayout.addWidget(self.widgetAButton)
        self.dockCentralWidgetlayout.addWidget(self.widgetBButton)
        
    def Ui(self):
        # first button
        self.widgetAButton = QtWidgets.QPushButton('aaaa')
        self.widgetAButton.clicked.connect(lambda : self.clicker((self.widgetAButton, Window.widgeta)))
        # second button 
        self.widgetBButton = QtWidgets.QPushButton('bbbb')
        self.widgetBButton.clicked.connect(lambda : self.clicker((self.widgetBButton, Window.widgetb)))
    
    def clicker(self, arg):
        Window.pageManager(arg[1])

class Widgeta(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super(Widgeta, self).__init__(parent)

        # sizing and layout
        self.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
        self.layout = QtWidgets.QVBoxLayout()
        self.setLayout(self.layout)

        # widgets
        self.ui()
    
    def ui(self):
        # a check button
        self.goButton = QtWidgets.QPushButton()
        self.goButton.setObjectName('gobutton')
        self.goButton.setText('ccc')
        self.goButton.setMinimumSize(QtCore.QSize(400, 150))
        self.goButton.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed)
        self.goButton.setStyleSheet(goButtonCSS)

        # label
        self.infoLabel = QtWidgets.QLabel()
        self.infoLabel.setObjectName('infolabel')
        self.infoLabel.setMinimumSize(QtCore.QSize(400, 250))
        self.infoLabel.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed)
        self.infoLabel.setText('jjjj')
        self.infoLabel.setStyleSheet(topDisplayCSS)

        # add widgets to layout
        self.layout.addWidget(self.infoLabel)
        self.layout.addWidget(self.goButton, QtCore.Qt.AlignVCenter, QtCore.Qt.AlignHCenter)
        self.layout.setContentsMargins(QtCore.QMargins(0,0,0,0))

if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    Window = Mainwindow()
    Window.load()
    sys.exit(app.exec_())

我也尝试过使用StackedWidget作为中央小部件和切换,同样的事情。

QStackedLayout始终根据其所有小部件的最大最小尺寸使用其最小尺寸。 这也意味着所有使用堆叠布局的小部件都以相同的方式运行:QStackedWidget 和 QTabWidget。

这是由设计完成的,这是正确的方法(否则,每当新“页面”设置为不同的最小大小时,父小部件总是会尝试调整自身大小)

解决方案是继承 QStackedLayout(或 QStackedWidget)并覆盖其minimumSize() 如果需要,可以以相同的方式覆盖sizeHint() ,但我不建议这样做。

class StackedLayout(QtWidgets.QStackedLayout):
    def minimumSize(self):
        if self.currentWidget():
            s = self.currentWidget().minimumSize()
            if s.isEmpty():
                s = self.currentWidget().minimumSizeHint()
            return s
        return super().minimumSize()

请注意,如果您想将主窗口的大小调整为可能的最小尺寸,您应该使用mainWindow.resize(mainWindow.minimumSizeHint()) ,因为 QMainWindow 也有最小尺寸要求,具体取决于其额外的小部件,如工具栏或,如您的案例,停靠小部件。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM