我想知道在PyQt中,当试图隐藏QTabWidget时,是否有可能隐藏内容本身,但保持QTabBar可见.

到目前为止,我拥有从QTabBar和QTabWidget继承的自定义TabBar和TabWidget.我的TabBar是垂直的,在TabWidget的西侧.

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

我试过重写.ide()方法,试过了

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

但是都不起作用,因为TabWidget是TabBar的父级,隐藏TabWidget会自动隐藏TabBar.

当然,我可能可以从两个小部件构建我自己的TabWidget,这样我就可以随时隐藏和显示这些小部件,但从QTabWidget继承非常方便,我不想从头开始.

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

My Idea is to have an expandable/shrinkable and hideable sidebar, such as in VSCode. enter image description here

C++Qt的解决方案也会有帮助,因为我两者都理解,而且这不一定是Python问题,而是Qt.

推荐答案

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

最重要的是,它覆盖了布局管理所需的基本方面,如sizeHint()minimumSizeHint()sizePolicy().

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

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

这是一种可能的实现,每当在当前可见页面(如果有的话)上点击选项卡时,切换选项卡"Pages"的可见性:点击当前选定且可见的选项卡将始终隐藏内容,而当点击任何选项卡时,即使没有可见的内容,内容也将变为可见.

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用于完全"隐藏"选项卡页的内容,并将忽略任何先前或进一步的显式调用;如果需要使用该属性,则必须实现另一个属性,该属性管理显式设置的值和由可见性切换设置的内部值;

Python相关问答推荐

Inquirer库不适用于Pyterfly

双情节在单个图上切换-pPython

如何在WTForm中使用back_plumates参考brand_id?

Asyncio与队列的多处理通信-仅运行一个协程

从收件箱获取特定列中的重复行

每个组每第n行就有Pandas

Snap 7- read_Area用于类似地址的变量

如何在telegram 机器人中发送音频?

Python中使用Delivercio进行多个请求

使用argsorted索引子集索引数组

Chatgpt API不断返回错误:404未能从API获取响应

GL pygame无法让缓冲区与vertextPointer和colorPointer一起可靠地工作

如何在BeautifulSoup中链接Find()方法并处理无?

大小为M的第N位_计数(或人口计数)的公式

在vscode上使用Python虚拟环境时((env))

如何在turtle中不使用write()来绘制填充字母(例如OEG)

在Python 3中,如何让客户端打开一个套接字到服务器,发送一行JSON编码的数据,读回一行JSON编码的数据,然后继续?

启动带有参数的Python NTFS会导致文件路径混乱

matplotlib图中的复杂箭头形状

找到相对于列表索引的当前最大值列表""