PDA

View Full Version : Catching Mouse Events on Top-Level Window



andyp
7th September 2009, 18:14
Is there any way of catching Mouse events (principally Press and Release) for the window frame of a QMainWindow. I need to compress moveEvents and resizeEvents for the window, because I want to suppress the "show contents while dragging" behavior (Windows,Linux and Mac). Overriding the mousePressEvent and mouseReleaseEvent handlers on a class derived from QMainWindow doesn't give me mouse events on the window frame, but only in the client area of the window.

aamer4yu
8th September 2009, 06:38
Window frame is managed by the OS...you only get
QWidget::moveEvent when u press and move the window frame.

I am afraid you might not get press and release event for the frame( I assume the top blue frame in windows).

By the way what do u need from press and release of the frame ? Might be there is some other way to achieve your goal...

andyp
8th September 2009, 08:07
My problem is that some of my windows have complex contents, therefore they take quite a time to repaint, which of course I can only do in the GUI thread. Currrently every move/resize event is generating a repaint. I need to compress the move/resize events so that I only do a full redraw on the "last" one, i.e. the event on mouse button up. Then I need only repaint my complex windows once. This is easy on Win32 because you can catch "window moving" and mouse events on the window frame, but alas not in QT that I can find.

wysota
8th September 2009, 09:05
You can intercept moveEvent and resizeEvent and block updates for that perdion. Then after some time (using a timer) you can enable updates back and schedule an update.

andyp
8th September 2009, 09:25
Thanks for the advice. However the updates issue is not really the solution I feel since the repaints are not handled automatically but controlled by another thread. I just need to catch the last "resize" (or "move") event because this changes characteristics of the window and thus what gets repainted therein. At that point I then force an update if necessary. The problem, which I know you understand, is that I am getting one of these on every mouse move which eventually locks the thing up. A timer is probably the answer, but I just thought any way of catching the mouse-up event would do me.

wysota
8th September 2009, 09:37
However the updates issue is not really the solution I feel since the repaints are not handled automatically but controlled by another thread.
Hmm? How come? Are you sure this is safe?


I just need to catch the last "resize" (or "move") event because this changes characteristics of the window and thus what gets repainted therein. At that point I then force an update if necessary.
My solution remains valid. Start a timer on first move or resize, if another move or resize happens before the timer fires, restart it. When the timer fires it is safe to assume the window has already been put in its final position.


The problem, which I know you understand, is that I am getting one of these on every mouse move which eventually locks the thing up. A timer is probably the answer, but I just thought any way of catching the mouse-up event would do me.

I can move the window without touching the mouse and then what?

andyp
8th September 2009, 10:26
By jove you're right Caruthers.
When I said "controlled by another thread" I meant controlled, not painted. It is thread-safe. It is a real pain that you can't make window (X) calls from threads other than the GUI thread. I can see why they (QT) have "copped out" this way, it has saved them making a threadsafe X system with a multitude of "critical sections" etc.
Back to the resize/move events: yes, your way is a good solution. I was just not sure of the overhead involved in restarting a timer on every move/resize event. I shall run it up the flagpole. Mille grazie. It is of course arbitrary what length of time is chosen, also if they hold the button down for ages while moving/resizing this may mean we get an extra event or two, but that is bearable compared to the current locks ups.