[⇐ К полному списку статей / Content] ID: 20141101_1855-qtabhide

Qt: сокрытие вкладок в QTabWidget

В стандартном виджете для организации вкадок в Qt нет возможности сокрытия отдельных вкладок (show/hide). Интернете не нашёл решения – предлагают сложные пути: временно удалять вкладки или переделывать виджет.

Кажется мне удалось найти простое решение, оно годится если вы не используйте «задисейбленные» («серые», «режим только-чтение») вкладки (disabled). Кстати, для сокрытых вкладок это и не имеет смысла.

Идея в том, что бы ставить режим disabled вкладкам, которые надо скрыть, а для маскировки вкладок использовать приём задание стиля с нулевым размером вкладки. Причём при установке режима disabled виджет сам автоматически переключит активную вкладку, так что проблем с показом содержимого скрытой вкладки нет!

Нужный стиль устанавливается так:

#include "qtesttabwidget.h"

#include <QTabBar>

QTestTabWidget::QTestTabWidget() // наследник QTabWidget
{
setStyleSheet();
}


void
QTestTabWidget::setStyleSheet()
{

tabBar()->setStyleSheet(
"QTabBar::tab:disabled { width: 0; height: 0; right: 1px; }"
// ??? border-style: none; margin-left: 1px;
);
}

У меня чуть-чуть кривовато выглядит последняя граница последней видимой вкладки, если она не активная и если скрыть самую последнюю. Вероятно тут можно как-то добиться идеального отображения и в этом случае поколдовав с полями, смещениями итд в стиле. Если кто разберётся с этим — пожалуйста, отправьте мне результат!
Состояние «:disabled» вроде не документировано для QTabBar::tab, однако у меня в Qt 4.5.0 это работает, думаю, и в новых версиях тоже должно.

Вот тестовая программа (код класса главного окна QMainWindow), которая динамически скрывает/показывает вкладки:

#include "mainwindow.h"

#include <QCheckBox>
#include <QVBoxLayout>
#include <QHBoxLayout>

#include <QLabel>
#include <QTabBar>


MainWindow::MainWindow(QWidget *parent)
:
QMainWindow(parent)
{

QWidget* w = new QWidget(this);
QVBoxLayout* vl = new QVBoxLayout( w );
QHBoxLayout* hl = new QHBoxLayout;
vl->addLayout( hl );
vl->addWidget( m_tabs = new QTestTabWidget );

for
(int i=0; i<3; i++)
{

const
QString num = QString::number(i+1);
QCheckBox* ch = new QCheckBox( QString("Show tab#")+num );
ch->setChecked(true);
hl->addWidget(ch);
m_map.insert( ch, m_tabs->addTab(new QLabel( QString("Label ")+num ), QString("tab#")+num ) );
// ^ QMap<QCheckBox*,int> m_map;
connect( ch, SIGNAL(stateChanged(int)), this, SLOT(stateChanged(int)) );
}


setCentralWidget( w );
}


void
MainWindow::stateChanged( int state )
{

QCheckBox *p = qobject_cast<QCheckBox*>( sender() );
if
( p==NULL||!m_map.contains(p) )
return
;

m_tabs->setTabEnabled( m_map[p], state!=Qt::Unchecked );
m_tabs->setStyleSheet();
}

PS Наткнулся на одну "кривость" (использовалось Qt 4.5.0 - древнее! возможно в новых это исправлено): если использовать виджеты на вкладках (в моём случае это раскрывающийся список на том месте, где обычно кнопка закрытия вкладки):

QComboBox *ysel = new YearInTabComboBox( years ); // наследник QComboBox
tabBar()->setTabButton(num, QTabBar::RightSide, ysel); // установка виджета во вкладку num справа от подписи
то при сокрытии вкладки этим методом эти виджеты у меня должным образом не скрываются и могут образовать "стопку" уложившись рядом. (С кнопками закрытия, наверное, будет то же самое). Впрочем, на сколько я представляю, во-первых, мало кто ставит виджеты во вкладки, а во-вторых это можно обойти, дополнительно скрывая и показывая такие виджеты на соответствующих вкладках обычным способом (методами show/hide).

Original: http://lj.rossia.org/users/shestero/139036.html
Tags: c++, gui, it, qt, qtabwidget
[⇐ К полному списку статей / Content]


© http://netdat.ru — Bulletin Publishing System, 2011-2016.