PDA

View Full Version : Ignore mouse click on window activation



shentian
21st June 2009, 12:23
I have an application with a painting area (QGraphicsView). The user can add a graphics object to the area by clicking on it.

If the application window is inactive, the user can click on the main window to activate it. Just in this case, I'd like to ignore the MouseButtonPress event in QGraphicsView, so that no object will be added. So the desired behaviour is:


Click on painting area of inactive window: Activate window
Click on painting area of active window: Add graphics object


Using an event filter, I got the following order of events when clicking on an inactive window:


ApplicationActivated @ app
WindowActivate @ all widgets
MouseButtonPress @ QGraphicsView
MouseButtonRelease @ QGraphicsView


My first idea was to ignore the first MouseButtonPress event after a WindowActivated event. But this will also ignore the first click when the windows has been activated using the keyboard (e.g. Alt-Tab on Windows).

Any suggestions are welcome.

jpn
21st June 2009, 22:32
This is a bit hackish but could work at least on some platforms. :) When GV receives QEvent::WindowActivate, either

post (NOT send) an event to itself
start a single shot timer with zero interval
use signals and slots with Qt::QueuedConnection
use QMetaObject::invokeMethod() with Qt::QueuedConnection
in any case, let the the execution return to the event loop.

If the custom event is received (or the slot is called) before receiving a mouse press event, the window was first activated by tab and then pressed. If a mouse press event is received before the custom event (or the slot getting called), the window was directly activated by mouse press.

shentian
22nd June 2009, 19:08
Thanks a lot for your advice, now it was quite easy.

As you suggested, I post an event when I recieve WindowActivate, and I ignore the mouse release if my custom event occurs between mouse press and mouse release.

If the window is activated by a mouse click, the events are:

WindowActivate (post ActivatedUserEvent here)
MouseButtonPressed (already in Queue)
ActivatedUserEvent (my custom event)
MouseButtonReleased

If the window is activated by Tab, the events are

WindowActivate (post ActivatedUserEvent here)
ActivatedUserEvent (my custom event)
MouseButtonPressed
MouseButtonReleased


The code looks like this:



bool MyGraphicsView::event(QEvent* event)
{
switch (event->type())
{
case QEvent::WindowActivate:
QCoreApplication::postEvent(this, new QEvent(ActivatedUserEvent));
break;
case Private::ActivatedUserEvent:
ignoreNextMouseRelease = true;
break;
default:
break;
}
return QGraphicsView::event(event);
}

void MyGraphicsView::mousePressEvent(QMouseEvent* event)
{
QGraphicsView::mousePressEvent(event);
ignoreNextMouseRelease = false;
}

void MyGraphicsView::mouseReleaseEvent(QMouseEvent* event)
{
if (ignoreNextMouseRelease)
{
ignoreNextMouseRelease = false;
return;
}
QGraphicsView::mouseReleaseEvent(event);
}