Calling functions without making the script launch - python

The title isnt very accurate i think
Here are my script at the right
Screenshot
It's a bot to automatize some actions. Now i want to add some gui to it but i dont know how.
Like you see at the left, i have " import questions" but cuz of it when I launch the tkinter file, it automatically launches the questions without taking my openBtn code into account.
How can I add gui to each command of my questions.py?

You need to break your questions.py script into actual functions . Python will simply execute all actions in questions.py when the namespace is imported before it reaches the logic below the import statements in testkinter.py.
So in questions.py remove your while True: statements in favor of function definitions like:
def check_database(param):
database check logic here
Then link the functions defined in questions.py to Tkinter button actions in testkinter.py like this:
w = tkinter.Button( fenetre, command=check_database )

Related

Function not defined when Importing Maya Python Script

I have a tool I wrote in python that works completely fine when running in the maya script editor. However, I want to be able to import the script from the script directory. Which should be simple, and I am shocked I can't find the solution while searching the web.
My script format is like this example:
import maya.cmds as cmds
# GUI code with buttons, they call the functions below.
#
#
def function1():
#commands that do things
def function2():
#commands that do things
#List of functions continues
Like I said, the program functions perfectly when run in the script editor. When saving the script to the directory and using this method:
import module
reload (module)
module.function()
The GUI loads fine, but then when pushing the gui buttons, it says the functions are not defined. I don't understand what I am missing? If the script was loaded, shouldn't the functions be defined? Any help would be greatly appreciated, thank you!
Just because the GUI loads doesn't mean that all of your functions loaded properly. You need to put your file, (module.py) in a directory that is visible to your PYTHONPATH. If you're in Maya, you can also put it in the MAYA_SCRIPT_PATH
The PYTHONPATH / MAYA_SCRIPT_PATH are environment variables that you set before launching Maya. In a default Maya installation, some places where you could put your module.py file would be:
(Windows) C:\Users\YOUR_USER_NAME\Documents\maya\scripts
(Linux) ~/maya/scripts
(Mac) - Not sure, put probably also ~/maya/scripts
If you want to know where else you can place it, you run this
import os
print(os.getenv('MAYA_SCRIPT_PATH', ''))
print(os.getenv('PYTHONPATH', ''))
Any location in that list that you have write permissions to is OK to add your module.py file.
Also, it's worth noting that in your example module.function() would fail. It'd need to be module.function1() or module.function2() but I assume you know that. Hope this helps
Sup guys
So i know this is an old question that has already been answered but I have some extra information that helps in regards to GUI functions not working. (same error)
and there's basically nothing on this anywhere.
so the script director only helps when loading in the module through the shelf but will still return the same error "fuction is not defined"
this has todo with how the function is called through the UI element.
example.
this is will allow you to call function in the script editor
but gives you the function not defined error when the module is imported
def GUI_function():
pm.button( command = "function()")
def function():
do stuff
this on the other hand works.
def GUI_function():
pm.button( command = function)
def function(*_):
do stuff
i don't know why but maya tends to think function() is a nodetype
so remove the brackets if you not using arguments and you good to go

How do I keep my code open in the shell with a pass command in the main() function?

I'm trying to learn how to build a web browser bot as half learning half project for someone else and I've hit a snag.
The site I'm using as guide has:
def main():
pass
Which he claims keeps the shell window open do he can run various functions like get x,y cords of the mouse position and take screen shots.
However when I run my code exactly as he has it in the guide it immediately opens and closes.
What I don't want is something like, "make it so pressing enter closes shell instead", what needs to happen is the window stays open so I can enter various functions.
What am I doing wrong? Am I suppose to just import the code in a different shell and run the functions outside it?
The code:
import os
import time
import ImageGrab
x_pad = 0
y_pad = 61
def screenGrab():
box = (x_pad,y_pad,x_pad+1919,y_pad+970)
im = ImageGrab.grab(box)
im.save(os.getcwd() + '\\full_snap__' + str(int(time.time())) + '.png','PNG')
def main():
pass
if __name__ == '__main__':
main()
The guide is: http://code.tutsplus.com/tutorials/how-to-build-a-python-bot-that-can-play-web-games--active-11117
You have three ways:
Start the intepreter with the -i option, as suggested by Ulrich in the comments:
python -i my-script.py
This way, the interpreter will be left open as soon as your script finishes execution and a prompt will be shown.
Use pdb. This is often used for debugging, and has a different interface than the usual Python prompt. If you're not familiar with it, it might not be the best option in your case. Replace pass with these two lines:
import pdb
pdb.set_trace()
Use code. This will give you an interface much more similar to the usual Python shell and can be an alternative to pdb if you're not familiar with it:
import code
code.interact()
By the way, you were not doing anything wrong per se. The pass statement is not meant to "halt Python and start a prompt", it's just needed as a filler for functions or loops with an empty body.

Maya Python multiple functions to one button

