[Interest] Prevent right click on specific QTabWidget tab from emitting currentChanged(int) signal

Murphy, Sean smurphy at walbro.com
Thu Apr 17 17:27:00 CEST 2014


I'm trying to duplicate the functionality of how many applications handle tabs where the last tab is treated as a special case and is used solely to create new tabs.  So when my widget launches it looks like:
\ Tab 1 /\ + /
With "Tab 1" set as the current index.  Left clicking on the '+' will add a new tab, "Tab 2", and sets "Tab 2" as the current index, like so:
\ Tab 1 /\ Tab 2 /\ + /

To achieve this, I've connected the currentChanged(int index) signal to a slot that checks to see if the current index is the last index, and if so it adds a new tab, and sets the newly created one as current.  If any other tab is the current index, the slot does nothing.  Here's the code for the slot:
void customTabWidget::slotTabBarClicked(int index)
{
    if (index != (count() - 1))
    {
        // if it's not the last one, we don't need to do anything
        return;
    }

    // if it's the last tab, we add a new tab
    slotAddTab();
}
This works great when the user left-clicks on the '+' tab.

I've also added a contextual menu that allows the user to rename or delete a tab by right clicking one of the tabs.  I'm handling that in mousePressEvent().  This functionality should work for all tabs EXCEPT the final tab; the user should never be able to rename or delete the '+' tab, since it's a special case.  In mousePressEvent(), I'm attempting to detect which index the user right clicked on so that I can rename or delete the correct tab.  Here's the code for mousePressEvent:
void customTabWidget::mousePressEvent(QMouseEvent *event)
{
    QTabWidget::mousePressEvent(event);
    if (event->button() == Qt::RightButton)
    {
        for (int i=0; i < tabBar()->count()-1; i++)
        {
            QPoint clickPos = mapToGlobal(event->pos());
            if (tabBar()->tabRect(i).contains(tabBar()->mapFromGlobal(clickPos)))
            {
                qDebug("Tab count %d, right click on %d", tabBar()->count(), i);
                setCurrentIndex(i);
                slotShowContextualMenu(clickPos);
            }
        }
    }
}

Since there's no reason to show that contextual menu on the '+' tab, I'd like to disable the right click functionality just on the last tab, which I'm trying to do in the mousePressEvent for loop, by only looping to bar->count() - 1.  But the problem I'm having is that right-clicking on the '+' tab emits currentChanged(int) BEFORE mousePressEvent() is called, so a new tab is being created in slotTabBarClicked(), so before the user right clicks, count() is 2, current index is 0, and the '+' is on index 1.  Once the user right clicks on the '+' tab, by the time we get to mousePressEvent(), count() is 3, current index is 1, and the '+' tab is at index 2. So the mapping doesn't work and I end up displaying a contextual menu on the newly created "Tab 2", even though the user right-clicked on the '+' tab.

The behavior I want is right-clicking on the '+' should do nothing; it shouldn't add a new tab, it shouldn't show a contextual menu.

What am I missing?  Or how should I be trying to do this?  If there was a separate signal for left vs. right clicks, it'd be easy.  But I don't see a way to easily detect in slotTabBarClicked(int) that it was a right-click that caused currentChanged(int) to be emitted...

Sean

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.qt-project.org/pipermail/interest/attachments/20140417/602abbb5/attachment.html>


More information about the Interest mailing list