PDA

View Full Version : QTabBar - Context menu on tab



gruszczy
26th October 2008, 19:53
I would like to show a context menu, when someone clicks on the tab. It's easy - just intercept signal customContextMenuEvent. But I have no idea, how to get proper tab just from the position of a click and not pop up a context menu, when user clicks somewhere else, than on a tab. Could someone help me on this?

elcuco
26th October 2008, 20:24
Here is what I did here http://code.google.com/p/qtedit4/source/browse/tools/qmdilib/src/qmditabwidget.cpp



bool qmdiTabWidget::eventFilter(QObject *obj, QEvent *event)
{
if (obj != tabBar())
return QObject::eventFilter(obj, event);

if (event->type() != QEvent::MouseButtonPress)
return QObject::eventFilter(obj, event);

// compute the tab number
QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
QPoint position = mouseEvent->pos();
int c = tabBar()->count();
int clickedItem = -1;

for (int i=0; i<c; i++)
{
if ( tabBar()->tabRect(i).contains( position ) )
{
clickedItem = i;
break;
}
}

// just in case
if (clickedItem == -1)
return QObject::eventFilter(obj, event);

switch( mouseEvent->button() )
{
case Qt::LeftButton:
return QObject::eventFilter(obj, event);
break;

case Qt::RightButton:
on_rightMouse_pressed( clickedItem, position );
break;

case Qt::MidButton:
on_middleMouse_pressed( clickedItem, position );
break;

default:
return QObject::eventFilter(obj, event);
}

return true;
}


I assume I would use a binary approach to reduce the time from O(n) to O(log(n)) [where n is the number of tabs), but in such magnitudes this optimization is irrelevant IMHO.

gruszczy
26th October 2008, 22:39
That seems to be exactly what I need. Thanks a lot, love it :)

And yeah, no point in complicated the code with useless optimisation. This is just fine, so I'll just translate it to Python :)

gruszczy
26th October 2008, 23:19
One more thing.



if (obj != tabBar())
return QObject::eventFilter(obj, event);


Any time I click on the tab, it cannot pass through this condition. obj is QTabWidget (a class inheriting from this QTabWidget) instead of tabBar(). Do you have any idea, why it is so? From what I have read about your project, you are using Qt4. Does require doing something more?

spirit
27th October 2008, 07:20
look at this example


...
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));
}


works perfectly.

pbek
3rd July 2020, 13:33
Thanks a lot, @spirit. Works like a charm!