I've been struggling with something related to tabs for a few days now. I'm trying to make it so that the tab bar I have in my application extends across the full width of the window size. I’m working with both MacOS and Ubuntu, and while the final result of both differs, neither work.
Up to now, I've tried a few things. First, I made subclass of QtWidgets.QTabBar and use that as the tab bar. I tried setting expand to true (self.setExpand(True)), but from everything I’ve heard, that doesn’t let you override OS defaults.
The next idea was to override tabSizeHint, and it seems like this is the right approach, but I haven’t been able to figure out the implementation. Here’s what I’m doing as of now, that to me, seems like it should work:
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_())
This works when I initially start the program, but does not expand the size of the tabs if I expand the window. It seems that tabSizeHint is not getting called. Another (failed) approach I took is the follow:
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_())
For this one, whenever I click on the tab, it will briefly show the 4 tabs taking up the whole width (as I want it to), but in the middle of the window rather than the top. Shortly after that, it will disappear and revert back to the default sized tabs on the top of the window, as though it's being overwritten by something else.
The
QTabWidget
calculates when it is necessary to change the size of theQTabBar
, so the solution is to force to have a new width that is equal to that of theQTabWidget
.With the previous implementation if the width is small, the buttons appear (in Linux, I have not tested in Mac OS), one way to avoid this is to implement the
tabSizeHint()
method: