root = Tk(), are there any alternatives? - python

does anyone know any alternatives for:
root = tk()
when i run my program, multiple windows run at the same time, just wondering whether there is an alternative so that they both dont open at the same time. The second window that opens as soon as the program is run should be launched when a button on the initial window is pressed. I also tried using:
root = Toplevel()
but the results are the same.
any ideas? thanks
def Search_Inventory():
#---First Window----
root = Toplevel()
root.title("Warehouse Inventory Control System")
root.configure(bg = "black")
#----Title displayed under the company logo on the first window----
Title_Screen = Label(root,
text="Warehouse Inventory Control System",
fg="grey",
bg="black",
font="Helevetica 25 bold",
pady = "50",
padx = "50",
).grid(row=3, column=4)
#----Interactive Input Boxes for the User----
#----Label to Notify what is needed in the entry box----
PN_Info_Label = Label(root,
text = "Part Number:",
fg="white",
bg="black",
font="Helevetica 15 bold",
padx = 50,
).grid(row=14, column=3, rowspan = 2)
#----Input Box for Part Number
PN_Display = StringVar()
Input_PartNumber = Entry(root,
textvariable=PN_Display,
fg = "blue",
font = "Helevtica 25 bold",
).grid(row=14, column=4)
#----A button that will proceed to the next part of the program----
Search_Button = Button(root,
text = "Search Inventory",
fg = "Blue",
bg = "Grey",
bd = 2,
font="Helevetica 15 bold",
command=lambda:Search_Prod(PN_Display.get()),
height = 1,
width = 15,
).grid(row=16, column=4,pady = 25,padx = 25,)
#----Information regarding how to enter the part number---
Info = Label(root,
text="Please Use Capitals to Enter Part Number",
fg= "red",
bg = "black",
font = "helevetica 12 bold",
).grid(row = 15, column = 4)
#----Adding the company logo to the first window----
photo = PhotoImage(file="image.gif")
photoLabel = Label(image=photo)
photoLabel.image = photo
photoLabel.grid(row=1, column=4, pady = 10)
#----Linking the Help Document----
Help_Button = Button(root,
text = "Help",
command=Help_PDF,
fg = "Red",
bg = "Black",
height = "1",
bd = "2",
font = "Helevetica 20 bold",
width = "4",
).grid(row=0, column=5, pady= 10,padx = 50, sticky = E)
#----Saying who the program was made by----
Credits = Label(root,
text = "Created By: Me",
fg = "White",
bg = "Black",
font = "Helevetica 10 underline",
).grid(row = 19, column = 5)
#To Make Sure that the window doesn't close
root.mainloop()
thats the subroutine that meant to run later but runs straight away.
root_menu = frame()
root_menu.title("Warehouse Inventory Control System")
root_menu.configure(bg = "black")
photo = PhotoImage(file="logo.gif")
photoLabel = Label(image=photo)
photoLabel.image = photo
photoLabel.grid(row=1, column=3,columnspan = 4, sticky = N)
Title_Screen = Label(root_menu,
text="Welcome to the SsangYong\n Warehouse Inventory Control System",
fg="grey",
bg="black",
font="Helevetica 25 bold",
pady = "50",
padx = "50",
).grid(row=2, column=3)
Search_Inventory = Button(root_menu,
command = Search_Inventory(),
text = "Search Inventory",
fg = "Blue",
bg = "Grey",
bd = 2,
font="Helevetica 12 bold",
height = 1,
width = 50,
).grid(row=16, column=3,pady = 25,padx = 25,)
Add_Stock = Button(root_menu,
text = "Add New Items",
fg = "Blue",
bg = "Grey",
bd = 2,
font="Helevetica 12 bold",
height = 1,
width = 60,
).grid(row=15, column=3,pady = 25,padx = 25,)
Print_Report = Button(root_menu,
text = "Print Stock Report",
fg = "Blue",
bg = "Grey",
bd = 2,
font="Helevetica 12 bold",
height = 1,
width = 70,
).grid(row=17, column=3,pady = 25,padx = 25,)
Help_Button = Button(root_menu,
text = "Help",
command=Help_PDF,
fg = "Red",
bg = "Black",
height = "1",
bd = "2",
font = "Helevetica 20 bold",
width = "4",
).grid(row=1, column=3,rowspan = 2, sticky= NE)
Credits = Label(root,
text = "Created By:mk",
fg = "White",
bg = "Black",
font = "Helevetica 10 underline",
).grid(row = 19, column = 5)
root_menu.mainloop()
this is what is meant to pop up initially but comes completely mixed up with the other one.

