簡體   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