I am building a very base movie recommendation GUI in python and I am trying to have it open a new window when a genre is selected. I am able to open the window but I am having trouble assigning my radio buttons to a new class. I want to be able to select a genre, hit next and start with my recommendation based on the button the user selects.
from tkinter import *
class movie1:
def __init__(self, master):
self.master = master
master.title("Movie Recommendation")
self.label = Label(master, text= "Welcome to the movie recommendation application! \n Please select the genre of the movie you would like to see.")
self.label.pack(padx=25, pady=25)
CheckVar1 = StringVar()
C1 = Radiobutton(master, text = "Action", variable = CheckVar1, value=1)
C1.pack(side=TOP, padx=10, pady=10)
C2 = Radiobutton(master, text = "Comedy", variable = CheckVar1, value=2)
C2.pack(side=TOP, padx=10, pady=10)
C3 = Radiobutton(master, text = "Documentary", variable = CheckVar1, value=3)
C3.pack(side=TOP, padx=10, pady=10)
C4 = Radiobutton(master, text = "Horror", variable = CheckVar1, value=4)
C4.pack(side=TOP, padx=10, pady=10)
C5 = Radiobutton(master, text = "Romance", variable = CheckVar1, value=5)
C5.pack(side=TOP, padx=10, pady=10)
self.nextbutton = Button(master, text="Next", command=self.reco)
self.nextbutton.pack(side=BOTTOM, padx=10, pady=10)
def reco(self):
self.newWindow = Toplevel(self.master)
self.app = movie2(self.newWindow)
class movie2:
def __init__(self, master):
self.master = master
self.frame = Frame(self.master)
def C1(self):
print("option 1")
root = Tk()
my_gui = movie1(root)
root.mainloop()
You can pass the selected value to the new class:
class movie1:
def __init__(self, master):
...
self.CheckVar1 = StringVar()
...
def reco(self):
...
choice = self.CheckVar1.get()
self.app = movie2(self.newWindow, choice)
class movie2:
def __init__(self, master, choice):
...
print("you chose: %s" % choice)
...
Related
I am totally new to tkinter. I am trying to pass data between two windows. There is a button on root window. button press will open a top level. There are two entry fields and a submit button in on toplevel window. user can enter two number and submit. What i am trying to achieve is, pressing submit button should close the top level and result (sum) should be shown in the root window. How to pass entry field data to root window?
from tkinter import *
root= Tk()
root.geometry('600x400')
sum_var= StringVar()
def entry_Fn():
level_1 = Toplevel(root)
Label( level_1, text = "level one").pack()
entry_1 =Entry(level_1)
entry_1.pack()
entry_2 =Entry(level_1)
entry_2.pack()
Button(level_1, text= "submit", command= submitBtn ).pack()
def submitBtn():
val_1= entry_1.get()
val_2= entry_2.get()
sum_var.set(int(val_1)+ int(val_2))
Label(root, text = "Main window").pack()
Button(root, text= "To enter Data", command= entry_Fn).pack()
sum = Label(root, textvariable = sum_var)
sum.pack()
root.mainloop()
#result
val_1= entry_1.get()
NameError: name 'entry_1' is not defined
#shall I define some global variables?
In this case, you don't have to declare global. Simply indent your submitBtn function inside entry_Fn:
def entry_Fn():
level_1 = Toplevel(root)
Label( level_1, text = "level one").pack()
entry_1 = Entry(level_1)
entry_1.pack()
entry_2 = Entry(level_1)
entry_2.pack()
def submitBtn():
val_1= entry_1.get()
val_2= entry_2.get()
sum_var.set(int(val_1)+ int(val_2))
level_1.destroy()
Button(level_1, text= "submit", command=submitBtn).pack()
But generally it is easier to make a class so you can avoid this kind of scope problems, like below:
from tkinter import *
class GUI(Tk):
def __init__(self):
super().__init__()
self.geometry('600x400')
self.sum_var= StringVar()
Label(self, text="Main window").pack()
Button(self, text="To enter Data", command=self.entry_Fn).pack()
sum = Label(self, textvariable=self.sum_var)
sum.pack()
def entry_Fn(self):
self.level_1 = Toplevel(self)
Label(self.level_1, text = "level one").pack()
self.entry_1 = Entry(self.level_1)
self.entry_1.pack()
self.entry_2 = Entry(self.level_1)
self.entry_2.pack()
Button(self.level_1, text="submit", command=self.submitBtn).pack()
def submitBtn(self):
val_1 = self.entry_1.get()
val_2 = self.entry_2.get()
self.sum_var.set(int(val_1)+ int(val_2))
self.level_1.destroy()
root = GUI()
root.mainloop()
For your case, you can simply pass the two entries to submitBtn() function:
def submitBtn(entry_1, entry_2):
....
Then update the command= for the submit button inside entry_Fn():
Button(level_1, text="submit", command=lambda: submitBtn(entry_1, enter_2)).pack()
You can subclass tk.TopLevel, and use a tk.IntVar to transfer the data back to root:
import tkinter as tk
class EntryForm(tk.Toplevel):
def __init__(self, master, sum_var):
super().__init__(master)
tk.Label(self, text="level one").pack()
self.sum_var = sum_var
self.entry_1 = tk.Entry(self)
self.entry_1.pack()
self.entry_2 = tk.Entry(self)
self.entry_2.pack()
tk.Button(self, text="submit", command=self.submitBtn).pack()
def submitBtn(self):
val_1 = self.entry_1.get()
val_2 = self.entry_2.get()
self.sum_var.set(int(val_1) + int(val_2))
self.destroy()
def spawn_entry_popup():
EntryForm(root, sum_var)
root= tk.Tk()
root.geometry('600x400')
sum_var = tk.IntVar()
tk.Label(root, text = "Main window").pack()
tk.Button(root, text= "To enter Data", command=spawn_entry_popup).pack()
sum_label = tk.Label(root, textvariable=sum_var)
sum_label.pack()
root.mainloop()
You can also place your app inside a class:
import tkinter as tk
class EntryForm(tk.Toplevel):
def __init__(self, master, sum_var):
super().__init__(master)
tk.Label(self, text="level one").pack()
self.sum_var = sum_var
self.entry_1 = tk.Entry(self)
self.entry_1.pack()
self.entry_2 = tk.Entry(self)
self.entry_2.pack()
tk.Button(self, text="submit", command=self.submitBtn).pack()
def submitBtn(self):
val_1 = self.entry_1.get()
val_2 = self.entry_2.get()
self.sum_var.set(int(val_1) + int(val_2))
class GUI(tk.Tk):
def __init__(self):
super().__init__()
self.geometry('600x400')
self.sum_var = tk.IntVar()
tk.Label(self, text = "Main window").pack()
tk.Button(self, text= "To enter Data", command=self.spawn_entry_popup).pack()
sum_label = tk.Label(self, textvariable=self.sum_var)
sum_label.pack()
def spawn_entry_popup(self):
EntryForm(self, self.sum_var)
GUI().mainloop()
After clicking the save button, I am trying to get the text in the first input box to be the text in the newly created button. I am having trouble getting the entry text for the text box however.
I have tried using entry[0] to get the text but I don't know if that's where the text value is stored and it gives me an error as well. The error says "unresolved reference".
from tkinter import *
import tkinter as tk
class MainWindow(tk.Frame):
counter = 0
def __init__(self, *args, **kwargs):
tk.Frame.__init__(self, *args, **kwargs)
self.button = tk.Button(self, text="Create new hotlink",
command=self.create_window)
self.button.pack(side="top")
def create_window(self):
self.counter += 1
t = tk.Toplevel(self)
t.wm_title("Create New Hotlink")
fields = 'Hotlink Name', 'URL'
def fetch(entries):
for entry in entries:
field = entry[0]
text = entry[1].get()
print('%s: "%s"' % (field, text))
def makeform(root, fields):
entries = []
for field in fields:
row = Frame(root)
lab = Label(row, width=15, text=field, anchor='w')
ent = Entry(row)
row.pack(side=TOP, fill=X, padx=5, pady=5)
lab.pack(side=LEFT)
ent.pack(side=RIGHT, expand=YES, fill=X)
entries.append((field, ent))
return entries
ents = makeform(t, fields)
t.bind('<Return>', (lambda event, e=ents: fetch(e)))
b2 = Button(t, text='Save', command=button2())
b2.pack(side=LEFT, padx=5, pady=5)
def button2():
newButton = tk.Button(root, text=entry[0])
newButton.pack()
if __name__ == "__main__":
root = tk.Tk()
main = MainWindow(root)
main.pack(side="top", fill="both", expand=True)
root.mainloop()
entry is a local variable. You can't reference it there. You need to realize that all the information that you need is there in your ents variable. Use that.
I have stripped off the unnecessary parts of your code as well.
from tkinter import *
import tkinter as tk
class MainWindow(tk.Frame):
counter = 0
def __init__(self, *args, **kwargs):
tk.Frame.__init__(self, *args, **kwargs)
self.button = tk.Button(self, text="Create new hotlink", command=self.create_window)
self.button.pack(side="top")
def create_window(self):
self.counter += 1
t = tk.Toplevel(self)
t.wm_title("Create New Hotlink")
fields = 'Hotlink Name', 'URL'
def makeform(root, fields):
entries = []
for field in fields:
row = Frame(root)
lab = Label(row, width=15, text=field, anchor='w')
ent = Entry(row)
row.pack(side=TOP, fill=X, padx=5, pady=5)
lab.pack(side=LEFT)
ent.pack(side=RIGHT, expand=YES, fill=X)
entries.append((field, ent))
return entries
def button2():
newButton = tk.Button(root, text=ents[0][1].get())
newButton.pack() #\______________/
ents = makeform(t, fields)
b2 = Button(t, text='Save', command=button2)
b2.pack(side=LEFT, padx=5, pady=5)
if __name__ == "__main__":
root = tk.Tk()
main = MainWindow(root)
main.pack(side="top", fill="both", expand=True)
root.mainloop()
I'm studying GUI for Python, and I don't know how to disable a button with a check button. Which trigger does Python use to verify if I mark the check button? Follow some code I wrote trying to do it, but without success.
Sorry for my bad English.
from tkinter import *
from tkinter import ttk
class HelloApp:
def __init__(self, master):
self.label = ttk.Label(master, text="Hello, Tkinter!")
self.button1 = ttk.Button(master, text="Texas", command=self.texas_hello)
self.button2 = ttk.Button(master, text="Hawaii", command=self.hawaii_hello)
value_check = IntVar()
def disable_button(button):
button.config(state=DISABLED)
def enable_button(button):
button.config(state=NORMAL)
checkbutton = ttk.Checkbutton(master, variable=value_check, text='Deactivate!',
onvalue=enable_button(self.button1),
offvalue=disable_button(self.button1))
self.label.grid(row=0, column=0, columnspan=2)
self.button1.grid(row=1, column=0)
self.button2.grid(row=1, column=1)
checkbutton.grid(row=1, column=2)
print(value_check)
def texas_hello(self):
self.label.config(text='Howdy, Tkinter!')
def hawaii_hello(self):
self.label.config(text='Aloha, Tkinter!')
def main():
root = Tk()
HelloApp(root)
root.mainloop()
if __name__ == "main": main()
main()
You have to pass a function to command, this function is the one that will be notified every time there is a change, and you can get the status through value_check.
...
value_check = IntVar()
def disable_enable_button(button):
self.button1.config(state=DISABLED if value_check.get() else NORMAL)
checkbutton = ttk.Checkbutton(master, variable=value_check, text='Deactivate!',
command=disable_enable_button)
....
use command option. you can set the default status using value_check.set(1/0).
def disable_button(self, button):
print('disable button')
button.config(state=DISABLED)
def enable_button(self, button):
print('enable button')
button.config(state=NORMAL)
def changebutton(self):
print('changebutton=', self.value_check.get())
if self.value_check.get()==1:
self.enable_button(self.button1)
else:
self.disable_button(self.button1)
def __init__(self, master):
self.label = ttk.Label(master, text="Hello, Tkinter!")
self.button1 = ttk.Button(master, text="Texas", command=self.texas_hello)
self.button2 = ttk.Button(master, text="Hawaii", command=self.hawaii_hello)
self.value_check = IntVar()
self.checkbutton = ttk.Checkbutton(master, variable=self.value_check, text='Activate!',
onvalue=1, offvalue=0,
command=self.changebutton)
self.value_check.set(0)
self.changebutton()
self.label.grid(row=0, column=0, columnspan=2)
self.button1.grid(row=1, column=0)
self.button2.grid(row=1, column=1)
self.checkbutton.grid(row=1, column=2)
print(self.value_check.get())
Follows the code including some radio buttons to play with the checkbox.
class HelloApp:
def __init__(self, master):
self.label = ttk.Label(master, text="Hello, Tkinter!")
self.button1 = ttk.Button(master, text="Texas", command=self.texas_hello)
self.button2 = ttk.Button(master, text="Hawaii", command=self.hawaii_hello)
self.value_check = IntVar()
self.value_check.set(0)
self.checkbutton = ttk.Checkbutton(master, variable=self.value_check, text='Activate!',
onvalue=1, offvalue=0,
command=self.disable_enable_button)
self.choice = StringVar()
self.frame_radio = ttk.Frame(master).grid(row=3, column=3)
self.radiobutton1 = ttk.Radiobutton(self.frame_radio, text='Button 1', variable=self.choice, value='button1')
self.radiobutton1.grid(row=2, column=2)
self.radiobutton2 = ttk.Radiobutton(self.frame_radio, text='Button 2', variable=self.choice, value='button2')
self.radiobutton2.grid(row=3, column=2)
self.label.grid(row=0, column=0, columnspan=2)
self.button1.grid(row=1, column=0)
self.button2.grid(row=1, column=1)
self.checkbutton.grid(row=1, column=2)
def texas_hello(self):
self.label.config(text='Howdy, Tkinter!')
def hawaii_hello(self):
self.label.config(text='Aloha, Tkinter!')
def disable_enable_button(self):
self.button1.config(
state=DISABLED if self.value_check.get() and self.choice.get() == 'button1' else NORMAL)
self.button2.config(
state=DISABLED if self.value_check.get() and self.choice.get() == 'button2' else NORMAL)
def main():
root = Tk()
HelloApp(root)
root.mainloop()
I want to know how to get input from Tkinter and put it into a variable like a phone number or a piece of text.
from tkinter import *
def show_data():
print( 'My First and Last Name are %s %s' % (fname.get(), lname.get()) )
win = Tk()
Label( win, text='First Name' ).grid( row=0 )
Label( win, text='Last Name' ).grid( row=1 )
fname = Entry( win )
lname = Entry( win )
fname.grid( row=0, column=1 )
lname.grid( row=1, column=1 )
Button( win, text='Exit', command=win.quit ).grid( row=3, column=0, sticky=W, pady=4 )
Button( win, text='Show', command=show_data ).grid( row=3, column=1, sticky=W, pady=4 )
mainloop()
Maybe this can help you:
from tkinter import *
def get_variable_value():
valueresult.set( strlname.get() + ' ' + strfname.get() ) #assign val variable to other
print(valueresult.get()) #if you want see the result in the console
root = Tk()
strfname = StringVar()
strlname = StringVar()
valueresult = StringVar()
labelf = Label(root, text = 'First Name').pack()
fname = Entry(root, justify='left', textvariable = strfname).pack() #strlname get input
labell = Label(root, text = 'Last Name').pack()
lname = Entry(root, justify='left', textvariable = strlname).pack() #strfname get input
button = Button(root, text='Show', command=get_variable_value).pack()
res = Entry(root, justify='left', textvariable = valueresult).pack() #only to show result
root.mainloop()
You haven't provided any code but you could try:
class GetPhoneNbr(object):
def __init__(self):
self.root = Tk.Tk()
self.label = Tk.Label(self.root, text="Enter phone number")
self.label.pack()
self.phoneNbr = Tk.StringVar() # <- here's what you need
Tk.Entry(self.root, textvariable=self.phoneNbr).pack()
NOTE: This is a stub of code, not the entire class definition.
Below is a minimal GUI that puts what's written in an entry to a variable, which is the button's text:
import tkinter as tk
def replace_btn_text():
b['text'] = e.get()
root = tk.Tk()
e = tk.Entry(root)
b = tk.Button(root, text="Replace me!", command=replace_btn_text)
e.pack()
b.pack()
root.mainloop()
Same example but with an OOP structure:
import tkinter as tk
class App(tk.Tk):
def __init__(self):
super().__init__()
self._create_widgets()
self._display_widgets()
def replace_btn_text(self):
""" Replaces button's text with what's written in the entry.
"""
# self._e.get() returns what's written in the
self._b['text'] = self._e.get() # entry as a string, can be assigned to a var.
def _create_widgets(self):
self._e = tk.Entry(self)
self._b = tk.Button(self, text="Replace me!", command=self.replace_btn_text)
def _display_widgets(self):
self._e.pack()
self._b.pack()
if __name__ == '__main__':
root = App()
root.mainloop()
I need to return all variables from all tabs by clicking on ok button.
I have two tabs. What I want is that when I enter some value in 2nd tab, it should automatically appear in first tab in 'height' entry.
Then if I click 'ok' in first tab, it should return all variables(from first tab and 2nd tab) to my 'main' program for further use.
Thanks
from tkinter import *
from tkinter import ttk
class App1(ttk.Frame):
def createWidgets(self):
#text variables
self.i_height = StringVar()
self.i_weight = StringVar()
self.o_bmi = StringVar()
#labels
self.label1 = ttk.Label(self, text="Enter your weight:").grid(row=0, column=0, sticky=W)
self.label2 = ttk.Label(self, text="Enter your height:").grid(row=1, column=0, sticky=W)
self.label3 = ttk.Label(self, text="Your BMI is:").grid(row=2, column=0, sticky=W)
#text boxes
self.textbox1 = ttk.Entry(self, textvariable=self.i_weight).grid(row=0, column=1, sticky=E)
self.textbox2 = ttk.Entry(self, textvariable=self.i_height).grid(row=1, column=1, sticky=E)
self.textbox3 = ttk.Entry(self, textvariable=self.o_bmi).grid(row=2, column=1, sticky=E)
#buttons
self.button1 = ttk.Button(self, text="Cancel/Quit", command=self.quit).grid(row=3, column=1, sticky=E)
self.button1 = ttk.Button(self, text="Ok", command=self.calculateBmi).grid(row=3, column=2, sticky=E)
def calculateBmi(self):
try:
self.weight = float(self.i_weight.get())
self.height = float(self.i_height.get())
self.bmi = self.weight / self.height ** 2.0
self.o_bmi.set(self.bmi)
except ValueError:
messagebox.showinfo("Error", "You can only use numbers.")
finally:
self.i_weight.set("")
self.i_height.set("")
def __init__(self, master=None):
ttk.Frame.__init__(self, master)
self.grid()
self.createWidgets()
class App2(ttk.Frame):
def create_widgets(self):
"""Create the widgets for the GUI"""
#1 textbox (stringvar)
self.entry= StringVar()
self.textBox1= ttk.Entry(self, textvariable=self.entry).grid(row=0, column=1)
#5 labels (3 static, 1 stringvar)
self.displayLabel1 = ttk.Label(self, text="feet").grid(row=0, column=2, sticky=W)
self.displayLabel2 = ttk.Label(self, text="is equivalent to:").grid(row=1, column=0)
self.result= StringVar()
self.displayLabel3 = ttk.Label(self, textvariable=self.result).grid(row=1, column=1)
self.displayLabel4 = ttk.Label(self, text="meters").grid(row=1, column=2, sticky=W)
#2 buttons
self.quitButton = ttk.Button(self, text="Quit", command=self.quit).grid(row=2, column=1, sticky=(S,E))
self.calculateButton = ttk.Button(self, text="Calculate", command=self.convert_feet_to_meters).grid(row=2, column=2, sticky=(S,E))
def convert_feet_to_meters(self):
"""Converts feet to meters, uses string vars and converts them to floats"""
self.measurement = float(self.entry.get())
self.meters = self.measurement * 0.3048
self.result.set(self.meters)
def __init__(self, master=None):
ttk.Frame.__init__(self, master)
self.grid()
self.create_widgets()
def button1_click():
root = Tk()
app = App1(master=root)
app.mainloop()
def button2_click():
root = Tk()
app = App2(master=root)
app.mainloop()
def main():
#Setup Tk()
window = Tk()
#Setup the notebook (tabs)
notebook = ttk.Notebook(window)
frame1 = ttk.Frame(notebook)
frame2 = ttk.Frame(notebook)
notebook.add(frame1, text="BMI Calc")
notebook.add(frame2, text="Feet to Meters")
notebook.grid()
#Create tab frames
app1 = App1(master=frame1)
app1.grid()
app2 = App2(master=frame2)
app2.grid()
#Main loop
window.mainloop()
main()
You have some fundamental mistakes in your program -- you cannot have three mainloops running at the same. You should always only have exactly one instance of Tk, and call mainloop exactly once.
Regardless of that, the solution is that you need to create a method or public variable in the app, and then your button callback needs to be able to call that method or access that variable.
For example, you would do it like this:
def callback():
value1 = app1.getValue()
value2 = app2.getValue()
...