Will Da Silva
Will Da Silva

Reputation: 7040

Select tab text in QTabBar

How can the text of a tab in a QTabBar be selected using the mouse?

The text within a QLabel can be selected as described here: Make QLabel text selectable?, but I haven't found a similar with to do this for QTabBar tab text.

The documentation for QTabBar can be found here: https://doc.qt.io/qt-5/qtabbar.html. It mentions "select" several times, but none of those instances have to do with selecting text. Rather, they all have to do with selecting the tabs themselves.

Upvotes: 1

Views: 531

Answers (1)

jpo38
jpo38

Reputation: 21544

Qt does not natively propose to make QTabBar text selectable.

However, they let you add your own widgets to the tab itself using QTabBar::setTabButton. Then, you can create the tab with no title (""), and then add a QLabel with your title and make it be selectable.

Note that clicking the QLabel itself does not change current tab, you'll need to handle that manually (done in the sample code below).

Here is a sample code that works (text of both active and inactive tabs can be selected):

#include <QApplication>
#include <QMainWindow>
#include <QTabWidget>
#include <QTabBar>
#include <QLabel>

#include <map>

class MainFrame : public QMainWindow
{
public:
    MainFrame()
    {
        tabWidget = new QTabWidget( this );
        setCentralWidget( tabWidget );

        addSelectableTab( new QLabel( "Hello World", tabWidget ), "foo" );
        addSelectableTab( new QLabel( "Hello World", tabWidget ), "bar" );
    }

    void addSelectableTab( QWidget* widget, const QString& title )
    {
        int index = tabWidget->addTab( widget, "" );

        QLabel* titleLabel = new QLabel( title );
        titleLabel->setTextInteractionFlags( Qt::TextSelectableByMouse );
        tabWidget->tabBar()->setTabButton( index, QTabBar::RightSide, titleLabel );

        tabLabels[titleLabel] = index;
        titleLabel->installEventFilter( this );
    }

    bool eventFilter(QObject *obj, QEvent *event) override
    {
        /** When using QLabel as tab title, current tab can only be changed by clicking outside
         *  the label...so let's detect when user clicked inside the label and then change current tab!
         */
        if ( event->type() == QEvent::MouseButtonRelease )
        {
            auto found = tabLabels.find( dynamic_cast<QLabel*>( obj ) );
            if ( found != tabLabels.end() )
            {
                if ( !found->first->hasSelectedText() )
                {
                    // suppose user clicked the label
                    tabWidget->setCurrentIndex( found->second );
                    return true;
                }
            }
        }

        return QMainWindow::eventFilter( obj, event );
    }

private:
    QTabWidget* tabWidget;

    // this is to know what tab should be activated when a label is clicked
    // you may get rid of that by using QTabBar::tabButton to identify what
    // tab a QLabel is related to
    std::map<QLabel*,int> tabLabels;
};

int main( int argc, char* argv[] )
{
    QApplication app(argc,argv);

    MainFrame wnd;
    wnd.show();
    return app.exec();
}

And now tab titles are selectable:

enter image description here

Upvotes: 4

Related Questions