如何在QTabWidget中制作一个标签栏?

时间:2016-02-22 15:02:15

标签: pyqt customization qtabwidget

我需要自定义我的QTabWidget,以便其中一个标签栏(假设总共有4个标签)具有扩展属性,并将填充其他标签之间的剩余空间。有什么想法吗?

2 个答案:

答案 0 :(得分:1)

你可以继承QTabBar,将其设置为tabwidget的宽度(高度取决于fontsize)并覆盖tabSizeHint()

class tabBar(QTabBar):

    def __init__(self, width, height, parent=None):
        QTabBar.__init__(self, parent)
        self.setFixedSize(width, height)

    def tabSizeHint(self, i):
        f = 3                           # Tab3 shall be f times wider then the other tabs
        tw = int(self.width()/(self.count() + f -1))        # width per Tab
        if i == 2:                      # Tab3                      
            # return QSize(tw*f, self.height())         edited -> rounding error possible
            return QSize(self.width() - (self.count() - 1)*tw, self.height())
        return QSize(tw, self.height())             # all other tabs

并将此tabBar设置为tabwidget:

tb = tabBar(tabWidget.width(), 34)                  # tabBars height depends on fontSize
tabwidget..setTabBar(tb)

看起来像这样:

tabwidget with expanded tab

修改

如果调整tabWidget的大小,则会出现resizeEvent()。在这一刻,tabWidget已经有了它的新大小,并在resizeEvent()之后立即重新绘制, see QT-Doc QTabWidget.resizeEvent

因此,如果tabBar的width()resizeEvent()中被调整,则tabBar将始终具有与tabwidget相同的宽度。由于tabSizeHint()取决于宽度,因此所有标签也都具有正确的宽度。因此,您可以将QTabWidget()子类化并覆盖resizeEvent()以获得动态解决方案:

class tabWidget(QTabWidget):

    def __init__(self, parent=None):
        QTabWidget.__init__(self, parent)

    def resizeEvent(self, event):
        self.tabBar().setFixedWidth(self.width())
        QTabWidget.resizeEvent(self, event)

答案 1 :(得分:1)

要正确执行此操作,必须从选项卡的现有大小向后工作。这是因为选项卡大小受当前样式以及选项卡关闭按钮等其他功能的影响。为标签设置最小尺寸也很重要,这是可以放大的(否则它可以调整为空白)。

这是一个简单的演示,可以完成所有这些:

from PyQt4 import QtCore, QtGui

class TabBar(QtGui.QTabBar):
    def __init__(self, expanded=-1, parent=None):
        super(TabBar, self).__init__(parent)
        self._expanded = expanded

    def tabSizeHint(self, index):
        size = super(TabBar, self).tabSizeHint(index)
        if index == self._expanded:
            offset = self.width()
            for index in range(self.count()):
                offset -= super(TabBar, self).tabSizeHint(index).width()
            size.setWidth(max(size.width(), size.width() + offset))
        return size

class TabWidget(QtGui.QTabWidget):
    def __init__(self, expanded=-1, parent=None):
        super(TabWidget, self).__init__(parent)
        self.setTabBar(TabBar(expanded, self))

    def resizeEvent(self, event):
        self.tabBar().setMinimumWidth(self.width())
        super(TabWidget, self).resizeEvent(event)

class Window(QtGui.QWidget):
    def __init__(self):
        super(Window, self).__init__()
        self.tabs = TabWidget(2, self)
        layout = QtGui.QVBoxLayout(self)
        layout.addWidget(self.tabs)
        for text in 'One Two Three Four'.split():
            self.tabs.addTab(QtGui.QWidget(self), text)

if __name__ == '__main__':

    import sys
    app = QtGui.QApplication(sys.argv)
    window = Window()
    window.setGeometry(500, 300, 400, 200)
    window.show()
    sys.exit(app.exec_())