Jump to content
Atom

[SOLVED]Python Button Call Def?

Recommended Posts

Hi All,

I have a python node that I have added a button to that nodes user interface.

I want the button to call a def inside the python script of the self node.

I use the code from the help file but it does not work.

Code in button:

kwargs['node'].hdaModule().onButtonPress()

Code in script:

def onButtonPress():
    print "click"
	

Untitled-1.jpg

What more do I need to make this work?

Edited by Atom

Share this post


Link to post
Share on other sites

Hey there,

the script parameter of the python node is not where you want to put your callback scripts. It is meant for processing incoming geometry.

You need to create a new Digital Asset definition and put the callback script into the hdaModule.

  • Go to the Type Properties of your HDA and select the script tab.
  • From the Event Handler dropdown menu select "Python Module".
  • Write your "onButtonPress" funtion in there (it can have any name you want).
  • Now you can call that with a button callback script.
     
hou.phm().onButtonPress() # hou.phm() is a shortcut to getting the current node's hdaModule

If you want to have a user editable script in your node you can run it like this:

exec(hou.pwd().parm("python").eval()); onButtonPress()

Cheers,

Dennis

Edited by dennis.albus

Share this post


Link to post
Share on other sites

Thanks, I was hoping for something much simpler.

I don't want to make an HDA I just want to run code from clicking a button. I was hoping to just have a button be part of my script.

 

Share this post


Link to post
Share on other sites

That code you found in the help is for when you define functions on the 'scripts' tab of a digital asset (ah, Dennis has replied while I was typing!). Defining it as a digital asset is The Right Way, but if you wanna go hacky...

In your case, you have a node parm (named 'python'), which is a string. To make python execute code in a string, just wrap it in 'exec':

   exec('print 32')

But you have a function within the string instead: 

   exec('def onClick():\n   print "hello"')

When you exec the string, that function becomes known to python, so you can just call it. To do it in one line, there's a cheat in python that a ';' works as a newline:

   exec('def onClick():\n   print "hello"') ; onClick()

Your string is actually a parm on the node. To get to the parm:

   kwargs['node'].parm('python')

To actually return the contents of that parm as a string, eval it:

   kwargs['node'].parm('python').eval()

So now that we have that as a string, wrap it in exec(), then call the function afterwards:

   exec(kwargs['node'].parm('python').eval());onClick()

And that's the callback you put on the button.

That's all _very_ hacky though, doing it in an HDA is cleaner. :)

 

-matt

 

  • Thanks 1

Share this post


Link to post
Share on other sites

Thanks fellows, those work!

I had to remember to change the callback script type from hscript to python as well.

I just needed a simple button to zero out some parameters on the script.

 

Untitled-1.jpg

Share this post


Link to post
Share on other sites

One thing I do notice is that the above mentioned technique only works for a single button added to the interface. If I add multiple buttons to the interface and change the call to another def, that def is never called?

I realize I am evaluating the entire script every time the button is called but after that evaluation occurs shouldn't the follow up call take place? I don't get an error, just nothing happens?

.

.

.

Edit: Never mind, I forgot to switch the new buttons from hScript to Python. Now they work as expected.

 

Edited by Atom

Share this post


Link to post
Share on other sites

Hi,

I am looking similar solution, this works for the python script node in obj path. My python node is under path /obj/geo/subnet, and the button is on subnet node.
How I can use similar callback script as above? I am not sure do I understand correctly

     exec(kwargs['node'].parm('python').eval());onClick()

the 'node' is it a node where is a button?
'python' is a parameter on that node?

am I right?
if yes, I did something like 

    exec(kwargs['/obj/geo/subnet/py'].parm('python').eval());onClick()

'py' is my python node name
I think I miss understand something here or maybe I write inncorectly

I need a hand with this part.

 

Thank you

Share this post


Link to post
Share on other sites

You want to write it like this:

exec(hou.node('/obj/geo/subnet/py').parm('python').eval());onClick()

Or even better relative to the current node:

exec(hou.node(hou.pwd().path() + '/subnet/py').parm('python').eval());onClick()

kwargs is a prefilled dictionary that contains information about the current node, the parm that has been changed/executed and can be used as a convenient way to grab that information in your code. You can simply run 

print(kwargs)

to see what information it contains.

Edited by dennis.albus
  • Thanks 1

Share this post


Link to post
Share on other sites
9 minutes ago, dennis.albus said:

You want to write it like this:


exec(hou.node('/obj/geo/subnet/py').parm('python').eval());onClick()

Or even better relative to the current node:


exec(hou.node(hou.pwd().path() + '/subnet/py').parm('python').eval());onClick()

kwargs is a prefilled dictionary that contains information about the current node, the parm that has been changed/executed and can be used as a convenient way to grab that information in your code. You can simply run 


print(kwargs)

to see what information it contains.

Works, thank you. 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×