Planned maintenance has been done but it did not solve the problem. So work will continue on this and a new time for trying updates will be announced asap.

How to make mouseMoveEvent and keyPressEvent to be called interchangeably?



  • I have a program that reacts to mouse movements and keypress events. My problem is that when a key is already pressed, most of the mouse movements are being ignored, or maybe one mouse-move event is handled every about ~20 handlings of keypress.
    How to make the both events to be equally likely handled when they both are active?

    My Qt version is 5.11.1 and I'm using it on Debian 9 (stretch). Any help please?


  • Moderators

    That doesn't seem like something that could be configured. Mouse and keyboard are separate devices and Qt handles them based on the events sent from the OS. Those events are kinda independent of each other,, so if you want to get them at some fixed rate in Qt you would have to make your OS send those events that way, which, again, sounds unlikely to be configurable (though I'm not a Linux guy, so who knows).

    Maybe there's some other approach we can find. What do you need that for?



  • I do have a 3d scene with Opengl, and I'm using the keyboard to move forward and backward, and the mouse pointer to change the direction. The problem is that in order to change the direction while moving, I have to release the pressed key on the keyboard, as in the most of cases the keyPressEvents somehow get over the mouseMoveEvents.
    Here is how my draft code looks like:

    MyWidget.h

    class MyWidget : public QGLWidget, protected QOpenGLFunctions_3_0
    {
        Q_OBJECT
    public:
        // some other stuff
    
    protected:
        virtual void mouseMoveEvent(QMouseEvent*) override;
        virtual void keyPressEvent(QKeyEvent*) override;
    
       // some other stuff
    
    private:
    
       // some other stuff
    
    

    MyWidget.cpp

    void MyWidget::keyPressEvent(QKeyEvent* ev)
    {
        // move forward, backward
    }
    
    void MyWidget::mouseMoveEvent(QMouseEvent *ev)
    {
       // change direction
    }
    

    I'm wondering if it is even possible to call mouseMoveEvent inside the keyPressEvent , so to make sure that after every keypress handling the mouse event will be handled as well?


  • Moderators

    Mouse events and keyboard events have nothing to do with each other and you shouldn't try to tie them in any way.

    That being said you should not tie movement directly to key press events either because of how keyboards work - there's an initial key press, and if you hold the key, after a short break you get a stream of additional key presses at a much higher rate. This is because keyboards were originally designed for typing, not camera manipulation in 3D environments.

    For camera control you should handle input a little differently. Mouse moves you can handle directly in the move events, but keyboard needs special treatment. I already described that in another thread a couple years back so have a look: Big Issue with Qt key inputs for gaming. In short you set some variable to true on press and to false on release and then poll that variable at a constant rate (e.g. with a timer). Don't tie directly to key presses or releases, as keyboard rates are hardware and software dependent and you don't want to have your camera move slower or faster on different computers.


  • Moderators

    Oh, and another thing that may be related to your problem - don't update your 3D view in these input handlers. Both mouse and keyboard events come at a much higher rate than the refresh rate of a standard display. If you're trying to "redraw" on every key press you're probably choking the machine and it can't handle mouse events at a reasonable rate anymore.

    If you haven't already, decouple your drawing from input. As I mentioned before - store keyboard state in some variables and accumulate the change in direction from mouse events in some variable and then actually process that input at some fixed interval which is lower or equal to that of the refresh rate of your target display (usually 60Hz) e.g. with a timer.



  • Yes i already do the movement/rotation at a constant rate. But I think the idea of using press/release key events to set some flags was just on the point. I think it should solve my problem, will try it later anyway.
    Thanks for the info :-)



  • @Chris-Kawa Oky, here I recall, those suggestions actually solved my problem, so thanks for the information! The problem was that I was calling repaint() inside mouseMoveEvent and keyPressEvent removing it from there solved the issue, and the program now runs smoothly as expected.

    I don't know how to mark this thread as solved, I didn't see any obvious tool for such a thing from my side, so you may manage that from your side.


  • Qt Champions 2018

    @BoboFuego said in How to make mouseMoveEvent and keyPressEvent to be called interchangeably?:

    I don't know how to mark this thread as solved

    "Topic Tools" at the bottom right side and then "Mark as Solved".