I have a check button in my program. when I click the check button, the var value is always 0. Shouldn't the value be 1 when clicked. It works in a small program that i made but when I try to get a check button value in my big program, the value is always 0 no matter how many times I click the checkbutton. The following code is the small example program that I wrote which works just fine but when I try to get the var value in my bigger program, the value is always 0.
from tkinter import *
root = Tk()
root.geometry("400x400")
def check():
global var2
var2 = IntVar()
c=Checkbutton(root, text="click me", variable=var2, command=show)
c.pack()
myButton=Button(root, text="show selection", command=show).pack()
def show():
myLabel = Label(root, text=var2.get()).pack()
check()
root.mainloop()
Well, I figured it out. Well, thanks to Google. When opening up a new window instead of calling Tk() I changed it to Toplevel() and it finally worked. Thanks for all of your input.
You needed to use BooleanVar(). Hope it helps.
from tkinter import *
root = Tk()
root.geometry("400x400")
def check():
global var2
var2 = BooleanVar()
c=Checkbutton(root, text="click me", variable=var2, command=show)
c.pack()
myButton=Button(root, text="show selection", command=show).pack()
def show():
myLabel = Label(root, text=int(var2.get())).pack()
# commented out the lower label, it returned False instead of one.
# It's always a good idea to force variables to be what they should be.
# myLabel = Label(root, text=var2.get()).pack()
check()
root.mainloop()
Related
I would like to have a window with a single button (with text "Click"). When I click the button a new window should open. And in that second window I would like to have 2 radiobuttons and a button (with text "Print"). Clicking that button ("Print") should print the current value of the variable my_variable, which indicates which Radiobutton is choosen.
The first code is missing the first window, but it prints out the correct values. The second code, where I added the first window (with the button "Click" opening the second window) prints always the default value of the variable my_variable. What should I change to get the current value every time a press the button "Print"?
I use tkinter with Python 3.7.
Working code:
import tkinter as tk
def function():
"""That function print the current value of my_variable, depending on which radiobutton was choosen."""
value = my_variable.get()
print(value)
window = tk.Tk()
window.title("Title")
window.geometry('200x200')
my_variable = tk.IntVar(value=0)
rbtn1 = tk.Radiobutton(window, text='one', value=1, variable=my_variable)
rbtn1.grid(row=0, column=0)
rbtn2 = tk.Radiobutton(window, text='two', value=2, variable=my_variable)
rbtn2.grid(row=1, column=0)
button = tk.Button(window, text="Print", command=function)
button.grid(row=2, column=0)
window.mainloop()
Not working code:
import tkinter as tk
def on_click():
def function():
"""That function shoud print the current value of my_variable, depending on which radiobutton was choosen. But it prints the default value instead."""
value = my_variable.get()
print(value)
window = tk.Tk()
window.title("Title")
window.geometry('200x200')
my_variable = tk.IntVar(value=0)
rbtn1 = tk.Radiobutton(window, text='one', value=1, variable=my_variable)
rbtn1.grid(row=0, column=0)
rbtn2 = tk.Radiobutton(window, text='two', value=2, variable=my_variable)
rbtn2.grid(row=1, column=0)
button = tk.Button(window, text="Print", command=function)
button.grid(row=2, column=0)
window_main = tk.Tk()
window_main.title("Title main")
window_main.geometry('400x400')
button = tk.Button(window_main, text="Click", command=lambda: on_click())
button.grid(row=0, column=0)
window_main.mainloop()
The problem is you're calling tk.Tk() twice. When you want to create another window, use tk.Toplevel() instead.
To avoid needing to do that, just change the one line indicated below:
import tkinter as tk
def on_click():
def function():
"""That function should print the current value of my_variable, depending on which radiobutton was chosen. But it prints the default value instead."""
value = my_variable.get()
print(value)
window = tk.Toplevel() ##### CHANGED.
window.title("Title")
window.geometry('200x200')
my_variable = tk.IntVar(value=0)
rbtn1 = tk.Radiobutton(window, text='one', value=1, variable=my_variable)
rbtn1.grid(row=0, column=0)
rbtn2 = tk.Radiobutton(window, text='two', value=2, variable=my_variable)
rbtn2.grid(row=1, column=0)
button = tk.Button(window, text="Print", command=function)
button.grid(row=2, column=0)
window_main = tk.Tk()
window_main.title("Title main")
window_main.geometry('400x400')
button = tk.Button(window_main, text="Click", command=lambda: on_click())
button.grid(row=0, column=0)
window_main.mainloop()
If you want to understand why you should avoid calling Tk() more than once, see the answer to Why are multiple instances of Tk discouraged?
See:
When you click a button in the main window, it calls on_click.
Inside on_click, you every time reassign the variable value: my_variable = tk.IntVar(value=0).
This is why the value of my_variable is not preserved between clicks of the button in the main window.
You need to keep my_variable outside on_click, and initialize it once, not on every click.
A nice way to do that is to make on_click accept it as a parameter: def on_click(my_variable), and command=lambda: on_click(my_variable).
A quick and pretty dirty way is to use global; it's acceptable in a throwaway script, but will quickly become ugly and hard to reason about.
I'm new to trying out python GUI's and tried tkinter and pyglet, but only through tutorials, in-order-to understand the basic classes and functions. But what I'm currently trying to do is to get a button to increase a number whilst displaying that number at the same time. Somehow, even though the variable number was stated globally as 0, the function to increase it doesn't do anything, it actually produces an error: 'UnboundLocalError: local variable 'number' referenced before assignment'. I have no idea how to correct this.
The tutorials I've seen on both YouTube and as an article, don't talk about how to do this exactly. The article does mention how to change a certain text though, but not a previously created variable (which in my case would be 'number').
from tkinter import *
number = 0
window = Tk()
window.title("Programme")
window.geometry('350x250')
label = Label(window, text=number)
label.grid(column=0,row=0)
def clicked():
number += 1
button = Button(window, text="Push Me", command=clicked)
button.grid(column=1, row=2)
window.mainloop()
Is there any way to do this?
Also I've been looking for how to add time, to handle events and such, through ticks. But everything I find on the internet is about literally displaying a clock on the GUI, which is useless, or at least I don't know how to use it to have a ticking function.
You need to increment the number, like you do, but also update the Label to display the new number:
from tkinter import *
number = 0
window = Tk()
window.title("Programme")
window.geometry('350x250')
label = Label(window, text=number)
label.grid(column=0,row=0)
def clicked():
global number
number += 1
label.config(text=number)
button = Button(window, text="Push Me", command=clicked)
button.grid(column=1, row=2)
window.mainloop()
An easier way to do this is to use tkinter's version of an integer: IntVar. It takes care of the Label updates automatically, but it requires you use get() and set() to work with it.
from tkinter import *
def clicked():
number.set(number.get()+1)
window = Tk()
window.title("Programme")
window.geometry('350x250')
number = IntVar()
label = Label(window, textvariable=number)
label.grid(column=0,row=0)
button = Button(window, text="Push Me", command=clicked)
button.grid(column=1, row=2)
window.mainloop()
Here is my entire code:
from tkinter import *
def up():
number.set(number.get()+1)
def down():
number.set(number.get()-1)
window = Tk()
window.title("Programme")
window.geometry('350x250')
number = IntVar()
frame = Frame(window)
frame.pack()
entry = Entry(frame, textvariable=number, justify='center')
entry.pack(side=LEFT, ipadx=15)
buttonframe = Frame(entry)
buttonframe.pack(side=RIGHT)
buttonup = Button(buttonframe, text="▲", font="none 5", command=up)
buttonup.pack(side=TOP)
buttondown = Button(buttonframe, text="▼", font="none 5", command=down)
buttondown.pack(side=BOTTOM)
window.mainloop()
It looks better for me when the buttons are inside of the entry widget directly.
I'm a having a problem that I can't check if the checkbutton in tkinter is checked or not (I always get False).
I'm sure I'm missing something but I've tried for so long and I don't know what I'm doing wrong.
Bellow is the minimum code I could write that shows the problem:
There are two files:
The main file (that you run) is called "main_GUI.py" and here's the code:
from tkinter import *
import sub_GUI
root = Tk()
button1 = Button(root, bg='white', text="Click me", font=("Helvetica",12),
height=3, width=25, command=sub_GUI.create_new_window)
button1.grid(column=1, row=1)
root.mainloop()
The second file is called "sub_GUI.py" and here's the code:
from tkinter import *
var1 = None
sub_root = None
def create_widgets():
global sub_root
global var1
var1 = BooleanVar()
Checkbutton(sub_root,
text="A",
variable=var1,
command=do_something
).grid(row=2, column=0, sticky=W)
def do_something():
global var1
is_current_joint_checked = var1.get()
if is_current_joint_checked:
print('True')
else:
print('False')
def create_new_window():
global sub_root
sub_root = Tk()
sub_root.title("Movie Chooser")
create_widgets()
The problem is that in the window that appears with the letter 'A' (after you clicked the button), every time I check/uncheck 'A' it prints False (never prints True).
Can anyone tell me what's the problem?
Thanks
I use Tkinter for make a GUI. I have a window with 2 radiobutton ('Yes' and 'No'), but when I select one, it don't run the script :
root = Tk()
Button(root, text='TEST', command=root.quit).pack()
root.mainloop()
master = Tk()
v = IntVar()
Radiobutton(master, text='Yes', variable=v, value=0).pack()
Radiobutton(master, text='No', variable=v, value=1).pack()
Button(master, text='Exit', command=master.quit).pack()
master.mainloop()
print(v.get())
if v.get() == 0:
testy = Tk()
Label(testy, text='Bad').pack()
testy.mainloop()
else:
testn = Tk()
Label(testn, text='Bad').pack()
testn.mainloop()
If I don't have the first window, it works but with it, it don't.
Somebody know how to fix this problem ?
You have initiated several Tk() systems, but there should be only one.
If you want to get a new window then use Toplevel()
No code is executed after mainloop() except for events. The code continues to "flow" after mainloop only after closing the windows.
So here is your code with fixes:
from tkinter import *
root = Tk()
Button(root, text='TEST', command=root.quit).pack()
master = Toplevel()
v = IntVar()
def check_radio():
print(v.get())
if v.get() == 0:
Label(Toplevel(), text='Bad').pack()
else:
Label(Toplevel(), text='Good').pack()
Radiobutton(master, text='Yes', variable=v, value=0, command=check_radio).pack()
Radiobutton(master, text='No', variable=v, value=1, command=check_radio).pack()
Button(master, text='Exit', command=master.quit).pack()
root.mainloop()
Check carefully, I changed the parents of widgets and other changes.
Possible duplicate of tkinter radiobutton not updating variable, but seeing as this question was asked first the answer may make more sense here.
Make sure you are assigning a master to the IntVar like self.rbv=tk.IntVar(master) #or 'root' or whatever you are using):
import Tkinter as tk
import ttk
class My_GUI:
def __init__(self,master):
self.master=master
master.title("TestRadio")
self.rbv=tk.IntVar(master)#<--- HERE! notice I specify 'master'
self.rb1=tk.Radiobutton(master,text="Radio1",variable=self.rbv,value=0,indicatoron=False,command=self.onRadioChange)
self.rb1.pack(side='left')
self.rb2=tk.Radiobutton(master,text="Radio2",variable=self.rbv,value=1,indicatoron=False,command=self.onRadioChange)
self.rb2.pack(side='left')
self.rb3=tk.Radiobutton(master,text="Radio3",variable=self.rbv,value=2,indicatoron=False,command=self.onRadioChange)
self.rb3.pack(side='left')
def onRadioChange(self,event=None):
print self.rbv.get()
root=tk.Tk()
gui=My_GUI(root)
root.mainloop()
try running that, click the different buttons (they are radiobuttons but with indicatoron=False) and you will see it prints correctly changed values!
I'm trying to use an Entry field to get manual input, and then work with that data.
All sources I've found claim I should use the get() function, but I haven't found a simple working mini example yet, and I can't get it to work.
I hope someone can tel me what I'm doing wrong. Here's a mini file:
from tkinter import *
master = Tk()
Label(master, text="Input: ").grid(row=0, sticky=W)
entry = Entry(master)
entry.grid(row=0, column=1)
content = entry.get()
print(content) # does not work
mainloop()
This gives me an Entry field I can type in, but I can't do anything with the data once it's typed in.
I suspect my code doesn't work because initially, entry is empty. But then how do I access input data once it has been typed in?
It looks like you may be confused as to when commands are run. In your example, you are calling the get method before the GUI has a chance to be displayed on the screen (which happens after you call mainloop.
Try adding a button that calls the get method. This is much easier if you write your application as a class. For example:
import tkinter as tk
class SampleApp(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
self.entry = tk.Entry(self)
self.button = tk.Button(self, text="Get", command=self.on_button)
self.button.pack()
self.entry.pack()
def on_button(self):
print(self.entry.get())
app = SampleApp()
app.mainloop()
Run the program, type into the entry widget, then click on the button.
You could also use a StringVar variable, even if it's not strictly necessary:
v = StringVar()
e = Entry(master, textvariable=v)
e.pack()
v.set("a default value")
s = v.get()
For more information, see this page on effbot.org.
A simple example without classes:
from tkinter import *
master = Tk()
# Create this method before you create the entry
def return_entry(en):
"""Gets and prints the content of the entry"""
content = entry.get()
print(content)
Label(master, text="Input: ").grid(row=0, sticky=W)
entry = Entry(master)
entry.grid(row=0, column=1)
# Connect the entry with the return button
entry.bind('<Return>', return_entry)
mainloop()
*
master = Tk()
entryb1 = StringVar
Label(master, text="Input: ").grid(row=0, sticky=W)
Entry(master, textvariable=entryb1).grid(row=1, column=1)
b1 = Button(master, text="continue", command=print_content)
b1.grid(row=2, column=1)
def print_content():
global entryb1
content = entryb1.get()
print(content)
master.mainloop()
What you did wrong was not put it inside a Define function then you hadn't used the .get function with the textvariable you had set.
you need to put a textvariable in it, so you can use set() and get() method :
var=StringVar()
x= Entry (root,textvariable=var)
Most of the answers I found only showed how to do it with tkinter as tk. This was a problem for me as my program was 300 lines long with tons of other labels and buttons, and I would have had to change a lot of it.
Here's a way to do it without importing tkinter as tk or using StringVars. I modified the original mini program by:
making it a class
adding a button and an extra method.
This program opens up a tkinter window with an entry box and an "Enter" button. Clicking the Enter button prints whatever is in the entry box.
from tkinter import *
class mini():
def __init__(self):
master = Tk()
Label(master, text="Input: ").grid(row=0, sticky=W)
Button(master, text='Enter', command=self.get_content).grid(row=1)
self.entry = Entry(master)
self.entry.grid(row=0, column=1)
master.mainloop()
def get_content(self):
content = self.entry.get()
print(content)
m = mini()