This comes from a button that when pressed generates a radiobutton. I am not able to access to the choice made with radiobutton. Everything works fine, but the output of selected function is zero. I try using both local and global var but the result is the same.
def callback_st(): # RadioButton select technology
var = IntVar()
m=0
for m in range(len(un_tech)):
Radiobutton(radio_frame, text=un_tech[m], value=m, variable=var,
command=selected(var)).pack(anchor=W)
def selected(var):
print(var)
This doesn't work. I solved using lambda:
def selected(jst):
global sel_technology
sel_technology=un_tech[jst]
print(sel_technology)
def callback_st(): #RadioButton select technology
var_st = IntVar()
m=0
for m in range(len(un_tech)):
Radiobutton(radio_frame, text=un_tech[m], value=m, variable=var_st,
command = lambda jst=m: selected(jst)).pack(anchor=W)
This works as i want, but it isn't the solution that i want and i think is not the correct way. So, somebody can help me to find the right way?
In your first try, you call selected immediately, when var has a value of 0. You avoided this with the lambda expression, but you are correct that this is an awkward workaround for the original mistake. Make var global and have selected access it as a global. Modifying your first code:
var = IntVar()
def selected():
print(var.get())
def callback_st():
...
...command=selected...
If you were defining a class and methods, var would be an instance attribute instead of global.
Related
I would like to make a Button that assign a new variable with a value in a compact form.
I tried this:
def whichButton(self, _var, _pressedButton):
self._var = _pressedButton
def checkScooter(self):
self.checkScooter = Button(window, text="Standard", command=lambda: self.whichButton(edition, 1))
self.checkScooter(row=1, column=0)
def checkAbonnement(self):
self.checkAbonnement = Button(window, text="Gold", command=lambda: self.whichButton(abonnement, 3))
self.checkAbonnement(row=1, column=0)
It just gives me an error, that "edition" is not defined, but I want the Button to define it
Any tips?
Your request to set a new variable is odd, and probably not the right solution to whatever problem you're trying to solve.
That being said, you can use setattr to set the value based on the name of a variable. That variable doesn't have to exist. For example, to set the variable self.edition to 1 you can do setattr(self, "edition", 1).
Therefore, you can pass in the string name of the variable to your whichButton function, and use setattr to set a variable with that name.
It would look something like this:
def whichButton(self, _var, _pressedButton):
setattr(self, _var, _pressedButton)
...
self.checkScooter = Button(..., command=lambda: self.whichButton("edition", 1))
...
self.checkAbonnement = Button(..., command=lambda: self.whichButton("abonnement", 3))
In the above code, clicking either button will either set self.edition or self.abonnement.
There is almost certainly a better solution to your problem, but your question doesn't provide any details about what problem you're really trying to solve. A simple mprovement over this would be to use a dictionary to hold your "new" variables rather than creating literally new variables.
You can do that by defining a dictionary in your __init__ and then setting it in your whichButton function.
It would look something like this:
class Something:
def __init__(self):
self._vars = {}
def whichButton(self, name, new_value):
self._vars[name] = new_value
This has the advantage that all of these special variables exist in a single data structure, separate from the object. That means that it would be impossible to accidentally overwrite instance variables.
I am currently working an a snake game, but I first want a settings window to show up.i used tkinter for this. In smaller projekts I just wrote all of the code into the pressButton function, but I want to have non spagetti code now, so im not going with that. The problem is, that I have no idea how to get the entered values in the entry brackets into my main code, as global variables, out of the pressButton function and the settingsWin function. The problem is that I use the function as a command for the Button, so I cannt use "return". Can you change global variables in the main code direcktly from inside of a function? If yes how? Or is there another way to solve this?
My Code:
def settingsWin():
def pressButton():
len = entryLen.get()
wid = entryWid.get()
speed = entrySpeed.get()
print(len+wid+speed)
SettingsWin.destroy()
return len
SettingsWin = Tk()
SettingsWin.geometry("600x600")
SettingsWin.title("Settings")
label1 = Label(SettingsWin, text="playing field [tiles]")
label1.pack()
entryLen = Entry(SettingsWin, bd=2, width=20)
entryLen.pack()
label2 = Label(SettingsWin, text="X")
label2.pack()
entryWid = Entry(SettingsWin, bd=2, width=20)
entryWid.pack()
labelblanc = Label(SettingsWin, text="")
labelblanc.pack()
label3 = Label(SettingsWin, text="Speed [ms per tick]")
label3.pack()
entrySpeed = Entry(SettingsWin, bd=2, width="20")
entrySpeed.pack()
okButton = Button(SettingsWin, text="OK", command=pressButton)
okButton.pack()
SettingsWin.mainloop()
len = "len"
wid = "wid"
speed = "speed"
It is often indicative of code smell to require that a function alter variables at scopes outside the function (except possibly in the case of closures, which are quite useful), it is possible to do so using the global keyword:
greeting = "Hello world!"
def greet():
global greeting
greeting = "Goodbye world!"
print(greeting)
greet()
print(greeting)
By declaring the variable greeting to be of global scope, altering the variable within the function definition allows the function to affect the global variable.
If you are working within nested subs, the nonlocal keyword will provide access within the inner sub, to the variable in the outer sub. It works similar to global, except that it is for broader lexical scope, not global scope.
I'm working hard to solve this problem, can someone help me ?
There is what I mean by 'set' an argument:
from tkinter import *
window = Tk()
I=1
def add():
global I
menu1.add_command(label=I, command=lambda:Text(I))
I=I+1
def Text(I):
print(I)
menubar = Menu(window)
menu1 = Menu(menubar, tearoff=0)
menu1.add_command(label="Add", command=add)
menu1.add_separator()
menu1.add_command(label="Quit", command=window.quit)
menubar.add_cascade(label="Files", menu=menu1)
window.config(menu=menubar)
window.mainloop()
I want when we click on add and after on '1' it print '1', and when we add '2' and click on it, it print '2' but it always print the value of I, how can I set the argument by
menu1.add_command(label=I, command=lambda:Text(1))
for exemple ?
I don't know if I'm clear but I don't know how explain it !
Change your Text function to be a closure:
def Text(I):
def inner():
print(I)
return inner
Then change your add function to be this:
def add():
global I
text = Text(I)
menu1.add_command(label=I, command=text)
I=I+1
This will save the I in the text variable. The text variable is actually a function, inner, that will print I when called.
Or you could make your closure inline if you wanted to use the Text function somewhere else:
import functools
...
menu1.add_command(label=I, command=functools.partial(Text, i))
I think your problem is the lambda:Text(I). In this case, you have created a closure, but the closure knows I to be a global and is evaluating it at a later date.
You probably want to immediately evaluate Text(I) and use that as your result:
texti = Text(I) # Immediate evaluation
menu1.add_command(label=I, command=lambda:texti) # Return prior value of "I"
The idea of this code is, the user presses the first button and enters what they want, then they press the second button and it prints it out. Can someone please tell me why my return statement is not working? It says that 'variable' is not defined. Thanks in advance for taking the time to read my question.
from tkinter import*
def fun():
variable = input('Enter Here:')
return variable
def fun_2():
print(variable)
window = Tk()
button = Button(text = 'Button', command = fun )
button2 = Button(text = 'Button2', command = fun_2 )
button.pack()
button2.pack()
window.mainloop()
In python when you create a variable inside of a function, it is only defined within that function. Therefore other functions will not be able to see it.
In this case, you will probably want some shared state within an object. Something like:
class MyClass:
def fun(self):
self.variable = input('Enter Here:')
def fun_2(self):
print(self.variable)
mc = MyClass()
window = Tk()
button = Button(text = 'Button', command = mc.fun )
button2 = Button(text = 'Button2', command = mc.fun_2 )
button.pack()
button2.pack()
fun() may return a value, but Tkinter buttons don't do anything with that return value.
Note that I used the phrase return a value, not return a variable. The return statement passes back the value of an expression, not the variable variable here. As such, the variable variable is not made into a global that other functions then can access.
Here, you can make variable a global, and tell fun to set that global:
variable = 'No value set just yet'
def fun():
global variable
variable = input('Enter Here:')
Since you did use any assignment in fun2, variable there is already looked up as a global, and it'll now successfully print the value of variable since it now can find that name.
The problem is in in fun2(). It does not get variable as an input parameter.
def fun_2(variable):
print(variable)
But note that you have to call fun_2 now with the appropriate argument. Also, as the function stands right now, there is little point in having the function if you just do a print inside of it.
Take away message: variable is not global in Python, and as such you must pass it to each function that wants to use it.
I keep getting this error "global name v is not defined." I know this has most likely been heavily documented, however none of the other threads were very relavant to my GUI situation. Anyway, here we go:
v_amount= 5000
def set_v_to_something_else():
global v
v_amount=v_amount-1000
v.set(v_amount)
v = StringVar()
v.set(str(v_amount))
#create button that will allow v label to be set to something else
vbutton = Button(root, text = "change v", command = set_v_to_something_else).pack()
vlabel = Label(root, textvariable=v).pack()
Once again, it says that v is not defined, even though i set it equal to StringVar()
Thanks in advance
Perhaps you are getting the error
global name v_amount is not defined
That would be because, in this code,
v_amount= 5000
def set_v_to_something_else():
global v
v_amount=v_amount-1000
v.set(v_amount)
when Python parses the function set_v_to_something_else, it marks v_amount as a local variable because it appears on the left-hand side of an assignment:
v_amount=v_amount-1000
Later, when the function is called, since Python regards v_amount as a local variable, it tries to evaluate the right-hand side of the assignment statement first and finds v_amount is not defined. (Remember, it is looking for it in the local namespace, not the global namespace.)
The fix is to add global v_amount inside the function:
def set_v_to_something_else():
global v_amount
v_amount = v_amount-1000
v.set(v_amount)
You can also remove
global v
because you are not assigning a new value to v. v.set is merely calling a method of v.
v_amount= 5000
# you need to define variable 'v' here,
# before you define function that uses it
def set_v_to_something_else():
global v
v_amount=v_amount-1000
v.set(v_amount)
v = StringVar()
v.set(str(v_amount))
#create button that will allow v label to be set to something else
vbutton = Button(root, text = "change v", command = set_v_to_something_else).pack()
vlabel = Label(root, textvariable=v).pack()