I'm working on a project that recommends movies to a user through a GUI. However I'm new to python and tkinter and struggling with calling functions and variable to functions in general, as a test I want to print out two Entry widgets to the console. I've tried quite a few different approaches but something always seems to go wrong. Here is the relevant code for this test:
class App(Frame):
def print_it(self):
print(mn, nr)
def __init__(self, master):
Frame.__init__(self, master)
self.filename = None
movie_name = Entry(master)
movie_name.grid()
movie_name.delete(0, END)
movie_name.insert(0, "Enter Movie Name")
mn = movie_name.get()
num_recs = Entry(master)
num_recs.grid()
num_recs.delete(0, END)
num_recs.insert(0, "Enter Number of Movies")
nr = num_recs.get()
button1 = Button(self, text="Start", command=self.print_it)
button2 = Button(self, text="Exit", command=master.destroy)
button1.grid()
button2.grid()
self.grid()
root = Tk()
root.title("Recommender")
root.geometry("500x500")
app = App(root)
root.mainloop()
The variables nr and mn are obviously not being called in print it, ive tried the preifixes App. and self. but neither work. Can someone indicate to me what I need to do in order to call these variables. Thank you.
Good start.
First, if you want to access a variable from different methods, it needs to be named with the 'self.' prefix.
Second, the __init__ method runs when you boot, so if you call movie_name.get() it gets the value at boot time. You want the value it had when the button was pushed (I assume), so you need to move the get() call into the method that gets called when the button is pushed.
Third, an entry is empty when it's first initialized, you don't need to use the delete method to clear it.
class App(Frame):
def print_it(self):
print(self.movie_name.get(), self.num_recs.get())
def __init__(self, master):
Frame.__init__(self, master)
self.filename = None
self.movie_name = Entry(master)
self.movie_name.grid()
self.movie_name.insert(0, "Enter Movie Name")
self.num_recs = Entry(master)
self.num_recs.grid()
self.num_recs.insert(0, "Enter Number of Movies")
button1 = Button(self, text="Start", command=self.print_it)
button2 = Button(self, text="Exit", command=master.destroy)
button1.grid()
button2.grid()
self.grid()
root = Tk()
root.title("Recommender")
root.geometry("500x500")
app = App(root)
root.mainloop()
Related
I am quite new with Tkinter and am trying to create a new window using this script while keeping the current window but i am get the error
_init_() missing 1 required positional argument: 'parent'. I am not really sure what the reason is but I am assuming that the command function for my button isn't working the way I want it.
The script currently looks something like this:
from tkinter import simpledialog
from tkinter import *
class Additional(simpledialog.Dialog):
def body(self, master):
#input fields
Label(master, text="Picture 3 Path:").grid(row=1)
#input fields for tags
#add as needed
self.e1 = Entry(master)
self.e1.grid(row=1, column=1, ipadx=150)
return self.e1 # initial focus
def apply(self):
first = self.e1.get()
self.ttag1 = (first)
class Initial(simpledialog.Dialog):
def body(self, master):
#input fields for username and passwords
Label(master, text="Usernames:").grid(row=1),
self.e1 = Entry(master)
self.b1 = Button(master, text = "Add More", bg= 'grey', command= Additional)
self.b1.grid(row=6, column=2, ipadx=75)
self.e1.grid(row=1, column=1, columnspan=2, ipadx=50)
return self.e1 # initial focus
def apply(self):
first = self.e1.get()
self.tag1 = (first)
root = tk.Tk()
root.withdraw()
d = Initial(root)
toor = tk.Tk()
toor.withdraw()
I have tried changing it up but it seems that it's not working right. Any ideas?
When calling the Additional class through the button command, you are not specifying what the parent root should be, and therefore the class fails to initiate. You can solve this by passing the master using a lambda
self.b1 = Button(master, text="Add More", bg='grey', command=lambda: Additional(master))
i wrote bellow code in python 3.6.2 by tkinter,I want the cursor move to password textbox when user press Enter key in username textbox.
from tkinter import *
class Application(Frame):
def __init__(self,master):
super(Application, self).__init__(master)
self.grid()
self.create_main()
def create_main(self):
print("testing")
self.title = Label(self, text=" Stuck In The Circle ")
self.title.grid(row=0, column=2)
self.user_entry_label = Label(self, text="Username: ")
self.user_entry_label.grid(row=1, column=1)
self.user_entry = Entry(self)
self.user_entry.grid(row=1, column=2)
self.pass_entry_label = Label(self, text="Password: ")
self.pass_entry_label.grid(row=2, column=1)
self.pass_entry = Entry(self)
self.pass_entry.grid(row=2, column=2)
self.user_entry = Entry(self, justify="right")
self.pass_entry = Entry(self, justify="right")
self.sign_in_butt = Button(self, text="Sign In",command = self.logging_in)#SIGN IN BUTTON
self.sign_in_butt.grid(row=5, column=2)
def logging_in(self):
user_get = self.user_entry.get()
pass_get = self.pass_entry.get()
root = Tk()
root.title("Stuck in the Circle")
root.geometry("400x100")
app = Application(root)
root.mainloop()
How can do it?
This is actually a lot simpler than I expected it to be.
We can use .bind() to get a callback on the <Return> event. This means that every time the return character is pressed whenever the defined widget is in focus we get a callback.
In order to get it to cycle to the next widget we can use this answer from Bryan Oakley:
def focus_next_window(event):
event.widget.tk_focusNext().focus()
return("break")
text_widget=Text(...) text_widget.bind("<Tab>", focus_next_window)
Important points about this code:
The method tk_focusNext() returns the next widget in the keyboard
traversal hierarchy. the method focus() sets the focus to that widget
returning "break" is critical in that it prevents the class binding
from firing. It is this class binding that inserts the tab character,
which you don't want.
So, applying the same logic in our situation we can use something like the below:
from tkinter import *
class App:
def __init__(self, root):
self.root = root
self.entry1 = Entry(self.root)
self.entry2 = Entry(self.root)
self.entry1.pack()
self.entry2.pack()
self.entry1.bind("<Return>", self.callback)
def callback(self, event):
event.widget.tk_focusNext().focus()
root = Tk()
App(root)
root.mainloop()
I am learning Python and tkinter by going through several tutorials (python-course.eu & effbot.org). I have come across a pair of situations and am trying to learn the reasons behind the differences.
NOTE: I found many questions regarding __init__ in class, but not __init__ in frame.
Both call a class from the main, and use a constructor (def __init__) to create an instance of the class. Am I using correct terminology?
They both create a frame; however, one uses Frame.__init__(self,parent): and the other uses Frame(master):
Why does the first include __init__ in the construction of the frame?
Why does the second omit 'self' in the arguments when creating the frame?
Why does the first not use 'pack' to place, but the second does?
What other differences are noteworthy?
The following are MWE to produce the respective outputs.
import tkinter as tk
class Checkbar(tk.Frame):
def __init__(self, parent=None, picks=[], side=tk.LEFT, anchor=tk.W):
tk.Frame.__init__(self, parent)
self.vars = []
for pick in picks:
var = tk.IntVar()
chk = tk.Checkbutton(self, text=pick, variable=var)
chk.pack(side=side, anchor=anchor, expand=tk.YES)
self.vars.append(var)
def state(self):
return map((lambda var: var.get()), self.vars)
if __name__ == '__main__':
root = tk.Tk()
lng = Checkbar(root, ['Python', 'Ruby', 'Perl', 'C++'])
tgl = Checkbar(root, ['English','German'])
lng.pack(side=tk.TOP, fill=tk.X)
tgl.pack(side=tk.LEFT)
lng.config(relief=tk.GROOVE, bd=2)
def allstates():
print(list(lng.state()), list(tgl.state()))
tk.Button(root, text='Quit', command=root.destroy).pack(side=tk.RIGHT)
tk.Button(root, text='Peek', command=allstates).pack(side=tk.RIGHT)
root.mainloop()
print("You've selected ", list(lng.state()))
Language Widget
import tkinter as tk
class App:
def __init__(self, master):
frame = tk.Frame(master)
frame.pack()
self.button = tk.Button(frame, text="Quit", fg="red", command=master.destroy, padx=20)
self.button.pack(side='left', expand=10)
self.hi_there = tk.Button(frame, text="Hello", command=self.say_hi)
self.hi_there.pack(side='left')
def say_hi(self):
print("Hi there, everyone!")
if __name__ == '__main__':
root = tk.Tk()
app = App(root)
root.mainloop()
Hello Window
Thank you, kindly.
NameError: name 'onOpen' is not defined
There is something wrong with the command function. I am not sure what I did wrong here. I had the code tested before the onOpen function and it works fine.
import tkinter as tk
from tkinter import filedialog
class Application(tk.Frame):
def __init__(self, master=None):
tk.Frame.__init__(self, master)
self.pack()
self.createWidgets()
def onOpen():
""" Ask the user to choose a file and update the values of label change button"""
button_label.set(filedialog.askopenfilename(filetypes = ()))
def createWidgets(self):
#instruction label
self.labelInstruct = tk.Label(self, text="Instructions:", padx=10, pady=10)
self.labelInstruct = tk.Label(self, text="All you have to do is insert the file and save it.\n The conversion is instant", padx=10, pady=10)
self.labelInstruct.pack()
#insertfile button
self.ifbut = tk.Button(self, text="Insert File", command=onOpen)
self.ifbut.pack()
button_label = tk.StringVar(self)
text = tk.Label(self, textvariable = button_label)
text.pack()
#save button
self.saveLabel = tk.Label(self, text="Save File", padx=10, pady=10)
self.saveLabel.pack()
self.saveButton = tk.Button(self)
self.saveButton.pack()
#quit button
self.quitButton = tk.Button(self, text='Quit',
command=self.quit)
self.quitButton.pack()
app = Application()
app.master.title('Sample application')
app.mainloop()
Seeing that there are many problems with the way this code is written I am only going to point out a few of them and tackle the main question from the OP.
Lets start with the fact that you need to define the main window with something like root = tk.Tk() and you also need to make sure all your methods in your class have the argument self as the first argument.
Also any variable you are defining also should have self so that the class can interact with it. This (button_label) for example should be self.button_label.
There is no reason to use return the way you are trying to in the onOpen(self): method. Return does not work like that. Return is there so you can return a value to something that is calling the function/method to be used for something else and is not for setting the value of something.
Note that I also add the root window variable to the app = Application(root) line. This lets us pass the main window into the class.
all and all the following should work for the onOpen(self): function but the rest still needs some work.
import tkinter as tk
from tkinter import filedialog
class Application(tk.Frame):
def __init__(self, parent):
tk.Frame.__init__(self, parent)
self.parent = parent
self.pack()
self.createWidgets()
def onOpen(self):
""" Ask the user to choose a file and update the values of label change button"""
self.button_label.set(filedialog.askopenfilename(filetypes = ()))
def createWidgets(self):
#instruction label
self.labelInstruct = tk.Label(self.parent, text="Instructions:", padx=10, pady=10)
self.labelInstruct = tk.Label(self.parent, text="All you have to do is insert the file and save it.\n The conversion is instant", padx=10, pady=10)
self.labelInstruct.pack()
#insert file button
self.ifbut = tk.Button(self.parent, text="Insert File", command = self.onOpen)
self.ifbut.pack()
self.button_label = tk.StringVar()
self.text = tk.Label(self.parent, textvariable = self.button_label)
self.text.pack()
#save button
self.saveLabel = tk.Label(self.parent, text="Save File", padx=10, pady=10)
self.saveLabel.pack()
self.saveButton = tk.Button(self.parent, text = "Save")
self.saveButton.pack()
#quit button
self.quitButton = tk.Button(self.parent, text='Quit', command=self.quit)
self.quitButton.pack()
root = tk.Tk()
app = Application(root)
app.master.title('Sample application')
app.mainloop()
You need to return the function value as below:
def onOpen():
""" Ask the user to choose a file and update the values of label change button"""
return button_label.set(filedialog.askopenfilename(filetypes = ()))
This is my first python personal project. I am wanting to use Tkinter to create a window (GUARDIAN LOCATOR) that asks the user to input a value (enter sailor guardian) into the entry box. The rest of the program is dependent on what the user types in the entry box as I will be having if/else statements reacting to the sailor guardian entered.
The issue I am having is storing what is entered in the entry box as a variable to use in my main file for the if/else statements. I can get the value to print to the prompt window, but I haven't been able to store it successfully to a global variable.
My Tkinter window is in it's own class.
I have tried many different ways of doing this based on similar issues from stackoverflow, but I am getting an error every time. This is my base code that still produces the error.
Class file with the Tkinter window
class GuardianLocator:
def __init__(self, master):
frame = Frame(master)
frame.grid()
master.title("GUARDIAN LOCATOR")
self.locator_label = Label(frame, text="Which Sailor Guardian are you looking for?", width=40, height=2)
self.locator_label.grid()
self.entry = Entry(frame)
self.entry.grid()
self.button1 = Button(frame, text="Search", command=self.guardian_name, pady=2)
self.button1.grid()
def guardian_name(self):
print(self.entry.get())
and in my main working file
root = Tk()
locator = guardian_locator.GuardianLocator(root)
root.mainloop()
This is my test loop to see if it's working.
if locator.guardian_input() is "Sailor Moon":
print("hi")
else:
print("no")
Not sure exactly how your code is organized and where is your "test loop" located, but I assume it is after root.mainloop(). Thus the script can be as follows:
from tkinter import *
class GuardianLocator:
def __init__(self, master):
self._name = ""
frame = Frame(master)
frame.grid()
master.title("GUARDIAN LOCATOR")
self.locator_label = Label(frame, text="Which Sailor Guardian are you looking for?", width=40, height=2)
self.locator_label.grid()
self.entry = Entry(frame)
self.entry.grid()
self.button1 = Button(frame, text="Search", command=self.guardian_name, pady=2)
self.button1.grid()
def guardian_name(self):
self._name = self.entry.get()
print(self.entry.get())
root = Tk()
locator = GuardianLocator(root)
root.mainloop()
# this will be executed after the root window is closed.
print("Name is", locator._name)
Please note self._name = "" in the constructor. This instance variable can be used to store the name provided in your GuardianLocator window.