updated code as per below comments
I'm struggling to get my top level to open on button press!
I've scanned the code on here but don't seem to be able to get a woking solution. My latest error is:
AttributeError: '_tkinter.tkapp' object has no attribute 'unavail'
from tkinter import *
from ScheduleApi import flightData
import config
from itinerary import fltCreate
class FrontEnd:
def __init__(self, master):
self.master = master
master.title("A simple GUI")
self.label = Label(master, text="This is our first GUI!")
self.label.grid()
self.greet_button = Button(master, text="Create Itinerary", command=self.ItinBuilder)
self.greet_button.grid(row=1)
self.close_button = Button(master, text="Close", command=master.quit)
self.close_button.grid(row=2)
def greet(self):
print("Greetings!")
def ItinBuilder(self):
self = Toplevel(self.master)
self.title ("Please build your itinerary")
self.addflt_button = Button(self.master, text="add flights", command=fltCreate)
self.addflt_button.grid(row=1)
self.addfhtl_button = Button(self.master, text="add hotel", command=self.master.unavail)
self.addflt_button.grid(row=1, column=1)
self.addfmsc_button = Button(self.master, text="add misc item", command=self.master.unavail)
self.addflt_button.grid(row=2, column=1)
self.prvitin_button = Button(self.master, text="preview", command=self.master.unavail)
self.addflt_button.grid(row=2, column=1)
def unavail(self, Toplevel):
print("Function not yet available.")
root = Tk()
my_gui = FrontEnd(root)
root.mainloop()
Please change your function ItinBuilder to this. I hope this is what you expect.
def ItinBuilder(self):
self.newWindow = Toplevel(self.master)
self.newWindow.title ("Please build your itinerary")
self.addflt_button = Button(self.newWindow, text="add flights", command=fltCreate)
self.addflt_button.grid(row=0)
self.addfhtl_button = Button(self.newWindow, text="add hotel", command=self.master.unavail)
self.addfhtl_button.grid(row=0, column=1)
self.addfmsc_button = Button(self.newWindow, text="add misc item", command=self.master.unavail)
self.addfmsc_button.grid(row=1, column=0)
self.prvitin_button = Button(self.newWindow, text="preview", command=self.master.unavail)
self.prvitin_button.grid(row=1, column=1)
The add flights button is in main GUI because you passed the reference to your main window self.master as first argument(called parent in tkinter) in your code.
Only add_flights button is seen and not others because you called grid method only for self.addflt_button and not for other buttons(missed to change variable names in other calls I guess).
Related
Creating a popup window which will ask for email entry and then print the email when 'OK' is pressed, this is my code:
import tkinter as tk
class PopUp(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
tk.Label(self, text="Main Window").pack()
popup = tk.Toplevel(self)
popup.wm_title("EMAIL")
popup.tkraise(self)
tk.Label(popup, text="Please Enter Email Address").pack(side="left", fill="x", pady=10, padx=10)
self.entry = tk.Entry(popup, bd=5, width=35).pack(side="left", fill="x")
self.button = tk.Button(popup, text="OK", command=self.on_button)
self.button.pack()
def on_button(self):
print(self.entry.get())
app = PopUp()
app.mainloop()
Every time I run it I get this error:
AttributeError: 'NoneType' object has no attribute 'get'
The pop up works how it should but its the input entry that doesn't seem to be working.
I've seen this example before but it wasn't in the popup (I can get it work perfectly without the popup).
Any help is appreciated.
You can store the value in a StringVar variable and get() its value.
import tkinter as tk
from tkinter import StringVar
class PopUp(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
tk.Label(self, text="Main Window").pack()
popup = tk.Toplevel(self)
popup.wm_title("EMAIL")
popup.tkraise(self)
tk.Label(popup, text="Please Enter Email Address").pack(side="left", fill="x", pady=10, padx=10)
self.mystring = tk.StringVar(popup)
self.entry = tk.Entry(popup,textvariable = self.mystring, bd=5, width=35).pack(side="left", fill="x")
self.button = tk.Button(popup, text="OK", command=self.on_button)
self.button.pack()
def on_button(self):
print(self.mystring.get())
app = PopUp()
app.mainloop()
I am trying to create an application that will allow you to put in multiple websites and check if they are down. When I run the code the window opens and everything works fine until i click search. Then i get the following error
AttributeError: 'Window' object has no attribute 'text_entry'
Any help would be greatly appreciated
#Import everything from tkinter
from tkinter import *
import urllib.request
#Main window
class Window(Frame):
#Master Widget
def __init__(self, master = None):
Frame.__init__(self, master)
self.master = master
self.init_window()
#Creation of init_window
def init_window(self):
# changing the title of our master widget
self.master.title("GUI")
# allowing the widget to take the full space of the root window
self.pack(fill=BOTH, expand=1)
#Menu
menu = Menu(self.master)
self.master.config(menu=menu)
#File Menu option
file = Menu(menu)
file.add_command(label="Exit", command=self.client_exit)
menu.add_cascade(label="File", menu=file)
#Text Box
text_entry = Entry(self, width=20, bg="white")
text_entry.place(x=0, y=0)
#Submit button
searchButton = Button(self, text='SUBMIT', width=6,
command=self.search)
searchButton.place(x=200, y=30)
#Output Box
output = Text(self, width=20, height=1, bg="white")
output.place(x=0, y=50)
def search(self):
entered_text = self.text_entry.get()
output.delete(0.0, END)
definition=(int(urllib.request.urlopen(entered_text).getcode()))
output.insert(END, definition)
root = Tk()
#Size of the window
root.geometry("400x300")
#Window instance
app = Window(root)
#Show and mainloop
root.mainloop()
You haven't put text_entry on the self object and you can't access it in search function.
#Text Box
self.text_entry = Entry(self, width=20, bg="white")
self.text_entry.place(x=0, y=0)
I am writing a code for a login system using tkinter and for some reason when I run the code there are no error messages and a window pops up but without the title, buttons or labels I need.
from tkinter import *
import tkinter.messagebox
frame = Tk()
def adminlogincheck(self, master):
frame = Frame(master)
frame.pack()
if username == '123key' and password == 'key123':
accept = Label(frame, text='Login Successful')
else:
decline = Label(frame, text='Login incorrect')
mainloop()
def adminselect(self, master):
frame = Frame(master)
frame.pack()
self.button = Button(frame, text="Cancel", fg="red", command=quit)
self.button.pack(side=LEFT)
self.slogan = Button(frame, text="Proceed", command=self.adminlogin)
self.slogan.pack(side=LEFT)
mainloop()
def adminlogin(self, master):
frame = Frame(master)
frame.pack()
username_entry = Entry(frame)
password_entry = Entrey(frame)
confirm = Button(frame, text='Login', command = adminlogincheck)
loginquit = Button(frame, text='Cancel', command=quit)
mainloop()
I will add more after the login system works but does anyone know why no buttons or labels appear?
There's enough in your request to see what you're trying to accomplish, but there are many issues with the code. Here is a working model of what you appear to be working toward...
from tkinter import *
import tkinter.messagebox
class Admin:
def __init__(self, master):
self.frame = Frame(master)
self.frame.pack()
self.username = StringVar()
self.password = StringVar()
def logincheck(self):
self.clearframe()
if self.username.get() == '123key' and self.password.get() == 'key123':
accept = Label(self.frame, text='Login Successful')
accept.pack(side=LEFT)
else:
decline = Label(self.frame, text='Login incorrect')
decline.pack(side=LEFT)
def select(self):
self.clearframe()
self.button = Button(self.frame, text="Cancel", fg="red", command=quit)
self.button.pack(side=LEFT)
self.slogan = Button(self.frame, text="Proceed", command=self.adminlogin)
self.slogan.pack(side=LEFT)
def login(self):
self.clearframe()
username_entry = Entry(self.frame, textvariable=self.username)
username_entry.pack()
password_entry = Entry(self.frame, textvariable=self.password)
password_entry.pack()
confirm = Button(self.frame, text='Login', command = self.logincheck)
confirm.pack()
loginquit = Button(self.frame, text='Cancel', command=quit)
loginquit.pack()
def clearframe(self):
# Destroy all children of the class's frame.
for child in self.frame.winfo_children():
child.destroy()
root = Tk()
admin = Admin(root)
admin.login()
mainloop()
I've been playing around with my first Python Tkinter GUI.
Below you van find te script I've made. Must be honest, I've looked around on the internet to find out how to do it.
When I run my script now I get 2 seperate windows.
One window, lets call this "window A", with my text and input boxes and one empty window, lets call this "window B".
When I click on "Run" in "window A" my phyton script(tennisMatchProbability.py in this case) is triggered and the results of that script (tennisMatchProbability.py) are displayed in "window B".
This is the output that "tennisMatchProbability.py" gives.
Server Game = 0.735729230769
Receiver Game= 0.264270769231
Tiebreak = 0.337026817252
Server Set = 0.205146215901
Receiver Set= 0.794853784099
Match Server= 0.108987765053
Match Receiver= 0.891012234947
What I would like to achieve is that both windows are merged into one window.
I've been trying everything that I could think of but can't figure it out.
from Tkinter import *
import sys
sys.path.append("C:\Users\Magali\Desktop\Tennis\tennisMatchProbability.py")
class App(Frame):
def run_script(self):
sys.stdout = self
try:
del(sys.modules["tennisMatchProbability"])
except:
## Yeah, it's a real ugly solution...
pass
import tennisMatchProbability
tennisMatchProbability.matchProb()
sys.stdout = sys.__stdout__
def build_widgets(self):
self.text1 = Text(self)
self.text1.pack(side=TOP)
master = Tk()
Label(master, text="First Name").grid(row=0)
Label(master, text="Last Name").grid(row=1)
Label(master, text="Game Score").grid(row=2)
Label(master, text="Set Score").grid(row=3)
e1 = Entry(master)
e2 = Entry(master)
e3 = Entry(master)
e4 = Entry(master)
e1.delete(0,END)
e2.delete(0,END)
e3.delete(0,END)
e4.delete(0,END)
e1.insert(10,"Novak")
e2.insert(10,"Djokovic")
e3.insert(10,"30-15")
e4.insert(10,"3-1")
e1.grid(row=0, column=1)
e2.grid(row=1, column=1)
e3.grid(row=2, column=1)
e4.grid(row=3, column=1)
Button(master, text='Run', command=self.run_script).grid(row=4, column=1, sticky=W, pady=4)
def write(self, txt):
self.text1.insert(INSERT, txt)
def __init__(self, master=None):
Frame.__init__(self, master)
self.pack()
self.build_widgets()
root = Tk()
app = App(master = root)
app.mainloop()
The answer is easy:
In the build_widgets method you are constructing a new Tk frame and tcl interpreter with
master = Tk()
You should never have two Tk() calls in your application.
The solution is to delete this line and change every occurance of master to self. Self represent your app class, which inherits from the tk.Frame class and is therefore your main frame.
Also your construction of run_scipt is rather weird. Why don't you do it like this?
def run_script(self):
inputs = self.read_tk_fields()
result = tennisMatchProbability.matchProb(inputs)
Here is the full code
from Tkinter import *
import sys
sys.path.append("C:\Users\Magali\Desktop\Tennis\tennisMatchProbability.py")
import tennisMatchProbability
class App(Frame):
def run_script(self):
inputs = self.read_tk_field()
result = tennisMatchProbability.matchProb(inputs)
self.show_prob_result(result)
def show_prob_result(self,result):
self.result_label.config(text=result)
def build_widgets(self):
Label(self, text="First Name").grid(row=0)
Label(self, text="Last Name").grid(row=1)
Label(self, text="Game Score").grid(row=2)
Label(self, text="Set Score").grid(row=3)
e1 = Entry(self)
e2 = Entry(self)
e3 = Entry(self)
e4 = Entry(self)
self.result_label = Label(self)
e1.insert(10,"Novak")
e2.insert(10,"Djokovic")
e3.insert(10,"30-15")
e4.insert(10,"3-1")
e1.grid(row=0, column=1)
e2.grid(row=1, column=1)
e3.grid(row=2, column=1)
e4.grid(row=3, column=1)
self.result_label.grid(row=4, column=1)
Button(self, text='Run', command=self.run_script).grid(row=5, column=1, sticky=W, pady=4)
def __init__(self, master=None):
Frame.__init__(self, master)
self.pack()
self.build_widgets()
root = Tk()
app = App(master = root)
app.mainloop()
#Jannick, with your script I don't get the results in the GUI. With your script I get the results in CMD and the "Run" bottun gives an error
With my code below I get the results in the GUI.
from Tkinter import *
import sys
sys.path.append("C:\Users\Magali\Desktop\Tennis\tennisMatchProbability.py")
class App(Frame):
def run_script(self):
sys.stdout = self
try:
del(sys.modules["tennisMatchProbability"])
except:
## Yeah, it's a real ugly solution...
pass
import tennisMatchProbability
tennisMatchProbability.matchProb()
sys.stdout = sys.__stdout__
def build_widgets(self):
self.text1 = Text(self)
self.text1.grid(row=5)
Label(self, text="First Name").grid(row=0)
Label(self, text="Last Name").grid(row=1)
Label(self, text="Game Score").grid(row=2)
Label(self, text="Set Score").grid(row=3)
e1 = Entry(self)
e2 = Entry(self)
e3 = Entry(self)
e4 = Entry(self)
e1.delete(0,END)
e2.delete(0,END)
e3.delete(0,END)
e4.delete(0,END)
e1.insert(10,"Novak")
e2.insert(10,"Djokovic")
e3.insert(10,"30-15")
e4.insert(10,"3-1")
e1.grid(row=0,column=1)
e2.grid(row=1, column=1)
e3.grid(row=2, column=1)
e4.grid(row=3, column=1)
Button(self,text='Run', command=self.run_script).grid(row=4, column=1, sticky=W, pady=4)
def write(self, txt):
self.text1.insert(INSERT, txt)
def __init__(self, master=None):
Frame.__init__(self, master)
self.pack()
self.build_widgets()
root = Tk()
app = App(master = root)
app.mainloop()
I am making a program and i have a problem. When using time.sleep() like it shows in the code, i would like it to wait 5 secs after the first label appears and then show the second one, but instead when i press the 'start' button it waits 5 secs and then displays both labels at once. (The code i am interested in is just at the end, in guess_number)
Here's the code:
from tkinter import *
from tkinter import font
from datetime import datetime
import time
class Window(Frame):
def __init__(self, master):
Frame.__init__(self, master)
self.master = master
self.master.resizable(0,0)
master.title("Arcade Games")
master.geometry("800x600+560+240")
now = datetime.now()
hour = now.hour
minutes = now.minute
b = Button(self, text="Guess the number", command=self.new_window, cursor='hand2', relief='groove')
b.pack()
self.customFont = font.Font(master, font="Heraldica", size=12)
labelTime = Label(self.master, text=str(hour)+" : "+str(minutes), font=self.customFont)
labelTime.pack(side='bottom')
def new_window(self):
id = "Welcome to the 'Guess your number' game!\nAll you need to do is follow the steps\nand I will guess your number!\n\nClick the button to start!!"
self.window = Toplevel(self.master)
self.window.resizable(0,0)
self.label = Label(self.window, text=id, font=self.customFont)
self.label.pack(side="top", fill="both", padx=20, pady=20)
self.button = Button(self.window, text="Start", relief='groove')
self.button.config(width=20, height=2)
self.button.bind("<Button-1>", self.guess_number)
self.button.pack()
self.window.title("Guess the number")
self.window.geometry("400x300+710+390")
def guess_number(self, event):
self.button.destroy()
self.label.destroy()
labelGuess = Label(self.window, text="Pick any number.\nIt can be 3, 500 or even 1,324,324", font=self.customFont)
labelGuess.pack(padx=20, pady=20)
time.sleep(5)
labelGuess1 = Label(self.window, text="Now double it", font=self.customFont)
labelGuess1.pack(padx=20, pady=20)
if __name__ == "__main__":
root = Tk()
view = Window(root)
view.pack(side="top", fill="both")
root.mainloop()
Any help is appreciated!
Rather than use time.sleep() to stop the main task, try scheduling an event with tkinter's after(), like so:
def guess_number(self, event):
self.button.destroy()
self.label.destroy()
labelGuess = Label(self.window, text="Pick any number.\nIt can be 3, 500 or even 1,324,324", font=self.customFont)
labelGuess.pack(padx=20, pady=20)
self.window.after(5000, self.make_guess1_visible)
def make_guess1_visible(self):
labelGuess1 = Label(self.window, text="Now double it", font=self.customFont)
labelGuess1.pack(padx=20, pady=20)