[Interest] Qt::WA_NoMouseReplay? Extra mouse clicks during contextual menus.

John Weeks john at wavemetrics.com
Wed Feb 18 23:48:19 CET 2015


We have code conceptually like this (but more complicated :) --

void MainWindow::mousePressEvent(QMouseEvent *e)
{
	if (hotRect.contains(e->pos()))
	{
		QMenu aMenu("The Menu", 0);
		aMenu.addAction("Action 1");
		aMenu.addAction("Action 2");
		QAction * action = aMenu.exec(e->globalPos());
		if (action)
			qDebug() << "Selection:" << action->text();
		else
			qDebug() << "No selection";
	}
}

The problem is that once the menu is shown, if you click outside the menu in order to cancel the menu, the mouse click is propagated to the widget under the mouse. If it's the widget containing my hotRect, it can put up the menu again.

First question: How can this possibly be useful behavior?

Tracing through Qt source, I found the attribute  WA_NoMouseReplay. I can set a filter on the QMenu and set that attribute on the mouse click:

 bool MainWindow::eventFilter(QObject *obj, QEvent *e)
{
	if (e->type() == QEvent::MouseButtonPress /*|| e->type() == QEvent::MouseButtonRelease*/)
	{
		QMenu * menu = qobject_cast<QMenu *>(obj);
		if (menu)
			menu->setAttribute(Qt::WA_NoMouseReplay, true);
	}

	return false;
}

But the documentation of WA_NoMouseReplay says, "The flag is set by the widget's author and cleared by the Qt kernel every time the widget receives a new mouse event." This suggests that I shouldn't be using this attribute in the way I'm using it.

Second question: Is my filter safe? That is, can I count on this to continue working in the future?

Third question: Is there a better way to prevent the extra mouse click? Or a better way to present my menu?

Thanks!

-John Weeks


More information about the Interest mailing list