将选项卡扩展到完整 window 大小?

expanding tabs to full window size?

几天来我一直在为与选项卡相关的问题而苦苦挣扎。我正在努力使我的应用程序中的选项卡栏延伸到 window 大小的整个宽度。我同时使用 MacOS 和 Ubuntu,虽然两者的最终结果不同,但都不起作用。

到目前为止,我已经尝试了一些东西。首先,我创建了 QtWidgets.QTabBar 的子类并将其用作选项卡栏。我尝试将 expand 设置为 true (self.setExpand(True)),但据我所知,这不会让你覆盖 OS 默认值。

下一个想法是覆盖 tabSizeHint,这似乎是正确的方法,但我一直无法弄清楚实现。这是我目前正在做的事情,对我来说,这似乎应该可行:

import sys
from PySide2 import QtCore, QtWidgets, QtGui

class TabBar(QtWidgets.QTabBar):
    def __init__(self, parent=None):
        super(TabBar, self).__init__(parent)
        self.setExpanding(True)

    def tabSizeHint(self, index):
        size = QtWidgets.QTabBar.tabSizeHint(self, index)
        width = self.parent().size().width()
        size.setWidth( width / self.count() )
        return size

class TabWindow(QtWidgets.QTabWidget):
    def __init__(self, parent=None):
        super(TabWindow, self).__init__(parent)
        self.bar = TabBar()
        self.setTabBar(self.bar)
        self.initTabs()

    def initTabs(self):
        self.test1 = self.addTab(QtWidgets.QWidget(), "Test 1")
        self.test2 = self.addTab(QtWidgets.QWidget(),"Test 2")
        self.test3 = self.addTab(QtWidgets.QWidget(),"Test 3")
        self.test4 = self.addTab(QtWidgets.QWidget(),"Test 4")

class MainApplication(QtWidgets.QMainWindow):
    def __init__(self, parent=None):
        super(MainApplication, self).__init__(parent)
        self.mainWidget = TabWindow()
        self.setCentralWidget(self.mainWidget)

if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    main_app = MainApplication()
    main_app.show()
    sys.exit(app.exec_())

这在我最初启动程序时有效,但如果我展开 window,则不会扩大选项卡的大小。似乎 tabSizeHint 没有被调用。我采用的另一种(失败的)方法如下:

class TabBar(QtWidgets.QTabBar):
    def __init__(self, parent=None):
        super(TabBar, self).__init__(parent)

class TabWindow(QtWidgets.QTabWidget):
    def __init__(self, parent=None):
        super(TabWindow, self).__init__(parent)
        self.bar = TabBar()
        self.setTabBar(self.bar)
        self.initTabs()
        layout = QtWidgets.QHBoxLayout()
        layout.addWidget(self.bar)
        self.setLayout(layout)

    def initTabs(self):
        self.test1 = self.addTab(QtWidgets.QWidget(), "Test 1")
        self.test2 = self.addTab(QtWidgets.QWidget(),"Test 2")
        self.test3 = self.addTab(QtWidgets.QWidget(),"Test 3")
        self.test4 = self.addTab(QtWidgets.QWidget(),"Test 4")

class MainApplication(QtWidgets.QMainWindow):
    def __init__(self, parent=None):
        super(MainApplication, self).__init__(parent)
        self.mainWidget = TabWindow()
        self.setCentralWidget(self.mainWidget)

if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    main_app = MainApplication()
    main_app.show()
    sys.exit(app.exec_())

对于这个,每当我点击选项卡时,它会短暂显示 4 个选项卡占据整个宽度(如我所愿),但在 window 的中间而不是最佳。不久之后,它将消失并恢复为 window 顶部的默认大小的选项卡,就好像它被其他东西覆盖了一样。

QTabWidget计算什么时候需要改变QTabBar的大小,所以解决方法是强制有一个等于[=12=的新宽度].

from PySide2 import QtCore, QtGui, QtWidgets 

class TabWindow(QtWidgets.QTabWidget):
    def __init__(self, parent=None):
        super(TabWindow, self).__init__(parent)
        self.initTabs()

    def initTabs(self):
        self.test1 = self.addTab(QtWidgets.QWidget(), "Test 1")
        self.test2 = self.addTab(QtWidgets.QWidget(),"Test 2")
        self.test3 = self.addTab(QtWidgets.QWidget(),"Test 3")
        self.test4 = self.addTab(QtWidgets.QWidget(),"Test 4")

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

class MainApplication(QtWidgets.QMainWindow):
    def __init__(self, parent=None):
        super(MainApplication, self).__init__(parent)
        self.mainWidget = TabWindow()
        self.setCentralWidget(self.mainWidget)

if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    main_app = MainApplication()
    main_app.resize(640, 480)
    main_app.show()
    sys.exit(app.exec_())

使用之前的实现,如果宽度很小,就会出现按钮(在Linux中,我没有在MacOS中测试过),避免这种情况的一种方法是实施 tabSizeHint() 方法:

from PySide2 import QtCore, QtGui, QtWidgets 

class TabBar(QtWidgets.QTabBar):
    def __init__(self, parent=None):
        super(TabBar, self).__init__(parent)
        self.setExpanding(True)

    def tabSizeHint(self, index):
        if self.count() > 0:
            size = QtWidgets.QTabBar.tabSizeHint(self, index)
            width = self.parent().size().width()/self.count()
            return QtCore.QSize(width, size.height())
        return super(TabBar, self).tabSizeHint(index)

class TabWindow(QtWidgets.QTabWidget):
    def __init__(self, parent=None):
        super(TabWindow, self).__init__(parent)
        self.bar = TabBar()
        self.setTabBar(self.bar)
        self.initTabs()

    def initTabs(self):
        self.test1 = self.addTab(QtWidgets.QWidget(), "Test 1")
        self.test2 = self.addTab(QtWidgets.QWidget(),"Test 2")
        self.test3 = self.addTab(QtWidgets.QWidget(),"Test 3")
        self.test4 = self.addTab(QtWidgets.QWidget(),"Test 4")

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

class MainApplication(QtWidgets.QMainWindow):
    def __init__(self, parent=None):
        super(MainApplication, self).__init__(parent)
        self.mainWidget = TabWindow()
        self.setCentralWidget(self.mainWidget)

if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    main_app = MainApplication()
    main_app.resize(640, 480)
    main_app.show()
    sys.exit(app.exec_())