Atom Posted July 18, 2016 Share Posted July 18, 2016 (edited) 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" What more do I need to make this work? Edited July 18, 2016 by Atom Quote Link to comment Share on other sites More sharing options...
dennis.albus Posted July 18, 2016 Share Posted July 18, 2016 (edited) 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 July 18, 2016 by dennis.albus Quote Link to comment Share on other sites More sharing options...
Atom Posted July 18, 2016 Author Share Posted July 18, 2016 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. Quote Link to comment Share on other sites More sharing options...
mestela Posted July 18, 2016 Share Posted July 18, 2016 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 1 Quote Link to comment Share on other sites More sharing options...
Atom Posted July 18, 2016 Author Share Posted July 18, 2016 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. 1 Quote Link to comment Share on other sites More sharing options...
Atom Posted July 18, 2016 Author Share Posted July 18, 2016 (edited) 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 July 18, 2016 by Atom Quote Link to comment Share on other sites More sharing options...
Bart87 Posted November 5, 2017 Share Posted November 5, 2017 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 Quote Link to comment Share on other sites More sharing options...
dennis.albus Posted November 5, 2017 Share Posted November 5, 2017 (edited) 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 November 5, 2017 by dennis.albus 1 Quote Link to comment Share on other sites More sharing options...
Bart87 Posted November 5, 2017 Share Posted November 5, 2017 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. Quote Link to comment Share on other sites More sharing options...
philpappas Posted September 17, 2019 Share Posted September 17, 2019 On 11/5/2017 at 9:43 PM, Bart87 said: Works, thank you. Can you share an example? i'm trying to use the button press as a switch. when pressed val = 1 i have a python node with a button parameter on its interface. and in the pythoncode i want to use that button press to make val=1 1 Quote Link to comment Share on other sites More sharing options...
MonicaDale Posted November 28, 2019 Share Posted November 28, 2019 Hi, I wanted to expose the "Export" button which is inside sop_terrain_texture_rop node inside my subnet to a button in my HDA. Can some one help me out how to achive this. I'm not really good with programming . Can someone help me out??? Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.