10

I have already created the tabs in QtabWidget. My main purpose is to hide tabs and show it when a button is pressed. I don't want to remove and add tabs every time. I want to hide it and show when required.

I have tried to do this:

self.tab.hide()

But this doesn't work. Here is the code for current GUI:

    MainWindow.setObjectName(_fromUtf8("MainWindow"))
    MainWindow.resize(680, 425)
    self.centralwidget = QtGui.QWidget(MainWindow)
    self.centralwidget.setObjectName(_fromUtf8("centralwidget"))
    self.verticalLayout_3 = QtGui.QVBoxLayout(self.centralwidget)
    self.verticalLayout_3.setObjectName(_fromUtf8("verticalLayout_3"))
    self.tabWidget = QtGui.QTabWidget(self.centralwidget)
    self.tabWidget.setObjectName(_fromUtf8("tabWidget"))
    self.tab = QtGui.QWidget()
    self.tab.setObjectName(_fromUtf8("tab"))
    self.verticalLayout_4 = QtGui.QVBoxLayout(self.tab)
    self.verticalLayout_4.setObjectName(_fromUtf8("verticalLayout_4"))
    self.pushButton_3 = QtGui.QPushButton(self.tab)
    self.pushButton_3.setObjectName(_fromUtf8("pushButton_3"))
    self.verticalLayout_4.addWidget(self.pushButton_3)
    self.tabWidget.addTab(self.tab, _fromUtf8(""))
    self.tab_2 = QtGui.QWidget()
    self.tab_2.setObjectName(_fromUtf8("tab_2"))
    self.verticalLayout_5 = QtGui.QVBoxLayout(self.tab_2)
    self.verticalLayout_5.setObjectName(_fromUtf8("verticalLayout_5"))
    self.treeWidget = QtGui.QTreeWidget(self.tab_2)
    self.treeWidget.setObjectName(_fromUtf8("treeWidget"))
    self.verticalLayout_5.addWidget(self.treeWidget)
    self.tabWidget.addTab(self.tab_2, _fromUtf8(""))
    self.verticalLayout_3.addWidget(self.tabWidget)
    MainWindow.setCentralWidget(self.centralwidget)
    self.menubar = QtGui.QMenuBar(MainWindow)
    self.menubar.setGeometry(QtCore.QRect(0, 0, 680, 21))
    self.menubar.setObjectName(_fromUtf8("menubar"))
    MainWindow.setMenuBar(self.menubar)
    self.statusbar = QtGui.QStatusBar(MainWindow)
    self.statusbar.setObjectName(_fromUtf8("statusbar"))
    MainWindow.setStatusBar(self.statusbar)
    self.dockWidget = QtGui.QDockWidget(MainWindow)
    self.dockWidget.setObjectName(_fromUtf8("dockWidget"))
    self.dockWidgetContents = QtGui.QWidget()
    self.dockWidgetContents.setObjectName(_fromUtf8("dockWidgetContents"))
    self.verticalLayout = QtGui.QVBoxLayout(self.dockWidgetContents)
    self.verticalLayout.setObjectName(_fromUtf8("verticalLayout"))
    self.pushButton = QtGui.QPushButton(self.dockWidgetContents)
    self.pushButton.setObjectName(_fromUtf8("pushButton"))
    self.verticalLayout.addWidget(self.pushButton)
    self.dockWidget.setWidget(self.dockWidgetContents)
    MainWindow.addDockWidget(QtCore.Qt.DockWidgetArea(1), self.dockWidget)
    self.dockWidget_2 = QtGui.QDockWidget(MainWindow)
    self.dockWidget_2.setObjectName(_fromUtf8("dockWidget_2"))
    self.dockWidgetContents_2 = QtGui.QWidget()
    self.dockWidgetContents_2.setObjectName(_fromUtf8("dockWidgetContents_2"))
    self.verticalLayout_2 = QtGui.QVBoxLayout(self.dockWidgetContents_2)
    self.verticalLayout_2.setObjectName(_fromUtf8("verticalLayout_2"))
    self.pushButton_2 = QtGui.QPushButton(self.dockWidgetContents_2)
    self.pushButton_2.setObjectName(_fromUtf8("pushButton_2"))
    self.verticalLayout_2.addWidget(self.pushButton_2)
    self.lineEdit = QtGui.QLineEdit(self.dockWidgetContents_2)
    self.lineEdit.setObjectName(_fromUtf8("lineEdit"))
    self.verticalLayout_2.addWidget(self.lineEdit)
    self.dockWidget_2.setWidget(self.dockWidgetContents_2)
    MainWindow.addDockWidget(QtCore.Qt.DockWidgetArea(1), self.dockWidget_2)
Leo
  • 436
  • 1
  • 3
  • 14

2 Answers2

21

There is no convenient method to hide a tab. You have two workarounds:

  1. Use removeTab and insertTab. You need to keep a reference to the tabs that you removed to be able to re-insert them later (and their indexes, so that they reappear on the same spot).

  2. Use setTabEnabled to enable (=show) and disabled (=hide) tabs. When a tab is disabled, it's usually grayed out, but you can use style sheets to hide the tab instead:

    self.setTabEnabled(tabIndex,True/False) #enable/disable the tab
    # set the style sheet
    self.setStyleSheet("QTabBar::tab::disabled {width: 0; height: 0; margin: 0; padding: 0; border: none;} ")
    

I tested the second option, and had an issue when showing a previously hidden tab: the view was not repainted properly (even after calling update or repaint). Turns out the style sheet is not automatically updated and it still draws the tab as if it was disabled.
Calling setStyleSheet after every setTabEnabled(index,True) fixes the issue. It forces the style sheet to be recompute.

Mel
  • 5,837
  • 10
  • 37
  • 42
  • I tested this before, and instead of setting the StyleSheet every time, you can set it once, and then reapply it every time using polish/unpolish. eg. something like `self.style()->unpolish(self)`; then `self-style()->polish(self);` – Enthus3d Oct 18 '19 at 19:04
  • 2
    or you can set it in Qt Designer. – Chris P May 15 '22 at 20:01
  • This applies to QT before 5.15, in QT 5.15 and above there is direct support (see user13672091's answer for details). – Paul Hutchinson Nov 21 '22 at 01:20
12

Since PyQT version 5.15 you can use setTabVisible(index, visible). It will hide the tab at given index. When you will pass visible as true, it will show that tab and index will remain the same.

Paul Hutchinson
  • 1,578
  • 15
  • 21
  • https://doc.qt.io/qt-5/qtabwidget.html#:~:text=void%20QTabWidget%3A%3AsetTabVisible(int%20index%2C%20bool%20visible) – xiaoyifang Mar 02 '22 at 06:09