I am trying to create checkbox with default value True,but it's not working, I tried plenty of the answers but didn't work
import tkinter as tk
class App(tk.Tk):
def __init__(self):
super().__init__()
self.title("Test v1")
self.geometry("400x250")
self.build_init()
def build_init(self):
#CheckVar = tk.BooleanVar(self,)
CheckVar = tk.IntVar(value=1)
checkbutton = tk.Checkbutton(self, text = "Test", variable = CheckVar,onvalue=1, offvalue=0)
#checkbutton.select()
checkbutton.place(x=20,y=80)
App().mainloop()
I coouln't find much on it in the documentaion other than select which didn't work, Also on this question Tkinter: is there a way to check checkboxes by default?
import tkinter as tk
class App(tk.Tk):
def __init__(self):
super().__init__()
self.title("Test v1")
self.geometry("400x250")
self.build_init()
def build_init(self):
#CheckVar = tk.BooleanVar(self,)
self.CheckVar = tk.IntVar(value=1)
self.checkbutton = tk.Checkbutton(self, text = "Test", variable = self.CheckVar,onvalue=1, offvalue=0)
#checkbutton.select()
self.checkbutton.place(x=20,y=80)
App().mainloop()
Related
I'm trying to set up a list of checkbuttons from top to bottom in the GUI and add up the associated "onvalues" for each of the checkbuttons that are on.
My problem now is that for some reason my 'command' attribute in my 'calcbutton' is giving me a "Name 'calc_cost' is not defined" error.
I've added a bunch of imports that you see at the top of the code hoping that would solve the problem, to not much avail.
import tkinter as tk
from tkinter import *
from tkinter import Button
servicelist = ("Oil change","Lube job","Radiator flush","Transmission flush","Inspection","Muffler replacement","Tire rotation")
servicecost = (30,20,40,100,35,200,20)
a = 0
class Window(Frame):
def __init__(self, master=None):
Frame.__init__(self, master)
self.master = master
self.init_window()
def calc_cost(self):
print(a)
def init_window(self):
self.master.title("GUI")
self.pack(fill=BOTH, expand=1)
for i in range(len(servicelist)):
serviceButton = Checkbutton(self, text=servicelist[i], onvalue = servicecost[i], var = a)
serviceButton.place(x=0, rely = i*.1)
calcButton = tk.Button(self, text = "Calculate Cost", fg = "black", bg = "green", command = calc_cost)
calcButton.pack(side = "bottom")
root = Tk()
#size of the window
root.geometry("400x300")
app = Window(root)
root.mainloop()
The checkbuttons pop up and the GUI works for the most part besides the displaying of the 'calcbutton' as well as getting the "NameError: name 'calc_cost' is not defined"
Change command = calc_cost to command = self.calc_cost
self represents the instance of the class. By using the self keyword we can access the attributes and methods of the class in python.
It will give you this output
class First_Frame(Frame):
def __init__(self,master):
super().__init__(master)
self.grid()
self.widgets()
def widgets(self):
self.commandent1=StringVar()
self.commandent1.set("tutaj bedzie sie pokazywal aktualny status")
self.img=Image.open("database.XPM","r")
self.image_true=ImageTk.PhotoImage(self.img)
self.label=Label(self,image=self.image_true).grid()
self.label2=Label(self,text="twoje gui uzytkownika").grid()
self.widgets_2()
def widgets_2(self):
self.status_text=Label(self,text=self.commandent1.get())
self.entry1=Entry(self)
self.entry1.bind("<Return>",self.update_status)
self.entry1.grid()
self.status_text.grid()
def update_status(self):
self.x=self.entry1.get()
self.commandent1.set(self.x)
You have 2 main reasons your Label (not text) widget is not updating.
Reason 1. You need to handle the event that is being passed to update_status from the binding. To do this just add event or any argument name really you want. I just use event for readability.
def update_status(self, event):
Reason 2. You need to and the less obvious reason here for some is the way you are using your StringVar() on the label widget. Here you are assigning the current text value of the StringVar() only once and never again. To properly use the StringVar() with a label widget you will need to assign the StringVar() to a textvariable argument and not a text argument.
Like this:
Label(self,textvariable=self.commandent1).grid()
Note I took out the image portion of your code as it was irrelevant to the question. Your final code should look something like this:
from tkinter import *
class First_Frame(Frame):
def __init__(self, master):
super().__init__()
self.grid()
self.widgets()
def widgets(self):
self.commandent1 = StringVar()
self.commandent1.set("tutaj bedzie sie pokazywal aktualny status")
Label(self,text="twoje gui uzytkownika").grid()
self.widgets_2()
def widgets_2(self):
self.entry1 = Entry(self)
self.entry1.bind("<Return>", self.update_status)
self.entry1.grid()
Label(self,textvariable=self.commandent1).grid()
def update_status(self, event):
self.commandent1.set(self.entry1.get())
root = Tk()
First_Frame(root)
root.mainloop()
This question already has an answer here:
Passing argument to a function via a Button in Tkinter, starnge behaviour in loop [duplicate]
(1 answer)
Closed 4 years ago.
I'm trying to make a simple interface with 3 buttons, and each button should trigger an action based on its label. However, even though (I think) I'm passing the correct argument, it always passes the label of the last button. Here's a stripped-down version to show what's happening:
import tkinter as tk
import random
class Application(tk.Frame):
def __init__(self, window=None):
super().__init__(window)
self.labels = ['Washington','London','Paris','Rome','Berlin','Madrid']
self.buttons = [tk.Button(self),tk.Button(self),tk.Button(self)]
self.pack()
for k,button in enumerate(self.buttons):
button.config(width=10)
button.grid(row=0, column=k)
self.update_buttons()
def update_buttons(self):
labels = list(random.sample(self.labels,3))
random.shuffle(labels)
for label,button in zip(labels,self.buttons):
button["text"] = label
button["command"] = lambda: self.verify(label)
def verify(self, label):
print(f'You pressed the button with label {label}')
self.update_buttons()
window = tk.Tk()
app = Application(window=window)
app.mainloop()
Why?
You are encountering a (late biding) closure problem.
When you create a function using lambda, a closure is created. This means the variables in function's body are looked up at the time you call the lambda, not when you create it (and the scope in which lambda was created will contain variable with the final value that was assigned).
In order to prevent this, you need to create an argument and set it to a default value, which stores the current value of the variable at creation time.
import tkinter as tk
import random
class Application(tk.Frame):
def __init__(self, window=None):
super().__init__(window)
self.labels = ['Washington','London','Paris','Rome','Berlin','Madrid']
self.buttons = [tk.Button(self),tk.Button(self),tk.Button(self)]
self.pack()
for k,button in enumerate(self.buttons):
button.config(width=10)
button.grid(row=0, column=k)
self.update_buttons()
def update_buttons(self):
labels = list(random.sample(self.labels,3))
random.shuffle(labels)
for label,button in zip(labels,self.buttons):
button["text"] = label
button["command"] = lambda label=label: self.verify(label) # Here
def verify(self, label):
print(f'You pressed the button with label {label}')
self.update_buttons()
window = tk.Tk()
app = Application(window=window)
app.mainloop()
You can also use functools.partial, which looks cleaner in my opinion:
import tkinter as tk
import random
from functools import partial
class Application(tk.Frame):
def __init__(self, window=None):
super().__init__(window)
self.labels = ['Washington','London','Paris','Rome','Berlin','Madrid']
self.buttons = [tk.Button(self),tk.Button(self),tk.Button(self)]
self.pack()
for k,button in enumerate(self.buttons):
button.config(width=10)
button.grid(row=0, column=k)
self.update_buttons()
def update_buttons(self):
labels = list(random.sample(self.labels,3))
random.shuffle(labels)
for label,button in zip(labels,self.buttons):
button["text"] = label
button["command"] = partial(self.verify, label)
def verify(self, label):
print(f'You pressed the button with label {label}')
self.update_buttons()
window = tk.Tk()
app = Application(window=window)
app.mainloop()
You need to assign a parameter to the lambda function, and pass it as argument to the function.
import tkinter as tk
import random
class Application(tk.Frame):
def __init__(self, window=None):
super().__init__(window)
self.labels = ['Washington','London','Paris','Rome','Berlin','Madrid']
self.buttons = [tk.Button(self),tk.Button(self),tk.Button(self)]
self.pack()
for k,button in enumerate(self.buttons):
button.config(width=10)
button.grid(row=0, column=k)
self.update_buttons()
def update_buttons(self):
labels = list(random.sample(self.labels,3))
random.shuffle(labels)
for label,button in zip(labels,self.buttons):
button["text"] = label
button["command"] = lambda lbl=label: self.verify(lbl) # <-- here
def verify(self, label):
print(f'You pressed the button with label {label}', flush=True) # <-- added flush=True to ensure the printing is done as the moment you click
self.update_buttons()
window = tk.Tk()
app = Application(window=window)
app.mainloop()
I am creating a Tkinter program that allows the user to enter text into a nice looking box rather than the python shell.
As I would like to use this in multiple programs I made into a function that can be used in other files.
I can get it to run in another file, but not import the variable here is my code.
File 1:
import tkinter as tk
def input_text(label_text, button_text):
class SampleApp(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
self.entry = tk.Entry(self)
self.button = tk.Button(self, text=button_text, command=self.on_button)
self.label = tk.Label(self, text=label_text)
self.label.pack(side = 'top', pady = 5)
self.button.pack(side = 'bottom', pady = 5)
self.entry.pack()
def on_button(self):
answer = self.entry.get()
self.destroy()
w = SampleApp()
w.resizable(width=True, height=True)
w.geometry('{}x{}'.format(180, 90))
w.mainloop()
File 2:
import text_input as ti
from text_input import answer
ti.input_text('Enter some text', 'OK')
I get the error ImportError: cannot import name 'answer'
answer is a local variable withinbutton. If you want toimport` it, you need to make it a package attribute:
import tkinter as tk
global answer
def input_text(label_text, button_text):
class SampleApp(tk.Tk):
...
def on_button(self):
global answer
answer = self.entry.get()
However, this is a very strange way to access the data. Clean module design would likely have the object (SampleApp) at hand, and extract the answer with a method call for that app. More simply, why not just return that value from on_button?
def on_button(self):
answer = self.entry.get()
self.destroy()
return answer
... so your usage would be
response = my_app.on_button()
I have seen many explanations of how to turn an enabled button disabled but not when classes are involved. The error here is in the line 'button_1.config...' and the error message is that button_1 is not defined. I think this is because it is in a different method but im not sure how to disable a button from a different method. any help is appreciated.
from tkinter import *
class menu:
def __init__(self, master):
self.master = master
button_1 = Button(self.master, text = 'test', command = self.correct).pack()
def correct(self):
button_1.config(state = DISABLED)
def window():
root = Tk()
menu(root)
root.mainloop()
if __name__ == '__main__':
window()
The button needs to be an instance variable, if you're accessing it between methods in the class. Just add self. in front of it. It's also going to need to be packed on a separate line, otherwise the instance variable self.button_1 will return None:
class menu:
def __init__(self, master):
self.master = master
self.button_1 = Button(self.master, text = 'test', command = self.correct)
self.button_1.pack()
def correct(self):
self.button_1.config(state = DISABLED)