PDA

View Full Version : mousePressEvent - Problems handling right and left mouse buttons together



weevil
10th June 2010, 04:48
I have a board widget comprised of a bunch of cell widgets arranged in a grid layout. In the cell class I reimplemented the mouse event functions, but I'm having trouble dealing with clicks on a cell with both the right and left mouse buttons. The cell can recognize when both buttons are pressed, but it receives a prior mousePressEvent with either the right or left mouse button depending on which came first in the multi-button click. I'm not sure if it's possible to avoid this, but I don't want the widget to receive a single mouse button click before the event has both clicks. I also don't want to implement some kind of timer delay that will make my single mouse clicks seem laggy, if I'm expressing that coherently.

Right now my code looks like


void Cell::mousePressEvent( QMouseEvent *event )
{
Qt::MouseButtons mouseButtons = event->buttons();
if( mouseButtons == (Qt::LeftButton | Qt::RightButton) )
{ ... }
else if( mouseButtons == Qt::LeftButton )
{ ... }
else if( mouseButtons == Qt::RightButton )
{ ... }
}

aamer4yu
10th June 2010, 05:27
The cell can recognize when both buttons are pressed, but it receives a prior mousePressEvent with either the right or left mouse button depending on which came first in the multi-button click. I'm not sure if it's possible to avoid this, but I don't want the widget to receive a single mouse button click before the event has both clicks.
I dont think its possible to receive both clicks same time. For you it might seem you clicked both buttons simultaneously, but for computer, which deals in milli seconds, those will be sequential.
What you are talking is kinda multi touch event !

By the why do you need such a case ?

weevil
10th June 2010, 06:12
I dont think its possible to receive both clicks same time. For you it might seem you clicked both buttons simultaneously, but for computer, which deals in milli seconds, those will be sequential.
What you are talking is kinda multi touch event !

By the why do you need such a case ?

If the user presses the left button, for example, and releases it on the widget, the cell changes to a certain state. I don't want the widget to receive the single mouse click's release event when there's another multibutton release event coming. I'm actually confused as to what happens when I have, say, a left mouse button press event being handled, and then the following multibutton event, and then I release the mouse. Do I get two mouseReleaseEvents? If so, what order does the widget's handler execute them? Is there a way to tell and ignore the single button release event? Sorry if I'm not expressing myself well, I don't have a good grasp on Qts event system yet.

aamer4yu
10th June 2010, 06:21
I guess you will need to spy on the events and code your own logic for the multi button event.

tbscope
10th June 2010, 06:22
Events are like a FIFO, first in, first out. When you first click the left button and then the right, the left button event is first and then the right.
When you click both buttons at the same time on your mouse, it depends. You, as a human, can NOT press them at the same time, if you do, it's pure luck. One button will always be first. Which one is a guess.

Now, how to solve this?
You could make use of a timer. For example, the user has 500ms to press both buttons. If both release or press events happen before the timer times out, you could use them as a multi touch event.

weevil
10th June 2010, 06:29
I guess you will need to spy on the events and code your own logic for the multi button event.

I suppose I meant to ask how to do this. I'm looking throuh the documentation trying to find a way to get a list of events in the loop with no luck. I was thinking I could check for two mouse events and cancel or ignore one of them, but there are a ton of QMouseEvents flying around in the que all the time from mouseMoveEvent so even if I could I'm not sure how I'd differentiate those from the events sent to the release event handlers.

weevil
10th June 2010, 06:35
Events are like a FIFO, first in, first out. When you first click the left button and then the right, the left button event is first and then the right.
When you click both buttons at the same time on your mouse, it depends. You, as a human, can NOT press them at the same time, if you do, it's pure luck. One button will always be first. Which one is a guess.

Now, how to solve this?
You could make use of a timer. For example, the user has 500ms to press both buttons. If both release or press events happen before the timer times out, you could use them as a multi touch event.

Then I must be misunderstanding what's going on. I was thinking there were two mouse press events occuring in the scenario I described, where the first is either a left or right button press, and the second event registers both left and right button presses. You make it sound like there's one event that registers a left click say, and the other registers a right click? This doesn't seem to jive with my experimenting and the documenation, by testing if( event->buttons() == (Qt::LeftButton | Qt::RightButton) ), the following block statements are executed.

I had thought of using a timer, but as I said I'd like to find a way to not do that, as it makes the UI seem laggy. It is my fallback plan though.

tbscope
10th June 2010, 06:50
I was thinking there were two mouse press events occuring in the scenario I described, where the first is either a left or right button press, and the second event registers both left and right button presses. You make it sound like there's one event that registers a left click say, and the other registers a right click?

I see what you mean.
You can click the left mouse button and keep it pressed. There will be a left mouse button press event. It might be repeated too when holding it.
Now, while you keep the left mouse button pressed, you press the right button. There will now be a new press event for the right button.
They do not appear at the same time and the second press event is only for the right button.

You then want to check if both press events happened in a certain amount of time (if necessary) or just check if they are both pressed independent of the time.

SixDegrees
10th June 2010, 07:34
Mouse events are always serialized; even if you manage to press both mouse buttons precisely at the same time, the OS is going to convert that into two seperate events and send them along one after the other.

The best you can do is note the state of the event by examining buttons() and checking to see whether both buttons happen to be down, which will be the case for one of the pair of events you'll receive. If you want different behavior when only one button is down, though, the only way to implement that is to use an interval timer that determines when two clicks are "close enough" together to count as a single event.