[英]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
我有一个带有Dockwidget
的MainWindow
,其唯一目的是在多个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 widget
, MainWindow
仍然使用来自大小部件的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.