does anyone know any alternatives for: root = tk() [sic]
There is no alternative. A tkinter application absolutely must have a single root window. If you do not explicitly create one (and you should), one will be created for you the first time you create any other widget.
The second window that opens as soon as the program is run should be launched when a button on the initial window is pressed.
The reason for this is that you are telling it to open immediately. Take a look at this code:
Search_Inventory = Button(root_menu,
command = Search_Inventory(),
The above code is identical to this:
result = Search_Inventory()
Search_Inventory = Button(root_menu, command=result)
Notice the lack of () on the command. The command attribute requires a reference to a function.

command= needs function name - callback - it means without ()
But you have () in
command = Search_Inventory()
and this is why this is executed at start, not when you click button
BTW: tkinter need only one mainloop() - if you use two mainloop() then it works incorrectly.
EDIT: Problem with image is because you didn't set parent for Label in second window
photoLabel = Label(image=photo)
so it used main window as default
You need
photoLabel = Label(root, image=photo)
EDIT: minimal working code
from tkinter import *
def Help_PDF():
pass
def Search_Inventory():
#--- Second Window ----
root = Toplevel()
Title_Screen = Label(root, text="Warehouse Inventory Control System")
Title_Screen.grid(row=3, column=4)
PN_Info_Label = Label(root, text="Part Number:")
PN_Info_Label.grid(row=14, column=3, rowspan=2)
PN_Display = StringVar()
Input_PartNumber = Entry(root, textvariable=PN_Display)
Input_PartNumber.grid(row=14, column=4)
Search_Button = Button(root, text="Search Inventory",
command=lambda:Search_Prod(PN_Display.get()))
Search_Button.grid(row=16, column=4, pady=25, padx=25)
Info = Label(root, text="Please Use Capitals to Enter Part Number")
Info.grid(row=15, column=4)
photo = PhotoImage(file="image.gif")
photoLabel = Label(root, image=photo)
photoLabel.image = photo
photoLabel.grid(row=1, column=4, pady=10)
Help_Button = Button(root, text="Help",
command=Help_PDF)
Help_Button.grid(row=0, column=5, pady=10, padx=50, sticky=E)
Credits = Label(root, text="Created By: Me")
Credits.grid(row=19, column=5)
# --- First Window ---
root_menu = Tk()
photo = PhotoImage(file="logo.gif")
photoLabel = Label(root_menu, image=photo)
photoLabel.image = photo
photoLabel.grid(row=1, column=3, columnspan=4, sticky=N)
Title_Screen = Label(root_menu, text="Welcome to the SsangYong\n Warehouse Inventory Control System",)
Title_Screen.grid(row=2, column=3)
Search_Inventory = Button(root_menu, text="Search Inventory",
command=Search_Inventory)
Search_Inventory.grid(row=16, column=3, pady=25, padx=25)
Add_Stock = Button(root_menu, text="Add New Items")
Add_Stock.grid(row=15, column=3, pady=25, padx=25)
Print_Report = Button(root_menu, text="Print Stock Report")
Print_Report.grid(row=17, column=3, pady=25, padx=25)
Help_Button = Button(root_menu, text="Help",
command=Help_PDF)
Help_Button.grid(row=1, column=3, rowspan=2, sticky=NE)
Credits = Label(root_menu, text="Created By:mk")
Credits.grid(row=19, column=5)
root_menu.mainloop()

Related

How to know which button is pressed in tkinter? [duplicate]

This question already has answers here:
tkinter creating buttons in for loop passing command arguments
(3 answers)
Closed last year.
from tkinter import *
from Createwindow import *
button_name = ""
def click():
window = Tk()
window.geometry("600x500")
frame = Frame(window, bg = "#161853", width = 600, height = 500)
row_ = 0
column_ = 0
list = []
with open ("Passwords.txt", 'r') as data_file:
data = data_file.readlines()
for i in data:
names = i.split("|")
list.append(names[0])
for i in range(len(list)):
name = list[i]
button_ = Button(frame,text=name, font=("Helvetica", 12), width=16, bg="white", fg="black", command=create_window)
button_.grid(row=row_, column=column_, padx=(25, 0), pady=(25,0))
column_ += 1
if column_ == 3:
row_ += 1
column_ = 0
button_name = button_.cget('text')
frame.pack(fill="both", expand=True)
window.mainloop()
def create_window():
def fill_fields():
with open ("Passwords.txt", 'r') as data_file:
data = data_file.readlines()
for i in data:
names = i.split("|")
if names[0] == button_name:
Website_.insert(0, names[0])
Username_.insert(0, names[1])
Password_.insert(0, names[2])
def save_password():
if Website_.get() == "" or Username_.get() == "" or Password_.get() == "":
window = Tk()
Error_Message = Label(window, text = "Error! Please fill all the above fields.", bg="red", fg="white", font=("Arial", 16))
Error_Message.pack()
window.mainloop()
else:
with open("Passwords.txt" , 'a') as file:
file.write(Website_.get() + "|" + Username_.get() + "|" + Password_.get() + "\n")
window = Tk()
window.geometry("600x500")
window.configure(bg="#161853")
window.minsize(600, 500)
frame = Frame(window, bg="#161853")
frame.rowconfigure(2, weight=1)
frame.columnconfigure([0, 1, 2], weight=1)
Text = Label(frame, text="Save your password here", font=("Helvetica", 14), fg="white", bg="#161853")
Text.grid(row=0, column=1, pady=(0,25))
Website = Label(frame, text="Website:", font=("Helvetica", 14), fg="white", bg="#161853")
Website.grid(row=1, column=0, padx=(0, 15), pady=(0,20))
Website_ = Entry(frame, width=25)
Website_.grid(row=1, column=1, pady=(0, 20))
Username = Label(frame, text="Username/Email:", font=("Helvetica", 14), fg="white", bg="#161853")
Username.grid(row=2, column=0, padx=(0, 15), pady=(0, 20))
Username_ = Entry(frame, width=25)
Username_.grid(row=2, column=1, pady=(0, 20))
Password = Label(frame, text="Password:", font=("Helvetica", 14), fg="white", bg="#161853" )
Password.grid(row=3, column=0, padx=(0, 15), sticky="s")
Password_ = Entry(frame, width=25)
Password_.grid(row=3, column=1, pady=(0, 30), sticky="s")
Generate = Button(frame, text="Generate Password", font=("Helvetica", 12), width=16)
Generate.grid(row=3, column=2, sticky="s")
Save = Button(frame, text="Save Password", font=("Helvetica", 12), width=14, command=save_password)
Save.grid(row=4, column=1)
frame.place(relx=0.5, rely=0.5, anchor="center")
fill_fields()
window.mainloop()
In this piece of code basically I am creating a window where all the passwords saved in password.txt file will appear.
The code creates a button on the name of the website whose password is saved.
What I want to do is that when that button is clicked I want to get the text of the clicked button bcoz all the buttons are created automatically they have same name and the text of button is the one that is created in the last iteration.
You may pass the argument while adding click event in dynamic generated button.
for example below is your old code:
button_ = Button(frame,text = name , font = ("Helvetica", 12), width = 16, bg = "white" , fg = "black", command= create_window)
If you want to get the value of name when click on this button. Just do as like below:
button_ = Button(frame,text = name , font = ("Helvetica", 12), width = 16, bg = "white" , fg = "black", command= create_window(name))
Here i'm adding name argument in create_window function.
That i had already impletemented in my project and its working fine. Please try it and let me know if you will face any issue.
Please check below link for more details.
https://www.delftstack.com/howto/python-tkinter/how-to-pass-arguments-to-tkinter-button-command/

How to call a function when a button is pressed in tkinter?

I have written my code so that when the button "SignIn" is pressed it calls the function "Login". However, every time I run the code and press the button, the error message "_tkinter.TclError: image "pyimage2" doesn't exist" is displayed and I cannot seem to find a solution which fixes my code.
import tkinter
def Login():
window = tkinter.Tk()
window.title("Eat Well")
window.geometry("295x400")
UsernameLbl = tkinter.Label(window, text = "Username", fg= "white", bg= "black")
Utext = tkinter.Entry(window)
PasswordLbl = tkinter.Label(window, text = "Password", fg = "white", bg= "black")
Ptext = tkinter.Entry(window, show="*")
Login = tkinter.Button(window, text = "Login", fg = "black", bg = "honeydew", command = window.destroy )
window.configure(background= "#008bb5")
Photo = tkinter.PhotoImage(file = "Eating.gif")
w = tkinter.Label(window, image = Photo)
w.pack()
UsernameLbl.pack()
Utext.pack()
PasswordLbl.pack()
Ptext.pack()
Login.pack()
window.mainloop()
def Mainscreen():
window = tkinter.Tk()
window.title("Eat Well")
window.geometry("295x400")
Question = tkinter.Label(window, text = "Would you like to create an account or login?", fg = "black", bg = "white")
Create = tkinter.Button(window, text = "Create an account", fg = "white", bg = "black")
SignIn = tkinter.Button(window, text = "Login", fg = "white", bg = "black", command = Login)
Quit = tkinter.Button(window, text = "Quit", fg = "white", bg = "black", command = window.destroy)
window.configure(background = "#008bb5")
Photo = tkinter.PhotoImage(file = "Eating.gif")
w = tkinter.Label(window, image = Photo)
w.pack()
Question.pack()
Create.pack()
SignIn.pack()
Quit.pack()
window.mainloop()
Mainscreen()
When the SignIn button is pressed, the MainScreen should be destroyed and the Login screen should be opened. However, currently whenever the login button is pressed on the main screen, the MainScreen remains open and the Login screen is displayed as a blank screen.
This should work. Notice the use of
`tkinter.Toplevel()
and Image.open. This is because the button that calls the function is itself sitting in an active window.
import tkinter
from PIL import Image, ImageTk
def Login():
window = tkinter.Toplevel()
window.title("Eat Well")
window.geometry("295x400")
UsernameLbl = tkinter.Label(window, text = "Username", fg= "white", bg= "black")
Utext = tkinter.Entry(window)
PasswordLbl = tkinter.Label(window, text = "Password", fg = "white", bg= "black")
Ptext = tkinter.Entry(window, show="*")
Login = tkinter.Button(window, text = "Login", fg = "black", bg = "honeydew", command = window.destroy )
window.configure(background= "#008bb5")
im = Image.open("Eating.gif")
Photo = ImageTk.PhotoImage(im)
w = tkinter.Label(window)
w.pack()
UsernameLbl.pack()
Utext.pack()
PasswordLbl.pack()
Ptext.pack()
Login.pack()
window.mainloop()
def Mainscreen():
window = tkinter.Tk()
window.title("Eat Well")
window.geometry("295x400")
Question = tkinter.Label(window, text = "Would you like to create an account or login?", fg = "black", bg = "white")
Create = tkinter.Button(window, text = "Create an account", fg = "white", bg = "black")
SignIn = tkinter.Button(window, text = "Login", fg = "white", bg = "black", command = Login)
Quit = tkinter.Button(window, text = "Quit", fg = "white", bg = "black", command = window.destroy)
window.configure(background = "#008bb5")
im = Image.open("Eating.gif")
Photo = ImageTk.PhotoImage(im)
w = tkinter.Label(window)
w.pack()
Question.pack()
Create.pack()
SignIn.pack()
Quit.pack()
window.mainloop()
Okay so the problem is you are trying to run two instances of Tk() simultaneously which you should not. Reasons are described here and here also
Instead of window = tkinter.Tk() in your Login() you can use window = tkinter.Toplevel() to solve the problem like following:
import tkinter
def Login():
# window = tkinter.Tk()
window = tkinter.Toplevel()
window.title("Eat Well")
window.geometry("295x400")
user_name_label = tkinter.Label(window, text="Username", fg="white", bg="black")
user_name_text = tkinter.Entry(window)
password_label = tkinter.Label(window, text="Password", fg="white", bg="black")
password_text = tkinter.Entry(window, show="*")
login = tkinter.Button(window, text="Login", fg="black", bg="honeydew", command=window.destroy)
window.configure(background="#008bb5")
photo = tkinter.PhotoImage(file="Eating.gif")
w = tkinter.Label(window, image=photo)
w.pack()
user_name_label.pack()
user_name_text.pack()
password_label.pack()
password_text.pack()
login.pack()
window.mainloop()
def Mainscreen():
window = tkinter.Tk()
window.title("Eat Well")
window.geometry("295x400")
question = tkinter.Label(window, text="Would you like to create an account or login?", fg="black", bg="white")
create = tkinter.Button(window, text="Create an account", fg="white", bg="black")
sign_in = tkinter.Button(window, text="Login", fg="white", bg="black", command=Login)
quit = tkinter.Button(window, text="Quit", fg="white", bg="black", command=window.destroy)
window.configure(background="#008bb5")
photo = tkinter.PhotoImage(file="Eating.gif")
w = tkinter.Label(window, image=photo)
w.pack()
question.pack()
create.pack()
sign_in.pack()
quit.pack()
window.mainloop()
Mainscreen()

Fixing the design of RadioButtons in Tkinter

I want to link my radiobuttons with the title, like merge my title with the radio button. This is the code which I implemented:
but1 = Radiobutton(text = "Current",value = 0)
but1.place(x =400,y = 150)
but2 = Radiobutton(text = "Previous",value = 1)
but2.place(x =320,y = 150)
but3 = Radiobutton(text = "Current",value = 2)
but3.place(x =400,y = 260)
but4 = Radiobutton(text = "Previous",value = 3)
but4.place(x =320,y = 260)
the_window.geometry("510x430")
label1 = Label(the_window,text = "Most-Discussed \n TV SHOW", font =
"Times 10 bold")
label1.place(x = 350,y = 110)
label2 = Label(the_window,text = "Most-Discussed \n TV SHOW", font =
"Times 10 bold")
label2.place(x = 350,y = 230)
This is the actual result:
This is the expected result:
I don't know if you know this, but that widget is called a LabelFrame. See the below example.
P.S. I have changed your geometry manager to grid
import tkinter as tk
root = tk.Tk()
f1 = tk.LabelFrame(root, text="Most-Discussed \n TV SHOW", labelanchor="n", font="Verdana 12 bold", bd=4)
f1.grid(row=0, column=0, padx=10, pady=10)
f2 = tk.LabelFrame(root, text="Music Vinyl \n Album Chart", labelanchor="n", font="Verdana 12 bold", bd=4)
f2.grid(row=1, column=0, padx=10, pady=10)
but1 = tk.Radiobutton(f1, text="Current", value = 0)
but1.grid(row=0, column=0)
but2 = tk.Radiobutton(f1, text="Previous" ,value = 1)
but2.grid(row=0, column=1)
but3 = tk.Radiobutton(f2, text="Current", value = 2)
but3.grid(row=0, column=0)
but4 = tk.Radiobutton(f2, text="Previous" ,value = 3)
but4.grid(row=0, column=1)
root.mainloop()

Tkinter trying to destroy a Label defined inside a function after the function has finished

from tkinter import *
def spaces(int1,int2):
if int1 == 1:
return(int2*"\n")
else:
return(int2*" ")
def submitButton():
subButton_text = subButton.get()
try:
informationText.destroy()
except UnboundLocalError:
print("an error has occured.")
print("Attempting to run with the error.")
pass
informationText = Label(window, text=subButton_text, bg = "grey",
fg = "white", font = "none 12 bold")
informationText.grid(row=4,column=0,sticky=W)
#informationText.destroy()
#return informationText
def exit_Button():
window.destroy()
window = Tk()
window.title("Learning tkinter")
window.configure(background="grey")
subButton = StringVar()
#pic1 = PhotoImage(file="test.png")
#Label(window, image=pic1, bg = "grey").grid(row = 0, column = 0, sticky=W)
Label(window, text="Please enter a value", bg = "grey",
fg = "white", font = "none 12 bold").grid(row=0,column=0,sticky=W)
Entry(window, width=50, bg="white",textvariable=subButton).grid(row=1,column=0,stick=W)
subButton.set("default value")
Button(window, text="Submit", width=10,
command = submitButton).grid(row=2,column=0, sticky=W)
Label (window, text="\nInformation:", bg="grey", fg="white",
font="none 12 bold").grid(row=3,column=0, sticky=W)
Button (window, text="Save\nand exit", width=8,
command=exit_Button).grid(row=0,column=2,sticky=NW)
Label(window, text=spaces(1,10), bg = "grey",
fg = "white", font = "none 12 bold").grid(row=100,column=0,sticky=W)
Label(window, text=spaces(2,20), bg = "grey",
fg = "white", font = "none 12 bold").grid(row=0,column=1,sticky=W)
window.mainloop()
This is my code for a simple tkinter program. When the "submitButton" it creates create a Label called "informationText". But when the button is clicked again with new text I want it to destroy the old text, but it doesn't work. If I destroy the text immediately after creating it (commented out) it works.
Is it because I declared it in a function? If so how can I destroy it after the function has finished?
(first ask, tips appreciated for better questions in the future)
If you write you code in a class you will be able to use class attributes to store your label and update it later.
Going off what you code is trying to do the below code would be the class equivalent that works. That said I think you should update the label instead of destroying it.
import tkinter as tk
class MyApp(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
self.information_text = None
self.title("Learning tkinter")
self.configure(background="grey")
self.subButton = tk.StringVar()
tk.Label(self, text="Please enter a value", bg = "grey", fg = "white", font = "none 12 bold").grid(row=0,column=0,sticky="w")
tk.Entry(self, width=50, bg="white",textvariable=self.subButton).grid(row=1,column=0,stick="w")
self.subButton.set("default value")
tk.Button(self, text="Submit", width=10, command = self.submitButton).grid(row=2,column=0, sticky="w")
tk.Label (self, text="\nInformation:", bg="grey", fg="white", font="none 12 bold").grid(row=3,column=0, sticky="w")
tk.Button (self, text="Save\nand exit", width=8, command=self.exit_Button).grid(row=0,column=2,sticky="nw")
tk.Label(self, text=self.spaces(1,10), bg = "grey", fg = "white", font = "none 12 bold").grid(row=100,column=0,sticky="w")
tk.Label(self, text=self.spaces(2,20), bg = "grey", fg = "white", font = "none 12 bold").grid(row=0,column=1,sticky="w")
def spaces(self, int1, int2):
if int1 == 1:
return(int2*"\n")
else:
return(int2*" ")
def submitButton(self):
try:
self.information_text.destroy()
self.information_text = None
except:
print("an error has occured.")
print("Attempting to run with the error.")
self.information_text = tk.Label(self, text=self.subButton.get(), bg = "grey", fg = "white", font = "none 12 bold")
self.information_text.grid(row=4,column=0,sticky="w")
def exit_Button(self):
self.destroy()
if __name__ == "__main__":
app = MyApp()
app.mainloop()
My 2nd example will use config() to update the label instead of having to destroy it. I think this might work better for your needs here.
import tkinter as tk
class MyApp(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
self.title("Learning tkinter")
self.configure(background="grey")
self.subButton = tk.StringVar()
tk.Label(self, text="Please enter a value", bg = "grey", fg = "white", font = "none 12 bold").grid(row=0,column=0,sticky="w")
tk.Entry(self, width=50, bg="white",textvariable=self.subButton).grid(row=1,column=0,stick="w")
self.subButton.set("default value")
tk.Button(self, text="Submit", width=10, command = self.submitButton).grid(row=2,column=0, sticky="w")
tk.Label (self, text="\nInformation:", bg="grey", fg="white", font="none 12 bold").grid(row=3,column=0, sticky="w")
tk.Button (self, text="Save\nand exit", width=8, command=self.exit_Button).grid(row=0,column=2,sticky="nw")
tk.Label(self, text=self.spaces(1,10), bg = "grey", fg = "white", font = "none 12 bold").grid(row=100,column=0,sticky="w")
tk.Label(self, text=self.spaces(2,20), bg = "grey", fg = "white", font = "none 12 bold").grid(row=0,column=1,sticky="w")
self.information_text = tk.Label(self, text="", bg = "grey", fg = "white", font = "none 12 bold")
self.information_text.grid(row=4,column=0,sticky="w")
def spaces(self, int1, int2):
if int1 == 1:
return(int2*"\n")
else:
return(int2*" ")
def submitButton(self):
self.information_text.config(text=self.subButton.get())
def exit_Button(self):
self.destroy()
if __name__ == "__main__":
app = MyApp()
app.mainloop()

Button location(grid) in tkinter Python

Hey guys I have a problem and I have been searching for answers but I can't seem to solve my problem.
I want to move my "Enter" and "Quit" buttons more to the bottom of my window but I'm not sure I understand the grid function.
I made two frames inside my window and the buttons are in the bottom frame but I can't seem to get them lower with the row function.
I'm like just started with Python and have no experience with programming so this is my first project.(please don't laugh)
#import tkinder module
from tkinter import *
#make frame
root = Tk()
root.geometry("600x300")
top_frame = Frame(root)
bottom_frame = Frame(root)
top_frame.pack()
bottom_frame.pack()
#headline
headline = Label(top_frame, text="Welcome to PrintAssistant.", bg='blue', fg='white')
headline.config(font=('Courier', 27))
headline.grid(padx=10, pady=10)
Name = Label(bottom_frame, text="Name:", fg='blue')
Name.config(font=('Courier', 20))
Name.grid(row=1)
Password = Label(bottom_frame, text="Password:", fg='blue')
Password.config(font=('Courier', 20))
Password.grid(row=2)
Name_entry = Entry(bottom_frame)
Name_entry.grid(row=1, column=1)
Password_entry = Entry(bottom_frame)
Password_entry.grid(row=2, column=1)
#enter_button
enter_button = Button(bottom_frame, text="Enter", bg='blue', fg='white')
enter_button.config(height = 2, width = 15)
enter_button.grid(sticky = S)
#quit_button
quit_button = Button(bottom_frame, text="Quit", bg="blue", fg="white")
quit_button.config(height = 2, width = 15)
quit_button.grid(sticky = S)
root.mainloop()
Here is a quick and simple way to have your buttons sit at the bottom of your program.
First move enter_button and quit_button to the root window. A frame is not needed here.
then add root.rowconfigure() and apply a weight of 1 to the row the buttons are on. Configuring the row with a weight allows that row to expand and contract with the frame or window it is placed in. In this case we placed the buttons in root so we configured root. You could do the same to a frame but that is just adding another layer that is not needed for something simple like this.
Here is a section of code you can replace in your program and the result should be what you are looking for. Note I placed the buttons side by side but you can accomplish a top to bottom with the same method.
Edit:
I forgot to add the columnspan part. You also need to add a columnspan of the other frames so you can have your buttons placed centered when side by side. A columspan is used to tell the program how many columns that widget is going to be taking up. the same can be done with rows as well.
top_frame.grid(row = 0, column = 0, columnspan = 2)
bottom_frame.grid(row = 1, column = 0, columnspan = 2)
root.rowconfigure(2, weight = 1)
#enter_button
enter_button = Button(root, text="Enter", bg='blue', fg='white')
enter_button.config(height = 2, width = 15)
enter_button.grid(row = 2, column=0, sticky = 'se')
#quit_button
quit_button = Button(root, text="Quit", bg="blue", fg="white")
quit_button.config(height = 2, width = 15)
quit_button.grid(row = 2, column=1, sticky = 'sw')
If you want to keep the enter button on top of the quit button then you could do the following.
top_frame.grid(row = 0, column = 0) # remove columnspan or set it to 1
bottom_frame.grid(row = 1, column = 0)# remove columnspan or set it to 1
root.rowconfigure(2, weight = 1)
root.rowconfigure(3, weight = 0)
#enter_button
enter_button = Button(root, text="Enter", bg='blue', fg='white')
enter_button.config(height = 2, width = 15)
enter_button.grid(row = 2, column = 0, sticky = 's')
#quit_button
quit_button = Button(root, text="Quit", bg="blue", fg="white")
quit_button.config(height = 2, width = 15)
quit_button.grid(row = 3, column = 0, sticky = 's')
If you are just trying to place a little space between your entry fields and buttons you could use an spacer label. Something like this:
#empty row spacers
spacer1 = Label(bottom_frame, text = "")
spacer1.grid(row = 3)
spacer2= Label(bottom_frame, text = "")
spacer2.grid(row = 4)
#enter_button
enter_button = Button(bottom_frame, text="Enter", bg='blue', fg='white')
enter_button.config(height = 2, width = 15)
enter_button.grid(row = 5, column=1)
#quit_button
quit_button = Button(bottom_frame, text="Quit", bg="blue", fg="white")
quit_button.config(height = 2, width = 15)
quit_button.grid(row = 6, column=1)
I think you can do it by adding an extra Frame and set it to the bottom. After that put the Enter and Quit buttons on that frame. I have modified your code and you can try it.
#import tkinder module
from tkinter import *
#make frame
root = Tk()
root.geometry("600x300")
top_frame = Frame(root)
center_frame = Frame(root)
bottom_frame = Frame(root)
top_frame.pack()
center_frame.pack()
bottom_frame.pack(side = BOTTOM, fill = BOTH)
#headline
headline = Label(top_frame, text="Welcome to PrintAssistant.", bg='blue', fg='white')
headline.config(font=('Courier', 27))
headline.grid(padx=10, pady=10)
Name = Label(center_frame, text="Name:", fg='blue')
Name.config(font=('Courier', 20))
Name.grid(row=1)
Password = Label(center_frame, text="Password:", fg='blue')
Password.config(font=('Courier', 20))
Password.grid(row=2)
Name_entry = Entry(center_frame)
Name_entry.grid(row=1, column=1)
Password_entry = Entry(center_frame)
Password_entry.grid(row=2, column=1)
#enter_button
enter_button = Button(bottom_frame, text="Enter", bg='blue', fg='white')
enter_button.config(height = 2, width = 15)
enter_button.pack()
#quit_button
quit_button = Button(bottom_frame, text="Quit", bg="blue", fg="white")
quit_button.config(height = 2, width = 15)
quit_button.pack()
root.mainloop()
Please leave a comment if it worked for you :)

Categories