PyQt 隐藏 QTabWidget 的内容但保持 QTabBar 可见

问题描述 投票:0回答:1

我想知道在 PyQt 中,当尝试隐藏 QTabWidget 时是否可以隐藏内容本身,但保持 QTabBar 可见。

到目前为止,我有继承自 QTabBar 和 QTabWidget 的自定义 TabBar 和 TabWidget。我的 TabBar 是垂直的,位于 TabWidget 的西侧。

我已经创建了按钮并将一个插槽连接到它,该插槽应该隐藏 TabWidget。问题是,隐藏 TabWidget 会隐藏 TabBar,这是我不想要的。

我尝试过重写 .hide() 方法,尝试过

self.tab_widget.hide()
self.tab_widget.tabBar().show()

但是没有任何作用,因为TabWidget是TabBar的父级,隐藏TabWidget,自动隐藏TabBar。

当然,我可以用两个小部件构建我自己的穷人的 TabWidget,以便我可以随时隐藏和显示小部件,但是从 QTabWidget 继承非常方便,我不想从头开始。

我也可以在隐藏时将选项卡小部件的大小调整为TabBar的宽度,但我觉得这也是愚蠢的解决方案。

我的想法是有一个可扩展/可收缩和可隐藏的侧边栏,例如在 VSCode 中。

C++ QT 中的解决方案也会有帮助,因为我都了解,而且这不一定是 Python 问题,而是 Qt 问题。

python qt pyqt qtabwidget
1个回答
0
投票

QTabWidget 是一个复合小部件,由 QTabBar 和 QStackedWidget 组成。

最重要的是,它覆盖了布局管理所需的基本方面,例如

sizeHint()
minimumSizeHint()
sizePolicy()

您不能只切换选项卡栏的可见性(也不能切换堆叠的小部件内容):

  1. 正如您已经发现的那样,隐藏 QTabWidget 并显示选项卡栏基本上是无操作的,因为父级可见性具有优先级:在
    nested
    子级(没有
    show() 的 QWidget)上调用 
    setVisible(True)Qt.Window
     
    窗口标志)只会在父级显示时才使其可见;
  2. 尝试隐藏堆叠的小部件是无关紧要的,因为 QTabWidget 大小提示函数将始终考虑堆叠的小部件提示,无论可见性如何;

这是一种可能的实现,每当在当前可见页面(如果有)上单击选项卡时,都会切换选项卡“页面”的可见性:单击当前选定且可见的选项卡将始终隐藏内容,而内容将变得可见单击任何选项卡时,即使看不到任何内容。

from PyQt5.QtWidgets import *

class ToggleTabWidget(QTabWidget):
    _contentsVisible = True
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        self.tabBarClicked.connect(self.toggleContentsVisibleFromClick)
        self._stackedWidget = self.findChild(QStackedWidget)

    def toggleContentsVisibleFromClick(self, index):
        if not self._contentsVisible or index == self.currentIndex():
            self.toggleContentsVisibility()

    def toggleContentsVisibility(self):
        self.setContentsVisible(not self._contentsVisible)

    def setContentsVisible(self, visible):
        if self._contentsVisible != visible:
            self._contentsVisible = visible
            self._stackedWidget.setVisible(visible)
            self.setDocumentMode(not visible)

            tabHint = self.tabBar().sizeHint()
            maxSize = 16777215 # default maximum size
            if not self.tabPosition() & self.West:
                # horizontal
                if not visible:
                    maxSize = tabHint.height()
                self.setMaximumHeight(maxSize)
            else:
                if not visible:
                    maxSize = tabHint.width()
                self.setMaximumWidth(maxSize)


class Test(QWidget):
    def __init__(self):
        super().__init__()
        self.tabWidget = ToggleTabWidget()
        self.tabWidget.addTab(QTextEdit('hello world'), 'Hello')
        self.tabWidget.addTab(QTextEdit('bye world'), 'Bye')
        self.table = QTableWidget(10, 2)

        layout = QVBoxLayout(self)
        layout.addWidget(self.tabWidget)
        layout.addWidget(self.table)


app = QApplication([])
test = Test()
test.show()
app.exec()

请注意:

  • 这不考虑可能影响选项卡栏大小的样式更改(包括进一步调用
    setStyleSheet()
    )或字体更改;
  • 正确的实现不应该使用
    setMaximum<size-or-dimension>()
    ,而是覆盖
    sizeHint()
    minimumSizeHint()
    ,并且还应该考虑选项卡小部件大小策略中可能的变化;
  • 由于上述原因,应考虑在课堂外进行的
    maximum<size-or-dimension>
    的显式更改;
  • setDocumentMode
    用于完全“隐藏”选项卡页的内容,并且将忽略任何先前或进一步的显式调用;如果您需要使用该属性,则必须实现另一个属性来管理显式设置的值和通过可见性切换设置的内部值;
© www.soinside.com 2019 - 2024. All rights reserved.