QTabWidget tab context menu
Asked Answered
M

4

10

I need to display a context menu whenever a tab is clicked on and it needs to react to that specific tab. Is there any way to do this without subclassing it?

Mckenna answered 30/9, 2009 at 3:12 Comment(1)
qtcentre.org/threads/… (comment #5) works great!Aurel
E
5

Easy way, but possibly not precisely what you need:

  1. Connect to the 'currentChanged' signal of your QTabWidget
  2. In the slot which is connected to the signal, create a QMenu and populate it as needed
  3. Finally, in the slot which is connected to the signal, call QMenu::exec( QCursor::pos() )

This will get a function called whenever the tab is changed (not necessarily clicked) and spawn a menu at the current mouse position.

Complicated way, which exactly does what you describe:

  1. Call QObject::installEventFilter on your QTabWidget, so that all the events on your QTabWidget are redirected to your own object.
  2. In your own object, reimplement QObject::customEvent and handle all QMouseEvent events.
  3. Populate a QMenu as needed and call QMenu::exec at the position of the QMouseEvent you're handling.
Evita answered 30/9, 2009 at 8:52 Comment(1)
Your first easy solution does not works as he wants. Context menu will not be display is mouse click is done on current tab. The only solution seems to be the your second one.Booking
I
3

create a QMenu:

m_menu = new QMenu;

add your actions to menu.

Create a slot to be called when context menu requested on tab bar:

connect(m_tabWidget->tabBar(), &QTabBar::tabBarClicked, this, &MyClass::on_contextMenuRequested);

In the slot, show the menu. Definition of slot:

void MyClass::on_contextMenuRequested(int tabIndex)
{
    m_menu->popup(QCursor::pos());
}

If you need index of current tab in another function, use following:

m_tabWidget->tabBar()->currentIndex()
Illuminate answered 17/5, 2019 at 21:13 Comment(0)
C
2

As per the comment by @Petrzio Berkerle, the solution found at https://www.qtcentre.org/threads/16703-QTabBar-Context-menu-on-tab?p=84057#post84057 worked very well for me. (Actually, it was the only one that worked at all.)

The code from the post there (by "spirit"):

    ...
    m_tabBar = new QTabBar();
    m_tabBar->addTab(tr("OK"));
    m_tabBar->addTab(tr("NO"));
    m_tabBar->addTab(tr("IGNORE"));
    m_tabBar->setContextMenuPolicy(Qt::CustomContextMenu);
     
    connect(m_tabBar, SIGNAL(customContextMenuRequested(const QPoint &)), SLOT(showContextMenu(const QPoint &)));
    ...
     
    void Test::showContextMenu(const QPoint &point)
    {
        if (point.isNull())
            return;
     
        int tabIndex = m_tabBar->tabAt(point);
        QMenu menu(this);
        if (!tabIndex)
            menu.addAction(tr("OK"));
        else if (tabIndex == 1)
            menu.addAction(tr("NO"));
        else if (tabIndex == 2)
            menu.addAction(tr("IGNORE"));
     
        menu.exec(m_tabBar->mapToGlobal(point));
    }
Complected answered 20/8, 2021 at 14:38 Comment(0)
B
0

I think you need to create your own class that inherits from QTabWidget and override the MousePressEvent(QMouseEvent) protected function in which you can create your context menu on right click.

Booking answered 30/9, 2009 at 8:52 Comment(2)
-1 since he specifically asked for a way to achieve what he wants without subclassing QTabWidget.Evita
If he is not familiar with the installEventFilter, the inheritance is an easier way. But let him try your second solution first.Booking

© 2022 - 2024 — McMap. All rights reserved.