Как скрыть вкладку QTabWidget?

Подскажите, как скрыть вкладку.

Не помогает ни hide(),ни setVisible()

Только удалить можно через deleteLater()

Но это мне не подходит. Подскажите другие способы решения проблемы. Заранее спасибо.

Пример удаления:

Self.ui.tab_7.deleteLater()

Ответы (3 шт):

Автор решения: gil9red

Действительно, в API виджета нет такого метода, хотя он был бы полезным.

Поиск решения привел на форум и там был предложен трюк с QSS:

There's no built in method like setTabVisible(false) unfortunately. The workaround I often use is applying this stylesheet: @ QTabWidget::tab:disabled { width: 0; height: 0; margin: 0; padding: 0; border: none; } @ and then using setTabEnabled(false). Of course if you also need disabled (grayed out) tabs this method won't work.

Суть в том, что при состояние disabled прятать вкладку убрав ей размеры, отступы и границы. В ответе, кст, есть небольшая опечатка не QTabWidget::tab:disabled, а QTabBar::tab:disabled

Реализация:

from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QTabWidget, QPushButton


class MainWindow(QWidget):
    def __init__(self):
        super().__init__()

        self.tab_widget = QTabWidget()
        self.tab_widget.tabBar().setStyleSheet("""
            ::tab:disabled { width: 0; height: 0; margin: 0; padding: 0; border: none; }
        """)

        self.tab_widget.addTab(QPushButton('Tab 1'), 'Tab 1')
        self.tab_widget.addTab(QPushButton('Tab 2'), 'Tab 2')
        self.tab_widget.addTab(QPushButton('Tab 3'), 'Tab 3')

        self.button = QPushButton('Show/Hide tab #2')
        self.button.setCheckable(True)
        self.button.setChecked(True)
        self.button.clicked.connect(lambda checked: self.tab_widget.setTabEnabled(1, checked))

        main_layout = QVBoxLayout()
        main_layout.addWidget(self.button)
        main_layout.addWidget(self.tab_widget)

        self.setLayout(main_layout)


if __name__ == '__main__':
    app = QApplication([])

    mw = MainWindow()
    mw.show()

    app.exec()

Указываем стиль конкретно для tabBar() того виджета self.tab_widget: self.tab_widget.tabBar().setStyleSheet

Спрятали вторую вкладку:

введите сюда описание изображения

→ Ссылка
Автор решения: S. Nick

Как вариант

from PyQt5.Qt import *


class MainWindow(QWidget):
    def __init__(self):
        super().__init__()

        self.tab_widget = QTabWidget()

        self._dictTabs = [
            ['Tab 1', QPushButton('Tab 1')],
            ['Tab 2', QPushButton('Tab 2')],
            ['Tab 3', QPushButton('Tab 3')],
        ]

        for k, v in self._dictTabs: #.items():
            self.tab_widget.addTab(v, k)

        self.comboBox = QComboBox()
        self.comboBox.setFixedHeight(50)
        self.comboBox.addItems(['Выберите вкладку, кот. не показывать\n(показать все вкладки)', 
                                'Tab 1', 'Tab 2', 'Tab 3'])
        self.comboBox.currentIndexChanged.connect(self.onCurrentIndexChanged)

        self.main_layout = QVBoxLayout()
        self.main_layout.addWidget(self.comboBox)
        self.main_layout.addWidget(self.tab_widget)
        self.setLayout(self.main_layout)

    @pyqtSlot(int)
    def onCurrentIndexChanged(self, index):
        self.tab_widget.hide()
        self.tab_widget = QTabWidget() 
        if index == 0:
            for k, v in self._dictTabs: 
                self.tab_widget.addTab(v, k) 
        else:
            for k, v in self._dictTabs:                   
                if k != f'Tab {index}' and index:
                    self.tab_widget.addTab(v, k)
        self.tab_widget.show()
        self.main_layout.addWidget(self.tab_widget)


if __name__ == '__main__':
    app = QApplication([])
    app.setFont(QFont("Times", 12, QFont.Bold))
    mw = MainWindow()
    mw.resize(300, 200)
    mw.show()
    app.exec()

