[英]How to resize QTabWidget with different widgets?
我有一個主要的 window,它只包含一個 tabwidget。我在 mainwindow 上應用布局,以便在更改 mainwindow 的大小時使其自適應。我通過 qtdesigner 制作的兩個選項卡也應用布局。(就像制作一個單獨的窗口一樣)這兩個 sizehint 被設置為QSizePolicy.Preferred, QSizePolicy.Preferred
。 我希望 tabwidget 可以在選擇不同的選項卡時調整每個 QWidget 的最小尺寸,但我不知道如何實現它。
我已經嘗試了一些方法,例如根據當前 Tab 對堆棧溢出 QTabWidget 大小的回答。 但是我發現它對我不起作用。它似乎只花費了我的 window。
這是我的例子:
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_Form1(object):
def setupUi(self, Form1):
Form1.setObjectName("Form1")
Form1.resize(400, 300)
Form1.setMinimumSize(QtCore.QSize(400, 300))
self.horizontalLayout = QtWidgets.QHBoxLayout(Form1)
self.horizontalLayout.setObjectName("horizontalLayout")
self.pushButton = QtWidgets.QPushButton(Form1)
self.pushButton.setObjectName("pushButton")
self.horizontalLayout.addWidget(self.pushButton)
self.retranslateUi(Form1)
QtCore.QMetaObject.connectSlotsByName(Form1)
def retranslateUi(self, Form1):
_translate = QtCore.QCoreApplication.translate
Form1.setWindowTitle(_translate("Form1", "Form"))
self.pushButton.setText(_translate("Form1", "Test1"))
class Ui_Form2(object):
def setupUi(self, Form2):
Form2.setObjectName("Form2")
Form2.resize(261, 205)
Form2.setMinimumSize(QtCore.QSize(261, 205))
self.horizontalLayout = QtWidgets.QHBoxLayout(Form2)
self.horizontalLayout.setObjectName("horizontalLayout")
self.pushButton = QtWidgets.QPushButton(Form2)
self.pushButton.setObjectName("pushButton")
self.horizontalLayout.addWidget(self.pushButton)
self.retranslateUi(Form2)
QtCore.QMetaObject.connectSlotsByName(Form2)
def retranslateUi(self, Form2):
_translate = QtCore.QCoreApplication.translate
Form2.setWindowTitle(_translate("Form2", "Form"))
self.pushButton.setText(_translate("Form2", "Test2"))
class Ui_mainWindow(object):
def setupUi(self, mainWindow):
mainWindow.setObjectName("mainWindow")
mainWindow.setWindowModality(QtCore.Qt.ApplicationModal)
self.horizontalLayout = QtWidgets.QHBoxLayout(mainWindow)
self.horizontalLayout.setObjectName("horizontalLayout")
self.tabWidget = QtWidgets.QTabWidget(mainWindow)
self.tabWidget.setObjectName("tabWidget")
self.horizontalLayout.addWidget(self.tabWidget)
self.retranslateUi(mainWindow)
QtCore.QMetaObject.connectSlotsByName(mainWindow)
def retranslateUi(self, mainWindow):
_translate = QtCore.QCoreApplication.translate
mainWindow.setWindowTitle(_translate("mainWindow", "calc"))
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
Form1 = QtWidgets.QWidget()
ui1 = Ui_Form1()
ui1.setupUi(Form1)
Form2 = QtWidgets.QWidget()
ui2 = Ui_Form2()
ui2.setupUi(Form2)
Form3 = QtWidgets.QWidget()
ui3 = Ui_mainWindow()
ui3.setupUi(Form3)
ui3.tabWidget.addTab(Form1, "test1")
ui3.tabWidget.addTab(Form2, "test2")
Form3.show()
sys.exit(app.exec_())
這是我用 qtdesigner 創建的兩個小部件。每個小部件都有自己的默認大小和最小大小。 window1 window2之后,我將它們添加到 tabwidget 中,但它們的大小相同。Tabwidget 似乎適應了兩者中的最大尺寸。我無法更改 window 尺寸,盡管在最小尺寸較小的選項卡中。 選項卡 1 選項卡 2
在我根據當前 Tab 使用 QTabWidget 大小的嘗試中,我只是按照答案中的解決方案。不幸的是,它不起作用。
self.mainW.tabWidget.currentChanged.connect(self.updateSize)
def updateSize(self, index):
sizePolicyI = QSizePolicy(QSizePolicy.Ignored, QSizePolicy.Ignored)
sizePolicyP = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred)
for i in range(self.mainW.tabWidget.count()):
if not i == index:
self.mainW.tabWidget.widget(i).setSizePolicy(sizePolicyI)
self.mainW.tabWidget.widget(index).setSizePolicy(sizePolicyP)
self.mainW.tabWidget.widget(index).resize(self.mainW.tabWidget.widget(index).minimumSizeHint())
self.mainW.tabWidget.widget(index).adjustSize()
self.mainW.resize(self.mainW.minimumSizeHint())
self.mainW.adjustSize()
雖然更新小部件的大小策略可能有效,但它並不總是有效的解決方案,尤其是當這些小部件的大小策略不是Preferred
時。
實現這一點的唯一、安全的方法是使用 QTabWidget 子類,因為這允許完全控制其虛擬函數sizeHint()
和minimumSizeHint()
返回的內容。
class TabWidget(QTabWidget):
def minimumSizeHint(self):
if self.count() < 0:
return super().sizeHint()
baseSize = self.currentWidget().sizeHint().expandedTo(
self.currentWidget().minimumSize())
if not self.tabBar().isHidden():
tabHint = self.tabBar().sizeHint()
if self.tabPosition() in (self.North, self.South):
baseSize.setHeight(baseSize.height()
+ tabHint.height())
else:
baseSize.setWidth(baseSize.width()
+ tabHint.width())
opt = QStyleOptionTabWidgetFrame()
self.initStyleOption(opt)
return self.style().sizeFromContents(
QStyle.CT_TabWidget, opt, baseSize, self)
def sizeHint(self):
return self.minimumSizeHint()
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.tabWidget = TabWidget()
self.setCentralWidget(self.tabWidget)
self.setStyleSheet('''
QLabel {
border: 1px solid green;
}
''')
self.tabWidget.addTab(
QLabel(
'640x480',
minimumSize=QSize(640, 480),
alignment=Qt.AlignCenter
),
'First'
)
self.tabWidget.addTab(
QLabel(
'320x240',
minimumSize=QSize(320, 240),
alignment=Qt.AlignCenter
),
'Second'
)
self.tabWidget.currentChanged.connect(self.updateSize)
def updateSize(self):
self.tabWidget.updateGeometry()
super().updateGeometry()
self.adjustSize()
注意:這並不完美。 由於 Qt styles 引起的許多“怪癖”,大小不會得到充分尊重,但重要的是要考慮默認實現也會發生這種情況。
我懷疑這是每種樣式的sizeFromContents
實現中的一個錯誤,因為我根據使用的樣式得到不同的結果。 N.netheless,上面的結果很符合預期。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.