what is the best way drive a node.attribute with a signal from a QObject?

715 views
Skip to first unread message

mtherrell

unread,
Dec 14, 2010, 2:04:10 PM12/14/10
to python_inside_maya
Hi,

with mel there is a command 'connectControl' that would link the
output of, say, a mel float slider, to say, the translateX attribute
of a node in maya.

in my project, i am dual subClassing a QObject and QGraphicsItem.
adding my own signal to the resulting item that is triggered when the
item is moved around in a QGraphicsScene, and now i want to connect
that signal to the translateX of a node in maya.

I could just re-implement the QGraphicsItem.itemChange function and
inside that, call setAttr on the translateX, but this seems ugly and
possibly slow since setAttr is less direct than connectControl would
be.

I could maybe use the maya API equivalent of setAttr in the same
scheme.. but would that be any faster?

I would like to avoid a literal callback mechanism inside my object's
event handlers.

what i would like to be able to do is exactly what connectControl mel
command does, connecting the output of a widget to an attr in maya..
but instead, using the signal and slot mechanism of QT.

is there a way to define a node.attr in maya as a QT slot? ---that
would be awesome---.

is there something like a pymel "QConnectControl" command that i am
missing?

thanks for any help on this.

-

Chad Vernon

unread,
Dec 16, 2010, 12:18:23 PM12/16/10
to python_in...@googlegroups.com
I've been doing a setAttr with

 cmds.undoInfo(openChunk=True)
 cmds.undoInfo(closeChunk=True)

on the mouse events.  I haven't found a way to do any direct connection.



mtherrell

unread,
Dec 17, 2010, 2:30:42 PM12/17/10
to python_inside_maya
thanks chad.

this does work .. but in one direction. (qtcontrol -> attr)

the undo will return the node.attr to where it should be, but it won't
undo my qt interface to correspond.
similarly, scrubbing the attr does not automatically change the qt
interface either..like with "connectControl"
..with this scheme i will need to find a way to trigger the QT event
with undo, or just somehow update the qt control when its the attr
changes with a callback (scriptJob or somthing)...and this could get
kind of messy.

i can see there may be a need for the creation of a command plugin (or
just a py function) that will create a two way connection between attr
and a QT control,
and either tie the qt control in with maya's undo scheme or just rely
on that two way connection to reset the control..

Does anyone know exactly how connectControl works under the hood in
maya?
it would be nice to emulate the way it works, while extending it to
work with QT slots and signals.

cheers.

-mt


On Dec 16, 9:18 am, Chad Vernon <chadver...@gmail.com> wrote:
> I've been doing a setAttr with
>
>  cmds.undoInfo(openChunk=True)
>  cmds.undoInfo(closeChunk=True)
>
> on the mouse events.  I haven't found a way to do any direct connection.
>

Chad Vernon

unread,
Dec 17, 2010, 3:02:00 PM12/17/10
to python_in...@googlegroups.com
I do it with a callback from MNodeMessage to update the UI when the attribute changes.  You'll need to do some signal blocking to not get an infinite loop.  For time change you could use MDGMessage.addTimeChangeCallback.

Everyone that I've talked to using Qt and Maya say you pretty much just have to manage all the callbacks yourself.


mtherrell

unread,
Dec 22, 2010, 1:20:51 PM12/22/10
to python_inside_maya
thanks chad.

good to know.. at least i know i'll be barking up the right tree by
going this route.

btw, i know this is straying into another topic, but:

i wrote a node plugin a while back that used kAttributeChanged
callbacks 'attached' to all attrs on the plugin node, as a way of
monitoring (its own) attrs for change, and then i filter those signals
using a string attr that names the attribute to listen for and a
script to run when it changes. (as kind of an alternative to
scriptJob). but to do this, it meant that i had to create the node
itself as a plugin to expose all the various callback signals to the
attrs to capture when they change.

do you know of a way to do this without having to create the node
itself as a plugin?
ie. an alternative to scriptjob 'attrchange' that would use already
existing (non-plugin) maya nodes?

ie. ie.. attach an 'attrchanged' callback to, say, all (or some) of
the attrs of a nurbsSphere without having to write the sphere node
itself as a plugin, and without having to write a scriptjob to monitor
each attr individualy? (another scheme might create a plugin deformer
node that would associate an attr being dirtied with a script to run..
then just connect that attr to an already existing maya node.attr that
you want to monitor.. but im trying to avoid that scheme as well)

i think you may have alluded to alternatives to these node plugin
schemes in your previous post:

"I do it with a callback from MNodeMessage to update the UI when the
attribute changes."

(i could really use somthing like this right about now!)
but up till now i could only figure out how to monitor for attrchange,
if i create the whole node, with the attrs to monitor, as a plugin
itself..

would love to be able to just have a command or something that would
replace scriptjob and work on already existing out of the box
node.attrs

-thanks

-mark therrell

On Dec 17, 12:02 pm, Chad Vernon <chadver...@gmail.com> wrote:
> I do it with a callback from MNodeMessage to update the UI when the
> attribute changes.  You'll need to do some signal blocking to not get an
> infinite loop.  For time change you could use
> MDGMessage.addTimeChangeCallback.
>
> Everyone that I've talked to using Qt and Maya say you pretty much just have
> to manage all the callbacks yourself.
>

Ofer Koren

unread,
Dec 23, 2010, 6:17:32 AM12/23/10
to python_in...@googlegroups.com
The MNodeMessage class allows you to install callbacks via the API much like scriptJob. You can do this via the Python API so you don't need a plugin here at all.
Any specific reason not to use scriptJob?

- Ofer
www.mrbroken.com


mtherrell

unread,
Dec 23, 2010, 1:24:09 PM12/23/10
to python_inside_maya
Ofer,

monitoring all the attrs that, say, represent the controls of a
character(s) in a shot.. can be allot of attrs to monitor.
its totally possible with scriptJob, and i do have a functional way to
propagate and clean up mass numbers of jobs.. with a ton of logic.

this, historically, been a problem with many of the things we have
wanted to do with characters in big shots in maya.
the scriptJob system has arguably always fallen a little short on
this. and maybe is simply not what it was intended for.

according to the scriptJob docs, one is supposed to be able to monitor
all the child attrs of a compound attr for change, in which case one
could have a single scriptJob monitoring a single compound attr, the
children of which, have incoming connections from all the many attrs
you might want to test for change... but this is totally busted. it
does not work since about maya 7.0.. if it ever really worked at
all... im using 2011 now, and it still crashes maya no matter how you
try to set it up.

also, for reasons i wont go into, we want to know exactly why the attr
changed. did it change from user interaction with manipulators? did it
change from setAttr command, did it change due to keyframes being
moved on an incoming animlayer? did it change via scrubbing the
channelbox virtual slider? etc. scriptJob is woefully inadequate for
this level of detail.

that's why (back in the day) we wrote a node that lets you add attrs
to it, connect the output of the attr you want to monitor to the input
of the attr on this plugin node, then define a string attr associated
with this monittr attr that lets you filter.. not only for change, but
why it changed..
ie,'MNodeMessage.kAttributeSet','MNodeMessage.kAttributeEval',MNodeMessage.kAttributeAdded...
etc.

but the only way i could (back then) figure out how to do this, was if
i created a plugin node in order to attatch the callbacks to attrs
created on this node.
its been awhile, and this limitation was perceived at a time before
python in maya.. and access to the API through scripts.

so. live and learn.. i would love to be able to attatch this family of
MNodeMessage callbacks to any old node.. and i will be trying to
figure that out right now!

-thanks

On Dec 23, 3:17 am, Ofer Koren <kor...@gmail.com> wrote:
> The MNodeMessage class allows you to install callbacks
> <http://download.autodesk.com/us/maya/2011help/API/class_m_node_messag...>via
> the API much like scriptJob. You can do this via the Python API so you don't
> need a plugin here at all.
> Any specific reason not to use scriptJob?
>
> - Oferwww.mrbroken.com
>
Reply all
Reply to author
Forward
0 new messages