Restrict mouse cursor movement


  • Qt Champions 2016

    Hello,
    I have a widgets application and I'd want to restrict the mouse from leaving my QMainWindow. I have considered grabbing the mouse, but it doesn't really suit me, as I still want to receive events (in the child widgets), but I don't want to allow the mouse to leave the window. Any suggestion on how such a behavior can be achieved?

    Kind regards.


  • Qt Champions 2016

    Hi
    Do you mean something like this windows function but crossplatform ?
    https://msdn.microsoft.com/en-us/library/windows/desktop/ms648383(v=vs.85).aspx

    And Mainwindow cannot just be fullscreen?


  • Qt Champions 2016

    Hello,

    Do you mean something like this windows function but crossplatform?

    Yes I mean it exactly like that.

    And Mainwindow cannot just be fullscreen?

    It is in a pseudo full screen because of a bug in Qt (I have opengl widget embeded that prevents full screen from working properly). Additionally, even if put in full screen the cursor is not clipped to an area, because there are multiple screens, so Qt allows the cursor to escape (which is of course an expected behavior).

    Kind regards.


  • Qt Champions 2016

    Ok.
    I didn't find any good way.
    I tried using MouseMoveEvent + mousetracking
    but if you moved the mouse really fast
    it would not detect leaving the window.



  • @kshegunov said:

    may be you can get some information from this-
    http://www.codeprogress.com/cpp/libraries/qt/QtHideMouseCursor.php


  • Qt Champions 2016

    @mrjj
    Right? Me neither. The only thing I could fathom was to grab the mouse, but then my child widgets don't get anything. Maybe I could manually dispatch the messages, but it does seem weird.

    @Rahul-Sharma
    Sorry, but does me no good. I'm not after changing the cursor image, but disallowing it to leave a certain area instead. Thanks for the suggestion, though.


  • Qt Champions 2016

    @kshegunov
    Not sure how much worked there is to self dispatch messages.
    My use case for for demo to disallow people go clicking on other tings, so i ended up
    with timer, moving the mouse back if it has moved outside.
    While not limiting it for real. it was impossible to click on stuff outside.
    Still not a good solution but fine for the 2 hours demo.

    What is your use case`? if i may ask.


  • Qt Champions 2016

    @mrjj
    Sure, I don't like secrets, that's why I prefer Linux ;P
    It's for my pet project - a proof of concept Qt based game. I think I've mentioned it to you. I need to restrict the mouse from leaving the main window, because there is an action I wish to attach to certain area near the edges of the window, namely to allow the player to move around the world with the mouse.


  • Qt Champions 2016

    @kshegunov
    hehe.
    Yes you mentioned pet :)
    So In reality if opengl would go fullscreen it would just work.
    Else I think grab is the best option.


  • Moderators

    Some games do it this way:

    • Hide the cursor (set to Qt::BlankCursor)
    • In mouse move event record a distance of the cursor from the center of your window (QCursor::pos() and window geometry). Use that distance to update your "virtual cursor" clipped to whatever region you want.
    • Move the cursor to the center of your window
    • Draw your own cursor "in game" at the "virtual" position

    In mouse clicks use your "virtual" position instead of the real one. If you also need to pass the moves to some widgets etc. then you can filter your window for mouse clicks, intercept and resend the events with your "virtual" position.


  • Qt Champions 2016

    @Chris-Kawa
    Thanks for the suggestions, I'll think about it. They all seem to revolve around remapping the cursor, which I'm not sure will work for me, because I have Qt3D put into a QOpenGLWindow and it handles the mouse events itself. Still, thank you again for taking the time.

    Kind regards.


  • Qt Champions 2016

    Hello,
    It turned out to be incredibly simple in the end. There is a leave event (that was news for me) fired from Qt, to which it's possible to attach the necessary code (for anyone that might come to the same issue):

    void MyMainWindow::leaveEvent(QEvent * event)
    {
    	// Get the window geometry & cursor position
    	const QRect & rect = geometry();
    	QPoint position = QCursor::pos();
    
    	// Check the bounds
    	qint32 x = qBound(rect.left(), position.x(), rect.right());
    	qint32 y = qBound(rect.top(), position.y(), rect.bottom());
    
    	// Adjust the cursor
    	if (x != position.x() || y != position.y())
    		QCursor::setPos(x, y);
    
    	event->accept();
    	QMainWindow::leaveEvent(event);
    }
    

    Thanks to all for the help.

    Kind regards.


  • Qt Champions 2016

    Ok, that i completely missed it had :)



  • more cursors

    [EDIT: Irrelevant link removed --JKSH]



Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.