введите сюда описание изображения

введите сюда описание изображения


Update

По совету компетентных товарищей @gil9red

Мб не пересоздавать объект QTabWidget, а очищать его вкладки (doc.qt.io/qt-5/qtabwidget.html#clear) и после заново заполнять?


from PyQt5.Qt import *


class MainWindow(QWidget):
    def __init__(self):
        super().__init__()

        self.tab_widget = QTabWidget()

        self._dictTabs = [
            ['Tab 1', QPushButton('Tab 1')],
            ['Tab 2', QPushButton('Tab 2')],
            ['Tab 3', QPushButton('Tab 3')],
        ]

        for k, v in self._dictTabs: #.items():
            self.tab_widget.addTab(v, k)

        self.comboBox = QComboBox()
        self.comboBox.setFixedHeight(50)
        self.comboBox.addItems(['Выберите вкладку, кот. не показывать\n(показать все вкладки)', 
                                'Tab 1', 'Tab 2', 'Tab 3'])
        self.comboBox.currentIndexChanged.connect(self.onCurrentIndexChanged)

        self.main_layout = QVBoxLayout()
        self.main_layout.addWidget(self.comboBox)
        self.main_layout.addWidget(self.tab_widget)
        self.setLayout(self.main_layout)

    @pyqtSlot(int)
    def onCurrentIndexChanged(self, index):
        self.tab_widget.clear()                                    # +++
#        self.tab_widget.hide()                                    # ---
#        self.tab_widget = QTabWidget()                            # ---
        if index == 0:
            for k, v in self._dictTabs: 
                self.tab_widget.addTab(v, k) 
        else:
            for k, v in self._dictTabs:                   
                if k != f'Tab {index}' and index:
                    self.tab_widget.addTab(v, k)
#        self.tab_widget.show()                                    # ---   
#        self.main_layout.addWidget(self.tab_widget)               # ---


if __name__ == '__main__':
    app = QApplication([])
    app.setFont(QFont("Times", 12, QFont.Bold))
    mw = MainWindow()
    mw.resize(300, 200)
    mw.show()
    app.exec()
→ Ссылка
Автор решения: Alexander Chernin

Грех не присоединиться к такой честной компании с третьим вариантом (немного инициализации взял у S.Nick).

Ключевой момент - использование функции QTabWidget.removeTab(index):

class MainWindow(QWidget):
    def __init__(self):
        super().__init__()

        self.tab_widget = QTabWidget()
        # словарь скрытых табов
        self.hidden_tabs = {}

        self._dictTabs = [
            ['Tab 1', QPushButton('Tab 1')],
            ['Tab 2', QPushButton('Tab 2')],
            ['Tab 3', QPushButton('Tab 3')],
        ]

        for title, widget in self._dictTabs:
            self.tab_widget.addTab(widget, title)
            # инициализируем словарь ключами-заголовками табов
            # можно этого и не делать, но для наглядности
            self.hidden_tabs[title] = None

        # кнопка прятания текущего таба
        self.button_hide_tab = QPushButton('Скрыть текущий таб')
        self.button_hide_tab.clicked.connect(self.__slot_hide_current_tab)
        # кнопка показа всех ранее вкрытых табов
        # можно, конечно, показывать табы по какому-либо условию
        self.button_show_hidden_tabs = QPushButton('Показать все скрытые табы')
        self.button_show_hidden_tabs .clicked.connect(self.__slot_show_tab)


    def __slot_hide_current_tab(self): 
        index = self.tab_widget.currentIndex()
        if index == -1:
            return
        # сохраняем текущий таб в список скрытых
        self.hidden_tabs[title] = self.tab_widget.currentWidget()

        # скрываем таб из tab_widget
        self.tab_widget.removeTab(index)

    def __slot_show_tab(self): 
        # бежим по скрытышам
        for title, widget in self._hidden_tabs:
            # если скрытыш есть, то показываем его, добавляя в конец
            if widget:
                self.tab_widget.addTab(widget, title)
→ Ссылка