简体   繁体   English

PyQT5 QTabbar 展开选项卡 header

[英]PyQT5 QTabbar Expand tab header

I am writing a QTabwidget with only two tabs.我正在编写一个只有两个选项卡的 QTabwidget。 But the tab headers (name) are not fitting the QTabwidget width.但是选项卡标题(名称)不适合 QTabwidget 宽度。 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.受此答案的启发,我认为您可以覆盖showEvent (甚至resizeEvent )来计算新宽度并通过样式表进行设置。

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.选项卡的大小是使用当前 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:由于 QTabWidget 使用标签栏的 sizeHint 来设置标签栏的大小,并且 sizeHint 通常基于tabSizeHint() ,因此您必须重新实现两者:

  • sizeHint() is required in order to provide a width (or height) that is the same as the parent;需要 sizeHint() 以提供与父级相同的宽度(或高度);
  • 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; tabSizeHint() 考虑到 sizeHint() 的基本实现,以根据选项卡的内容计算提示,如果它小于当前大小,则建议基于可用空间除以选项卡计数的大小;
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.请注意,这是一个非常基本的实现,在某些情况下,您可能会看到带有很长选项卡名称的滚动按钮,即使理论上应该有足够的空间来查看它们。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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