簡體   English   中英

如何使用不同的小部件調整 QTabWidget 的大小?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM