Search code examples
c++qtqtabwidgetqtabbar

How to use an event handler to detect clicking on the empty space after tab bar?


I have a QTabWidget, and I need to trigger an event when i press the area on the tab widget where you normally would see the tab name, accept its an empty space with no tab.

Clicking the red area should trigger an event:

i want to click the red area to trigger an event

Here is how the result should look like:

here is a gif of what i am talking about


Solution

  • You could install an event filter on your QTabWidget, and use QMouseEvent position to detect if it's on the empty space after the tab bar, and add tabs there.

    There are many ways you can detect that, here's one of them:

    #include <QObject>
    #include <QDebug>
    #include <QEvent>
    #include <QMouseEvent>
    #include <QTabWidget>
    #include <QTabBar>
    
    class myEventFilter : public QObject
    {
        Q_OBJECT
    
    public:
        myEventFilter (QObject *parent = nullptr) {}
    
    protected:
        bool eventFilter(QObject * obj, QEvent * event) override
        {
            //check if event is a mouse button press
            if(event->type() == QEvent::MouseButtonPress)
            {
                QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
                //obj is the object that has the event filter installed on
                //here it is a QTabWidget, you can get it like this
                QTabWidget *tabWidget = static_cast<QTabWidget *>(obj);
    
                //here is where you can have multiple ways to check mouse event position
                //you can change it however it suits you
                //but be sure it works
                if(mouseEvent->position().toPoint().x() > tabWidget->tabBar()->width() &&
                   mouseEvent->position().toPoint().y() < tabWidget->tabBar()->height())
                {
                    //add tabs here
                    tabWidget->addTab(new QWidget(),"tab");
                }
            }
    
            return QObject::eventFilter(obj, event);
        }
    };
    

    Here's how it looks, I'm clicking on different areas to test that it only adds a tab when clicked on the space after the tab bar:

    enter image description here

    Notes:

    • If you install the event filter on the tab widget, tab bar will not get mouse press events.
    • You can use QCursor::pos() instead of QMouseEvent, but you'll need to map positions.
    • On Waterfox, a new tab is added on mouse double click, which would be more convenient in case of a misclick.