c++qtqwidgetqt6qtabwidget

How to display a tab widget's corner widget on the left/right side


I have a QTabWidget with its tabs on the West, then I tried to add a corner widget to it, but it did not appear. If I set the tabs position to North or South, the corner widget gets displayed, but not on the side.

QWidget *w = new QWidget();
QTabWidget *t = new QTabWidget(w);

w->setMinimumSize(800,600);

t->addTab(new QWidget(),"Tab");
t->addTab(new QWidget(),"Tab");
t->addTab(new QWidget(),"Tab");
t->addTab(new QWidget(),"Tab");

t->setTabPosition(QTabWidget::TabPosition::East);

t->setGeometry(100,100,400,400);

QPushButton *button = new QPushButton("Button");

//for debugging purposes
button->setObjectName("ss");

//for debugging purposes
t->setStyleSheet("background: red");
button->setStyleSheet("background: blue;");

//for debugging purposes
t->setCornerWidget(button1,Qt::TopLeftCorner);
//t->setCornerWidget(button1,Qt::TopRightCorner);
//t->setCornerWidget(button1,Qt::BottomLeftCorner);
//t->setCornerWidget(button1,Qt::BottomRightCorner);
    
w->show();

//for debugging purposes
//qDebug()<<button->geometry();
//button->setGeometry(0,0,50,50);

//for debugging purposes
button->connect(button,&QPushButton::clicked,[](){qDebug()<<"corner widget click?";});

I tried to use all 4 corners, and right corners have no effect, but the left causes an empty space before the tabs, here's how it looks, the empty space is at the top right corner:

Offset before tabs

I tried to set the stylesheet of the button I'm using as a corner widget, so that it might appear if hidden, but resulted in nothing.

I checked the button's geometry, and it got QRect(0,0 0x0), and that is after using show(). So I tried to set its geometry, but resulted in nothing as well (but the geometry got updated correctly), the button is still not displayed.

I also tried to check for the button whereabouts by connecting its clicked() signal to a qDebug(), I clicked all over the widget and got no output.

QTabWidget::setCornerWidget:

Note: Corner widgets are designed for North and South tab positions; other orientations are known to not work properly.

I get from that, that it's not entirely impossible to get it to work.


Solution

  • From the Qt documentation (qt6), QTabWidget::setCornerWidget: says:

    Note: Corner widgets are designed for North and South tab positions; other orientations are known to not work properly.

    That means they do work, but are messy to and inconvenient to use.

    Here's a way to use QTabWidget corner widget on the side:

    As already noted in the question, setting a corner widget while tabs position is West or East, causes a small gap before the tabs without anything appearing there.

    But if you set QTabWidget's corner widget minimum size, it will appear, which solves a problem but causes another, because now I need to calculate that size myself, or make room for my corner widget.

    QTabWidget *t = new QTabWidget();
    
    //I needed the stacked widget so I can use its geometry to calculate the empty corner size
    QStackedWidget *stack_widget = t->findChild<QStackedWidget*>("qt_tabwidget_stackedwidget");
    t->setMinimumSize(800,600);
    t->addTab(new QWidget(),"Tab1");
    t->addTab(new QWidget(),"Tab2");
    t->addTab(new QWidget(),"Tab3");
    t->addTab(new QWidget(),"Tab4");
    t->setTabPosition(QTabWidget::TabPosition::West);
    
    QToolButton *button1 = new QToolButton();
    button1->setIcon(QIcon(":/icons/collapse.png"));
    
    t->setCornerWidget(button1,Qt::TopLeftCorner);
    
    t->show();
        
    //width is equal to where the stack widget starts (x coordinate)
    //height is equal to where the tab bar starts (y coordinate)
    //I subtracted 1 from stackwidget's x because it simply looked better
    t->cornerWidget(Qt::TopLeftCorner)->setMinimumSize(stack_widget->geometry().x()-1,
                                                       t->tabBar()->geometry().y());
    

    Corner widget appeared

    If you need more space for the corner widget, you'll need to move the tab bar, because corner widget will cover it, you can do that using stylesheets.

    See: Qt Style Sheets Examples: Customizing QTabWidget and QTabBar.

    Example:

    t->setStyleSheet("QTabWidget::tab-bar "
                     "{"
                         "top: 50px;" /* push down by 50px */
                     "}");
    

    Here's how it looks with that being the only addition and change to my MRE:

    Extended tab widget corner widget


    Suggestion: QTabWidget::paintEvent might be a better solution.