Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

QTabWidget tab context menu

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?

like image 446
deuces Avatar asked Sep 30 '09 03:09

deuces


3 Answers

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.
like image 92
Frerich Raabe Avatar answered Oct 24 '22 07:10

Frerich Raabe


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()
like image 44
Hadi Navapour Avatar answered Oct 24 '22 08:10

Hadi Navapour


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));
    }
like image 1
Dragon Avatar answered Oct 24 '22 07:10

Dragon