QTabWidget是一个复合小部件,由QTabBar和QStackedWidget组成.
最重要的是,它覆盖了布局管理所需的基本方面,如sizeHint()
、minimumSizeHint()
和sizePolicy()
.
您不能只切换选项卡栏的可见性(也不能切换堆叠的小部件内容):
- 正如你已经发现的那样,隐藏QTabWidget并显示选项卡栏基本上是无效的,因为父控件的可见性具有优先级:对nested子控件(没有
Qt.Window
窗口标志的QWidget)调用show()
或setVisible(True)
只会使其在父控件显示时可见;
- 试图隐藏堆叠的小部件是无关紧要的,因为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
用于完全"隐藏"选项卡页的内容,并将忽略任何先前或进一步的显式调用;如果需要使用该属性,则必须实现另一个属性,该属性管理显式设置的值和由可见性切换设置的内部值;