简体   繁体   English

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

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

I have a MainWindow with a Dockwidget attached to it for the sole purpose of switching between multiple Stackedwidget/StackedLayout我有一个带有DockwidgetMainWindow ,其唯一目的是在多个Stackedwidget/StackedLayout之间切换

The Issue i am having is that the StackedLayout holds a particular widget that displays a large image which resizes the MainWindow as expected but when switching from that Widget to another using the docked widget the MainWindow still uses the SizeHint from the large widget even after calling a MainWindow.Resize(stackedwidget) which leaves the window larger than necessary for the current widget in view我遇到的问题是StackedLayout包含一个特定的小部件,该小部件显示一个大图像,该图像按预期调整MainWindow大小,但是当使用docked widget从该Widget切换到另一个docked widgetMainWindow仍然使用来自大小部件的SizeHint ,即使在调用了MainWindow.Resize(stackedwidget)使窗口大于当前窗口小部件所需的视图

Here's the code:这是代码:

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_())

i Have also tried using a StackedWidget as the central widget and switching, same thing.我也尝试过使用StackedWidget作为中央小部件和切换,同样的事情。

The QStackedLayout always uses its minimum size based on the largest minimum size of all its widgets. QStackedLayout始终根据其所有小部件的最大最小尺寸使用其最小尺寸。 This also means that all widgets using a stacked layout behave in the same way: QStackedWidget and QTabWidget.这也意味着所有使用堆叠布局的小部件都以相同的方式运行:QStackedWidget 和 QTabWidget。

This is done by design, and it's the correct approach (otherwise the parent widget would always try to resize itself whenever a new "page" is set with a different minimum size)这是由设计完成的,这是正确的方法(否则,每当新“页面”设置为不同的最小大小时,父小部件总是会尝试调整自身大小)

The solution is to subclass the QStackedLayout (or the QStackedWidget) and override its minimumSize() ;解决方案是继承 QStackedLayout(或 QStackedWidget)并覆盖其minimumSize() if needed, sizeHint() could be overridden in the same fashion, but I wouldn't suggest it.如果需要,可以以相同的方式覆盖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()

Note that if you want to resize the main window to the minimum possible size you should use mainWindow.resize(mainWindow.minimumSizeHint()) , since a QMainWindow also has minimum size requirements depending on its extra widgets, like toolbars or, as in your case, dock widgets.请注意,如果您想将主窗口的大小调整为可能的最小尺寸,您应该使用mainWindow.resize(mainWindow.minimumSizeHint()) ,因为 QMainWindow 也有最小尺寸要求,具体取决于其额外的小部件,如工具栏或,如您的案例,停靠小部件。

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

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