mouse position?

1,188 views
Skip to first unread message

maya2015

unread,
Nov 19, 2014, 5:10:44 PM11/19/14
to python_in...@googlegroups.com
How can I track the mouse's 2d screen-space position in realtime?

Jesse Kretschmer

unread,
Nov 19, 2014, 9:56:23 PM11/19/14
to python_in...@googlegroups.com
You can use PySide, probably. What are you trying to do? 

Tracking the mouse movement will get complicated, but it is trivial get the mouse position using PySide at any time you desire.
from PySide import QtGui
point = QtGui.QCursor().pos()
print "x: %s; y: %s" % (point.x(), point.y())



... Ignore the rest of this message if that would work for you. I'm indulging my own curiosity.

Tracking Mouse Movement (probably a bad idea)

If you want to actively track the mouse, you will need to mess with the widget settings. I don't think that mouse tracking is enabled in maya by default. I'm not going to have maya handy for a little while, so I can't verify that statement. 

Note from qt-project on QMouseEvent:

Mouse move events will occur only when a mouse button is pressed down, unless mouse tracking has been enabled with QWidget::setMouseTracking().

This would need to to be enabled on the widget of interest and all ancestors. You could perhaps recursively walk through all QWidget children starting at the Maya Main Window, or walk up through the parents from the widget of interest.

Anyhow, here is an example that may work while the mouse is held down. I have not tested it, but it covers the basic of creating an EventFilter and installing it to the MainWindow. I'll leave the setMouseTracking to someone with Maya handy.
"""
Wrap instance method:
http://nathanhorne.com/?p=485

Event filter installation example:
https://groups.google.com/d/msg/python_inside_maya/LwmKyqp8MW8/pSa0gRKuKHQJ
"""

import maya.OpenMayaUI as om
from PySide import QtGui, QtCore
import shiboken

def wrapinstance(ptr, base=None):
    """
    Utility to convert a pointer to a Qt class instance (PySide/PyQt compatible)

    :param ptr: Pointer to QObject in memory
    :type ptr: long or Swig instance
    :param base: (Optional) Base class to wrap with (Defaults to QObject, which should handle anything)
    :type base: QtGui.QWidget
    :return: QWidget or subclass instance
    :rtype: QtGui.QWidget
    """
    if ptr is None:
        return None
    ptr = long(ptr) #Ensure type
    if globals().has_key('shiboken'):
        if base is None:
            qObj = shiboken.wrapInstance(long(ptr), QtCore.QObject)
            metaObj = qObj.metaObject()
            cls = metaObj.className()
            superCls = metaObj.superClass().className()
            if hasattr(QtGui, cls):
                base = getattr(QtGui, cls)
            elif hasattr(QtGui, superCls):
                base = getattr(QtGui, superCls)
            else:
                base = QtGui.QWidget
        return shiboken.wrapInstance(long(ptr), base)
    elif globals().has_key('sip'):
        base = QtCore.QObject
        return sip.wrapinstance(long(ptr), base)
    else:
        return None


# Lifted from older Maya Python post:
# https://groups.google.com/d/msg/python_inside_maya/LwmKyqp8MW8/pSa0gRKuKHQJ
#
class MouseEventFilter(QtCore.QObject):
    def __init__(self, label=None):
        self.__label = label
        QtCore.QObject.__init__(self)

    def eventFilter(self, obj, event):
        typ = event.type()
        if event.type() == event.MouseMove:
            if self.__label and hasattr(self.__label, 'setText'):
                self.__label.setText("x: %s; y: %s" % (event.x(), event.y()))
        return False

def main():
    main_window = wrapinstance(long(om.MQtUtil.mainWindow()))
    label = QtGui.QLabel()
    eventFilter = MouseEventFilter(label)
    main_window.installEventFilter(eventFilter)
    label.show()

    ## remove
    # main_window.removeEventFilter(eventFilter)
    # eventFilter.deleteLater()

if __name__ == '__main__':
    main()
gl;hf

Marcus Ottosson

unread,
Nov 20, 2014, 2:59:21 AM11/20/14
to python_in...@googlegroups.com

For real-time, regardless of playback or events, you could do this.

from PySide import QtGui, QtCore

def print_mouse_position():

    point = QtGui.QCursor().pos()
    print "x: %s; y: %s"
 % (point.x(), point.y())

timer = QtCore.QTimer()
timer.setInterval(1000.0 / 25)  # Print 25 times per second
timer.timeout.connect(print_mouse_position)
timer.start()
# timer.stop()  # Call this to stop printing

This would need to to be enabled on the widget of interest and all ancestors. You could perhaps recursively walk through all QWidget children starting at the Maya Main Window, or walk up through the parents from the widget of interest.

You could use QApplication.allWidgets() for this, but there’s still an amount of elements in the Maya window without mouse tracking functionality; mainly the viewport. Not to mention the potential performance bottleneck, and the fact that some widgets may rely on having tracking disabled; e.g. widgets that overlap. Don’t do this. :)


--
You received this message because you are subscribed to the Google Groups "Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_m...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/python_inside_maya/CANESWi1YAh3RtGw15EAkpKNUci1ue4N9JTR2g5esssG-nOTMCw%40mail.gmail.com.

For more options, visit https://groups.google.com/d/optout.



--
Marcus Ottosson
konstr...@gmail.com

Jesse Kretschmer

unread,
Nov 20, 2014, 3:17:34 AM11/20/14
to python_in...@googlegroups.com
On Wed Nov 19 2014 at 11:59:20 PM Marcus Ottosson <konstr...@gmail.com> wrote:

You could use QApplication.allWidgets() 

Oh man! .allWidgets(). What a great/terrible idea. It's definitely easier to implement than the recursive function that I had suggested off-hand.

.. I'm not sure if this is going off topic, but you could try to implement something at the windows manager level. 

In particular, this project came through my feed some time ago: http://iographica.com/. It is cross-platform and they offer source. Most importantly, it makes pretty pictures, which is all we really care about anyhow, right?

Marcus Ottosson

unread,
Nov 20, 2014, 4:09:35 AM11/20/14
to python_in...@googlegroups.com

Oh man! .allWidgets(). What a great/terrible idea.

I know right. :) I discovered it not too long ago and have found it handy for debugging, but not much else. There’s also .topLevelWidgets() which can be a handy replacement for getting a handle to the Maya window, independent of both PyQt and PySide specifics, as discussed here.

from PySide import QtGui
widgets = dict((w.objectName(), w) for w in QtGui.QApplication.topLevelWidgets())
window = widgets['MayaWindow']

.. I’m not sure if this is going off topic, but you could try to implement something at the windows manager level.

There’s really no need, PySide is cross-platform too and something like iographica could be implemented using a similar approach to the above.


--
You received this message because you are subscribed to the Google Groups "Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_m...@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.



--
Marcus Ottosson
konstr...@gmail.com

Reply all
Reply to author
Forward
0 new messages