How to avoid losing mouse events?
i am developing a image editor/painting application and i have the following problem:
I receive the mouse events, i draw on a QImage, convert it to QPixmap, show it on the screen.
The drawing operation for debuging purposes at the moment is to draw a simple rectangle on the mouse position via QPainter on the QImage
Now the problem is: as long as i do this on a 512x512 image, everything seems fine, but if i do it on a 4096x4096 image, most mouse events are lost an i only get one every half a second or so.
I tried different approaches so far:
a) do the drawing operations in the mouse event handler
b) in mouse event handler, start a thread that does the drawing operations, this one failed because you can not draw on a QPixmap in a thread... which is why i tried approach c:
c) in mouse event handler, start a thread that does the drawing on the QImage and then emits a signal that is connected to the main window, which updates the QPixmap on screen
All three have the same problem: Mouse events get lost.
How can i prevent this, or what are my options to change the general workflow for better performance?
It's a pure performance problem, not mouse events one.
First of all I wouldn't create separate thread every time as it's time consuming on it's own. Keep an event loop in a separate working thread and communicate thrrough signals and slots or use a qthreadpool, whichever turns to be faster.
Another thing is that 4096x4096 is a pretty big image, and chances are - you're not redrawing all of it every time so if it's possible try to update just the small fragment that actually changes and apply this to the resulting image.
Another option is to go for hardware acceleration - since you're working with pretty big images you might want to look into opengl. Displaying a single quad is a breeze for a gpu and you would be updating the texture for it in a separate thread. Kinda like what you have in c) but a lot faster.
Maybe you want to use c), but also coalesce the events in order to limit the number QPixmap updates in the "main" thread. That is: If several events are encountered within a short time, update the QImage in the "background" thread for each event, but only trigger an update of the QPixmap once.
A simple solution would be to simply delay the signal that is sent from the "background" thread to the "main" thread. That is: If the background thread processes an event, it starts a timer. If the timer is triggered, the signal will be sent. But if a new event is encountered before the timer was triggered, stop the timer, process the new event and re-start the timer. There also should be a limit of the maximum overall delay, of course...