I have a QTabWidget with a few tabs of a fixed size. I'd like to place the tab widget in a layout to make it stretch with the main window, but this results in a scroller appearing to the right of the tabs when I shrink it or empty space on the right of the tabs when I stretch it out. I'd like the tabs to automatically fill the entire length of QTabWidget.
2 Answers
The tab widget very strictly ensures that the QTabBar inside is created with a minimum size. However, all is not lost.
Because we do have access to the QTabBar and the tabs inside it, there is something we can do. I found the following answer which proposes a straightforward workaround.
Basically using a style sheet we set the width of the tabs based on the current width of the tab widget. The trick then, is to ensure that if the width of the tab widget changes that we re-do this calculation.
The suggested way to do this was with an EventFilter. Basically all that is needed is the following class:
// On resize events, reapply the expanding tabs style sheet
class ResizeFilter : public QObject
{
QTabWidget *target;
public:
ResizeFilter(QTabWidget *target) : QObject(target), target(target) {}
bool eventFilter(QObject *object, QEvent *event)
{
if (event->type() == QEvent::Resize)
{
// The width of each tab is the width of the tab widget / # of tabs.
target->setStyleSheet(QString("QTabBar::tab { width: %1px; } ")
.arg(target->size().width()/target->count()));
}
return false;
}
};
Then for your particular QTabWidget, just install the event handler:
ui.tabWidget->installEventFilter(new ResizeFilter(ui.tabWidget));
Presto!
Although there is one thing I would add to the answer. Because the tabs are given the same size regardless of their display text, you may want to ensure that you set the "elideMode" property on the QTabWidget to handle cases where there is not enough room in the tab to show the whole title. This will truncate the text to fit and add a "...".