Search code examples
pythonpyqt5qtabwidgetqtabbar

Make every tab the same size and expandable


I was looking at this question asked 2 years ago: Make every tab the same width and also expandable

The solution is exactly what I am looking for, except that it does not work for me. I think I lack some elements in my code.

I used QtDesigner to design the window. I import the .py that is created. This file contains the QTabWidget that I want to resize and use all the width available. It is inserted in a HBoxLayout with a Frame next to it.

Then I proceed as follow in the controller_file.py:

I overwrite the TabBar class:

class tabBar(QTabBar):

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

       def tabSizeHint(self, index):
           size = QTabBar.tabSizeHint(self, index)
           w = int(self.width()/self.count())
           return QSize(w, size.height())

Then, I .setTabBar(tabBar()) to the QTabWidget in the __ init__ of the controller_file.py:

class flex_ctrl(QObject):

    def __init__(self, model, view, parent=None):
        super().__init__(parent)
        self._model = model
        self._view = view
        self.is_save = True
        self.file_name = ''

        self._view.graph_tot_tab.setTabBar(tabBar())

        self._get_file_menu()
        self._connect_signals()
        self.view.installEventFilter(self)

The problem is that when I do this, the Bar disappear. I can not switch between tabs:

Original tab

Becomes this:

Modified tab

Could you help me?

P.S: Sorry, but I could not give a fully reproducible example of my problem without giving the whole code. I did not find how to reproduce this "error"


Solution

  • It doesn't work because QTabBar needs a parent to construct itself properly (and ensure that the QTabWidget can initialize it correctly).

    Just add the tab widget as a parent when initializing the tab bar, but remember that this has to be done before adding any tab:

    setTabBar(QTabBar):

    Replaces the dialog's QTabBar heading with the tab bar tb. Note that this must be called before any tabs have been added, or the behavior is undefined.

    As long as no tabs exist yet, the following will suffice:

    self._view.graph_tot_tab.setTabBar(tabBar(self._view.graph_tot_tab))
    

    If, instead, you already added the tabs in Designer, this would obviously be a problem.

    While a possible solution might be to use a for cycle to remove all existing tabs and add them again (after the removal process), I've never tested it and I'm not really sure about the results. The best solution for this would be to subclass QTabWidget and promote the tab widget in Designer to your custom class.