I am creating a rig through scripting and I have a UI. I would like to connect multiple functions to one button. Or rather, have a function inside of a function. Any suggestions on how to go about this issue?
I am importing the following libraries:
import maya.cmds as cmds
from functools import partial
Could you explain further more what you to do with a little example ?
I see you want to use partial so you may have multiple variables to pass through ?
My first idea would to create a function grouping your multiples function, ie :
def temp01():
return cmds.ls(sl=True)
def connection(obj01, obj02):
someCommand(obj01, obj02)
def printor():
print('yeah it is working')
def uiCommandButton_whatShouldIDoFunc(obj02, specialOkay, *args):
someCommand(temp01(), obj02)
specialOkay() #should print message
button01 = cmds.button(c=partial( uiCommandButton_whatShouldIDoFunc, cmds.ls(sl=1)[-1]), printor )
To have things nice and clean, I would use handlers.
A handler is a method that is called when an event occurs on your GUI element, like click. In the handler you can do whatever you want to (like calling your two functions). Handlers/event handlers are a tried and test GUI programming technique.
Here is an example:
my_button = cmds.button(command=partial(my_button_on_click_handler, arg1, arg2))
def my_button_on_click_handler(arg1, arg2):
# call all your functions and do stuff here
my_other_func1(arg1)
my_other_func2(arg2)
Some great posts on this topic (courtesy: #theodox and his awesome blog):
http://techartsurvival.blogspot.ca/2014/04/maya-callbacks-cheat-sheet.html?m=1
http://techartsurvival.blogspot.ca/2014/04/the-main-event-event-oriented.html?m=1
There is a "dirty" way of doing so by using PyMel and PySide/Qt.
First, turn your button into Pymel button :
import pymel.core as pm
import pymel.core.uitypes as pui
pyBtn = pm.button(label="", etc...)
or
pyBtn = pui.PyUI(my_button)
Then, convert it to a QtObject:
qtBtn = pyBtn.asQtObject()
And finally, you can add functions when the button is clicked like that:
qtBtn.clicked.connect(func1)
qtBtn.clicked.connect(partial(func2, arg1))
etc...
But like I said, this is not really recommended... It's just another way of doing it.
I thought it might be interesting to share it.
As an example, you can use this solution if the UI already exists, but you can't access the code that creates it.
Otherwise, I would do like suggested in the other answers, creating handlers functions.
PS : This will only works with maya2014 and above, or a maya with PyQt installed !

Trouble importing files in Python

I'm just finding out now that when importing a module, it seems to run through ALL the code, instead of just the one function that I want it to go through. I've been trying to find a way around this, but can't seem to get it. Here is what is happening.
#mainfile.py
from elsewhere import something_else
number = 0
def main():
print('What do you want to do? 1 - something else')
donow = input()
if donow == '1':
something_else()
while 1:
main()
#elsewhere.py
print('I dont know why this prints')
def something_else():
from mainfile import number
print('the variable number is',number)
Now, although this code KIND OF works the way I want it to, the first time when I initiate it, it will go to the main menu twice. For example: I start the program, press one, then it asks me what I want to do again. If I press one again, then it will print "the variable number is 0".
Once I get this working, I would like to be importing a lot of variables back and forth. The only issue is,if I add more import statements to "elsewhere.py" I think it will just initiate the program more and more. If I put "from mainfile import number" on line 1 of "elsewhere.py", I think this raises an error. Are there any workarounds to this? Can I make a different file? What if I made a class to store variables, if that is possible? I'm very new to programming, I would appreciate it if answers are easy to read for beginners. Thank you for the help.
As Jan notes, that's what import does. When you run import, it runs all of the code in the module. You might think: no it doesn't! What about the code inside something_else? That doesn't get run! Right, when the def statement is executed it creates a new function, but it doesn't run it. Basically, it saves the code for later.
The solution is that pretty much all interesting code should be in a function. There are a few cases which make sense to put at the top-level, but if in doubt, put it inside a function. In your particular case, you shouldn't be printing at the top level, if you need to print for some reason, put that into a function and call it when you need it. If you care when something happens, put it in a function.
On a second node, don't import your primary script in other scripts. I.e. if your mainfile.py directly, don't import that in other files. You can but it produces confusing results, and its really best to pretend that it doesn't work.
Don't try to import variables back and forth. Down that path lies only misery. You should only be importing things that don't change. Functions, classes, etc. In any other case, you'll have hard time making it do what you want.
If you want to move variables between places, you have other options:
Pass function arguments
Return values from a function
Use classes
I'll leave it is an exercise to the reader to learn how to do those things.
import executes imported code
import simply takes the Python source file and executes it. This is why it prints, because that instruction is in the code and with import all the instructions get exectued.
To prevent execution of part of imported package/module, you shall use the famous:
if __name__ == "__main__":
print("I do not print with `import`")
Note, that this behaviour is not new in Python 3, it works the same way in Python 2.x too.

How do you pass a value from VBA to python

I have a VBA toolbar that i have been working on. It has two buttons, and near the end of the process, it calls a python script.
What I want to do is depending on which of the two buttons is clicked, a certain part of the python script will run, so I want to pass a value that is linked to the button which is then sent to the python script and run.
How do I do this?
Thanks
You can pass command line options to the python script, just like you can with other command line programs. Depending on which button was pressed, pass different switches to your program.
In your case, it may be simplest just to pass in one value on the command line depending on the button that was pressed and pick this from the sys.argv variable:
import sys
def fooClicked():
# Stuff to do when Foo was clicked
def barClicked():
# Stuff to do when Bar was clicked
button = sys.argv[1]
if button == 'foo':
fooClicked()
elif button == 'bar':
barClicked()
(You could use a dict to look up methods but that may be too advanced, don't know how comfortable you are with Python).
So, if you call this script with python.exe H:\Report_v7.py foo the fooClicked function will be called.
If this is going to grow to more than just two buttons, I'd use the optparse module to define your options and run different code paths depending on the options chosen.
If you upgrade to Python 2.7, then use the new (better) argparse module instead.

Categories