[Maya-Python] Getting shape under cursor

1,036 views
Skip to first unread message

Marcus Ottosson

unread,
Feb 21, 2016, 12:14:58 PM2/21/16
to python_in...@googlegroups.com

Hi all,

Is it possible to query the shape at the cursor position, without clicking and running cmds.ls(selection=True)?

The idea is to provide a tooltip of sorts, and for that I’ll need to know what to tooltip about, without interrupting the user.

Here’s a rough sketch.

Inline images 1

from PySide import QtGui, QtCore

data = {
    "lastPosition": QtCore.QPoint(0, 0),
    "currentTooltip": None,
    "timer": None
}

def tooltip(message):
    """Produce tooltip"""
    tooltip = QtGui.QLabel(message)
    tooltip.setWindowFlags(QtCore.Qt.ToolTip)
    tooltip.setStyleSheet("""
    QLabel {
        background: "white";
        color: "black";
        height: 30px;
        width: 100px;
        padding: 20px;
        border: 2px solid black;
    }
    """)
    tooltip.move(QtGui.QCursor.pos())
    tooltip.show()

    QtCore.QTimer.singleShot(2000, tooltip.deleteLater)

    return tooltip

def evaluate():
    """Should we produce a tooltip?"""
    position = QtGui.QCursor.pos()
    if position == data["lastPosition"]:
        object = object_under_cursor()
        data["currentTooltip"] = tooltip(
            "The object under the cursor is of type \"{}\"".format(
                cmds.nodeType(object)))
    data["lastPosition"] = position

def object_under_cursor():
    """

    I WANT THIS

    """

    return "persp"

def start():
    """Track the cursor"""
    if data["timer"] is not None:
        data["timer"].stop()

    timer = QtCore.QTimer()
    timer.setInterval(1000)
    timer.timeout.connect(evaluate)
    timer.start()

    # Store reference
    data["timer"] = timer

def stop():
    if data["timer"] is not None:
        data["timer"].stop()
        data["timer"] = None

start()
stop()

Aside from some of the logistical issues with how I’m tracking the mouse, how can I implement object_under_cursor?

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

Justin Israel

unread,
Feb 22, 2016, 1:16:33 PM2/22/16
to python_in...@googlegroups.com

Hey Marcus,

I don't know of any way to do what you want through a provided API call. Could you do it in a roundabout way by:

* saving the current selection
* force a click on the mouse position through Qt
* grab selection for use with your tool tips
* restore original selection

It may not cause any visual pops of it is happening really fast. Or if it does, maybe you can try adding a cmds.refresh(suspend=True/False) around it?

Justin


--
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/CAFRtmODRp0Jj8a_upqyT7Ycyz%3D%2BdWiUQ6Nw5AfLAf82pGmxBrw%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.

Justin Israel

unread,
Feb 22, 2016, 1:33:24 PM2/22/16
to python_in...@googlegroups.com

Hmm, after a bit more looking around, here is an untested shot in the dark. What if you

* cmds.getPanel(underPointer=True)
* Convert panel to editor using cmds.modelPanel(editor=True)
* cmds.hitTest(modelEditor, x,  y) to see if any dag objects are under the mouse. x, y would be the position of the mouse in local space to the model editor widget.

Justin

Marcus Ottosson

unread,
Feb 22, 2016, 4:40:58 PM2/22/16
to python_in...@googlegroups.com
Thanks Justin, I'll give this a go!


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



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

Marcus Ottosson

unread,
Feb 22, 2016, 4:56:18 PM2/22/16
to python_in...@googlegroups.com

That worked well, nice find on the seemingly obscure hitTest command.

Significant snippet

def object_under_cursor():
    """Get objects under cursor"""
    pos = QtGui.QCursor.pos()
    widget = QtGui.qApp.widgetAt(pos)
    relpos = widget.mapFromGlobal(pos)

    panel = cmds.getPanel(underPointer=True) or ""

    if not "modelPanel" in panel:
        return

    return (cmds.hitTest(panel, relpos.x(), relpos.y()) or [None])[0]

Thanks again!

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

Justin Israel

unread,
Feb 22, 2016, 5:02:04 PM2/22/16
to python_in...@googlegroups.com
Oh sweet! That's great that it worked! I had remembered seeing hitTest a long while back but had never used it. Finally it has some use!

Reply all
Reply to author
Forward
0 new messages