简体   繁体   中英

PyQT5 QTabbar Expand tab header

I am writing a QTabwidget with only two tabs. But the tab headers (name) are not fitting the QTabwidget width. I want to fit the length of the tab bar (two tab headers)

import sys
from PyQt5.QtWidgets import QMainWindow, QApplication, QPushButton, QWidget, QAction, QTabWidget,QVBoxLayout
from PyQt5.QtGui import QIcon
from PyQt5.QtCore import pyqtSlot

class App(QMainWindow):

    def __init__(self):
        super().__init__()

        self.table_widget = MyTableWidget(self)
        self.setCentralWidget(self.table_widget)
        
        self.show()
    
class MyTableWidget(QWidget):
    
    def __init__(self, parent):
        super(QWidget, self).__init__(parent)
        self.layout = QVBoxLayout(self)
        
        self.tabs = QTabWidget()
        """ Here I want to fit the two tab 
            headers withthe QTabwidget width
        """
        self.tab1 = QWidget()
        self.tab2 = QWidget()
        self.tabs.resize(300,200)
        
        self.tabs.addTab(self.tab1,"Tab 1")
        self.tabs.addTab(self.tab2,"Tab 2")
        
        # Create first tab
        self.tab1.layout = QVBoxLayout(self)
        
        self.layout.addWidget(self.tabs)
        self.setLayout(self.layout)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = App()
    sys.exit(app.exec_())

Inspired by this answer , I think you can override showEvent (and even resizeEvent ) to calculate the new width and set it through stylesheets.

It is not canonical but it does the job.

import sys
from PyQt5.QtWidgets import QMainWindow, QApplication, QWidget, QTabWidget, QVBoxLayout


class App(QMainWindow):

    def __init__(self):
        super().__init__()
        self.table_widget = MyTableWidget(self)
        self.setCentralWidget(self.table_widget)

        self.show()


class MyTableWidget(QWidget):
    def __init__(self, parent):
        super(QWidget, self).__init__(parent)
        self.layout = QVBoxLayout(self)

        self.tabs = QTabWidget()
        self.tabs.tabBar().setExpanding(True)
        self.tab1 = QWidget()
        self.tab2 = QWidget()
        self.tabs.resize(300, 200)

        self.tabs.addTab(self.tab1, "Tab 1")
        self.tabs.addTab(self.tab2, "Tab 2")

        # Create first tab
        self.tab1.layout = QVBoxLayout(self)

        self.layout.addWidget(self.tabs)
        self.setLayout(self.layout)

    def resizeEvent(self, event):
        super().resizeEvent(event)
        self._set_tabs_width()

    def showEvent(self, event):
        super().showEvent(event)
        self._set_tabs_width()

    def _set_tabs_width(self):
        tabs_count = self.tabs.count()
        tabs_width = self.tabs.width()
        tab_width = tabs_width / tabs_count
        css = "QTabBar::tab {width: %spx;}" % tab_width
        self.tabs.setStyleSheet(css)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = App()
    sys.exit(app.exec_())

The size of tabs is computed using the hints given by the current QStyle.

Since QTabWidget uses the sizeHint of the tab bar to set the tab bar size and the sizeHint is usually based on the tabSizeHint() , you have to reimplement both:

  • sizeHint() is required in order to provide a width (or height) that is the same as the parent;
  • tabSizeHint() takes into account the base implementation of sizeHint() to compute the hint based on the contents of the tabs, and if it's less than the current size it suggests a size based on the available space divided by the tab count;
class TabBar(QtWidgets.QTabBar):
    def sizeHint(self):
        hint = super().sizeHint()
        if self.isVisible() and self.parent():
            if not self.shape() & self.RoundedEast:
                # horizontal
                hint.setWidth(self.parent().width())
            else:
                # vertical
                hint.setHeight(self.parent().height())
        return hint

    def tabSizeHint(self, index):
        hint = super().tabSizeHint(index)
        if not self.shape() & self.RoundedEast:
            averageSize = self.width() / self.count()
            if super().sizeHint().width() < self.width() and hint.width() < averageSize:
                hint.setWidth(averageSize)
        else:
            averageSize = self.height() / self.count()
            if super().sizeHint().height() < self.height() and hint.height() < averageSize:
                hint.setHeight(averageSize)
        return hint

# ...
        self.tabWidget = QtWidgets.QTabWidget()
        self.tabWidget.setTabBar(TabBar(self.tabWidget))

Do note that this is a very basic implementation, there are some situations for which you might see the scroll buttons with very long tab names, even if theoretically there should be enough space to see them.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM