I am creating a login/sign-up system using tkinter. When the user clicks on either login or sign-up, I want all widgets to disappear for new widgets to appear on the screen depending on if they clicked on login or sign-up. So if they clicked on login, new labels and textboxes would appear for their username and password. The problem is I am using .place() and the tutorials I have seen are mostly using pack_forget or grid_forget
My Code:
from tkinter import *
class Window:
def __init__(self, master):
root.title("Sign Up or Login")
root.minsize(width=300, height=300)
root.maxsize(width=300,height=300)
self.login_button = Button(master, text = "Login", width=18,height=4, command=self.LoginPage)
self.signup_button = Button(master, text = "Sign Up", width=18,height=4, command=self.SignupPage)
self.login_button.place(relx=0.5, rely=0.3, anchor=CENTER)
self.signup_button.place(relx=0.5, rely=0.7, anchor=CENTER)
def LoginPage(self):
root.title("Login")
def SignupPage(self):
root.title("Sign Up")
root = Tk()
run = Window(root)
root.mainloop()
My Interface:
No matter you use place,pack or grid. The best solution works for all:
for widgets in root.winfo_children():
widgets.destory()
It loops through widgets and delete them. You can try:
from tkinter import *
class Window:
def __init__(self, master):
root.title("Sign Up or Login")
root.minsize(width=300, height=300)
root.maxsize(width=300,height=300)
self.login_button = Button(master, text = "Login", width=18,height=4, command=self.LoginPage)
self.signup_button = Button(master, text = "Sign Up", width=18,height=4, command=self.SignupPage)
self.login_button.place(relx=0.5, rely=0.3, anchor=CENTER)
self.signup_button.place(relx=0.5, rely=0.7, anchor=CENTER)
def LoginPage(self):
root.title("Login")
self.Restore()
def SignupPage(self):
root.title("Sign Up")
self.Restore()
def Restore(self):
for widgets in root.winfo_children():
widgets.destroy()
root = Tk()
run = Window(root)
root.mainloop()
Related
I have created a program in Python using tkinter. I have created two seperate classes for two windows. I am opening the other window by clicking on the button of one window. I want it such that when new window opens the other should close. My code is
from tkinter import Tk, Toplevel
from tkinter import *
def main():
main_window = Tk()
app = first(main_window)
main_window.mainloop()
class first:
def __init__(self, root):
self.root = root
self.root.title('First window')
self.root.geometry('1350x700+0+0')
frame1 = Frame(self.root, bg='black')
frame1.place(x=400, y=50, width=400, height=600)
btn_1 = Button(frame1, command=self.second_window, text='open second window', font=("Times New Roman", 15, 'bold'), bd=3,
relief=RIDGE,
cursor='hand2', bg='red', fg='white', activeforeground='white', activebackground='red')
btn_1.place(x=100, y=350, width=220, height=35)
def second_window(self):
self.new_window = Toplevel(self.root)
self.app = second(self.new_window)
class second:
def __init__(self, root):
self.root = root
self.root.title('Second Window')
self.root.geometry("1350x700+0+0")
self.root.config(bg='white')
frame1 = Frame(self.root, bg='black')
frame1.place(x=400, y=50, width=400, height=600)
btn_1 = Button(frame1, command=self.first_window, text='open first window',
font=("Times New Roman", 15, 'bold'), bd=3,
relief=RIDGE,
cursor='hand2', bg='red', fg='white', activeforeground='white', activebackground='red')
btn_1.place(x=100, y=350, width=220, height=35)
def first_window(self):
self.new_window = Toplevel(self.root)
self.app = first(self.new_window)
if __name__ == '__main__':
main()
I understand this question is quite common but I cant find a soloution on here which would be applicable for my code.
You can destroy the previous window and start a new window using Tk class
Here is an example
from tkinter import *
from tkinter.ttk import Button
root = Tk()
root.title("title")
root.geometry("800x500")
def window2():
root.destroy()
window2_main = Tk()
Label(window2_main, text="Bye Bye").pack()
window2_main.mainloop()
a = Button(text="Click This", command=window2)
a.pack()
root.mainloop()
I am stuck at referencing methods and variables between classes in Tkinter.
Here is an simple example, I have three different types of windows, which I would like to put into different classes.
In the root window, I can click the button to open the second window, where I can input something in to the Text widget.
Also in the 2nd window I want the OK button to read the content in the Text widget and insert the content into another Text widget into the 3rd window. And the Cancel button can close the 2nd window and show the root window again.
There is many bugs in the code, because I couldn't figure out how to make cross references between classes to access the methods and variables.
Could anyone help me to accomplish that? Thanks.
from tkinter import *
from tkinter import scrolledtext
def main():
"""The main app function"""
root = Tk()
root_window = Root(root)
return None
class Root:
def __init__(self, root):
# Main root window configration
self.root = root
self.root.geometry("200x100")
self.btn_ok = Button(self.root, text="Open new window",
command=NewWindow)
self.btn_ok.pack(padx=10, pady=10)
def hide(self):
"""Hide the root window."""
self.root.withdraw()
def show(self):
"""Show the root window from the hide status"""
self.root.update()
self.root.deiconify()
def onClosing(self, window):
window.destroy()
self.show()
class NewWindow:
def __init__(self):
Root.hide()
self.new_window = Toplevel()
lbl = Label(self.new_window, text="Input here:")
lbl.pack(padx=10, pady=(10, 0), anchor=W)
# Create a scrolledtext widget.
self.new_content = scrolledtext.ScrolledText(
self.new_window, wrap=WORD,
)
self.new_content.pack(padx=10, expand=True, fill=BOTH, anchor=W)
# Respond to the 'Cancel' button.
btn_cancel = Button(self.new_window, text="Cancel", width=10,
command=lambda: Root.onClosing(self.new_window))
btn_cancel.pack(padx=10, pady=10, side=RIGHT)
# Add 'OK' button to read sequence
self.btn_ok = Button(self.new_window, text="OK", width=10,
command=WorkingWindow)
self.btn_ok.pack(padx=10, pady=10, side=RIGHT)
def readContent(self):
self.content = self.new_content.get(1.0, END)
self.new_window.destroy()
workwindow = WorkingWindow()
class WorkingWindow:
def __init__(self):
self.work_window = Toplevel()
self.work_content = scrolledtext.ScrolledText(self.work_window, wrap=WORD, font=("Courier New", 11))
self.work_content.pack(padx=10, expand=True, fill=BOTH, anchor=W)
self.work_content.insert(1.0, Root.content)
if __name__ == '__main__':
main()
You were almost there all you have to do is pass the instance of Root class to other class you are calling
Here is the corrected code:
from tkinter import *
from tkinter import scrolledtext
def main():
"""The main app function"""
root = Tk()
root_window = Root(root)
root.mainloop()
class Root:
def __init__(self, root):
# Main root window configration
self.root = root
self.root.geometry("200x100")
self.btn_ok = Button(self.root, text="Open new window",
command=lambda :NewWindow(self))
self.btn_ok.pack(padx=10, pady=10)
def hide(self):
"""Hide the root window."""
self.root.withdraw()
def show(self):
"""Show the root window from the hide status"""
self.root.update()
self.root.deiconify()
def onClosing(self, window):
window.destroy()
self.show()
class NewWindow:
def __init__(self, parent):
parent.hide()
self.new_window = Toplevel()
lbl = Label(self.new_window, text="Input here:")
lbl.pack(padx=10, pady=(10, 0), anchor=W)
# Create a scrolledtext widget.
self.new_content = scrolledtext.ScrolledText(
self.new_window, wrap=WORD,
)
self.new_content.pack(padx=10, expand=True, fill=BOTH, anchor=W)
# Respond to the 'Cancel' button.
btn_cancel = Button(self.new_window, text="Cancel", width=10,
command=lambda: parent.onClosing(self.new_window))
btn_cancel.pack(padx=10, pady=10, side=RIGHT)
# Add 'OK' button to read sequence
self.btn_ok = Button(self.new_window, text="OK", width=10,
command=self.readContent)
self.btn_ok.pack(padx=10, pady=10, side=RIGHT)
def readContent(self):
self.content = self.new_content.get(1.0, END)
self.new_window.destroy()
workwindow = WorkingWindow(self)
class WorkingWindow:
def __init__(self, parent):
self.work_window = Toplevel()
self.work_content = scrolledtext.ScrolledText(self.work_window, wrap=WORD, font=("Courier New", 11))
self.work_content.pack(padx=10, expand=True, fill=BOTH, anchor=W)
self.work_content.insert(1.0, parent.content)
if __name__ == '__main__':
main()
I am new to python and tkinter. I'm looking to make a simple window with a few buttons. When a button is pressed, I wish for it to disappear and instead reveal something behind it, a number, for instance.
How do I go about doing this? Below is an example code which generates a window with a button. Can I work with a code like this or should it look completely different?
from tkinter import *
class Button:
def __init__(self):
self.root = Tk()
self.root.title("Button program")
self.root.geometry("100x100")
self.frame = Frame(self.root)
self.btn = Button(self.root, width=2)
self.btn.grid(row=1, column=1)
self.root.mainloop()
Button()
How about this? You will have to rearrange it in the class 'cause I couldn't fit it in, but works for me
from tkinter import *
def press_btn():
btn.grid_forget()
lbl = Label(root, text="label", width=15)
lbl.grid(row=1, column=1)
root = Tk()
root.title("Button program")
root.geometry("100x100")
frame = Frame(root)
btn = Button(root, text="button", width=15, command=press_btn)
btn.grid(row=1, column=1)
root.mainloop()
a beginner here, I was hoping to open a new window after I logged the correct entry by trying to put import filename.py but it won't show after the tm.showinfo. I don't know what function that will make it happen at the same time it will closed or quit my login window.
I've tried my previous way of doing it to call a command and making a function for it but now I'm totally confused about it,
from tkinter import *
import tkinter.messagebox as tm
class adminlog(Frame):
def __init__(self, master):
super().__init__(master)
self.label_username = Label(self, text="Username")
self.label_password = Label(self, text="Password")
self.entry_username = Entry(self)
self.entry_password = Entry(self, show="*")
self.label_username.grid(row=0, sticky=E)
self.label_password.grid(row=1, sticky=E)
self.entry_username.grid(row=0, column=1)
self.entry_password.grid(row=1, column=1)
self.logbtn = Button(self, text="Login as Admin", command=self.lg_admin)
self.logbtn.grid(columnspan=2)
self.pack()
def lg_admin(self):
un = self.entry_username.get()
ps = self.entry_password.get()
if un == "admin" and ps == "pito":
tm.showinfo("Login Info", "Login Successfully")
import adminpage
else:
tm.showerror("Login Error", "Incorrect password or username")
admin = Tk()
a = adminlog(admin)
admin.mainloop()
I expect that after I am logged in, then a new window will open after the tm.showinfo shows.
It really depends upon your choice and feel. I will give you two methods and let you decide.
Disclaimer : I prefer the first method.
It is not a good practice to create two Tk() windows in the same program. What you can do is have one main window and configure it as and when you want. Here for example, the function clear_widgets() clears the login page and shows the next page.
import tkinter as tk
import tkinter.messagebox as tm
class adminlog(tk.Tk):
def __init__(self):
super().__init__()
tk.Label(self, text="Username").grid(row=0, sticky="e")
tk.Label(self, text="Password").grid(row=1, sticky="e")
self.entry_username = tk.Entry(self)
self.entry_password = tk.Entry(self, show="*")
self.entry_username.grid(row=0, column=1)
self.entry_password.grid(row=1, column=1)
logbtn = tk.Button(self, text="Login as Admin", command=self.lg_admin)
logbtn.grid(columnspan=2)
def adminpage(self):
self.clear_widgets()
tk.Label(self, text='Hello Admin !!', bg='brown', fg='white').grid(row=0, column=1, padx=20, pady=20)
def clear_widgets(self):
for widget in self.winfo_children():
widget.destroy()
def lg_admin(self):
un = self.entry_username.get()
ps = self.entry_password.get()
if un == "admin" and ps == "pito":
tm.showinfo("Login Info", "Login Successfully")
self.adminpage()
else:
tm.showerror("Login Error", "Incorrect password or username")
adminlog().mainloop()
If you really want another window and can't do without it, you should use a Toplevel. Here is a demonstration.
import tkinter as tk
import tkinter.messagebox as tm
class adminlog(tk.Tk):
def __init__(self):
super().__init__()
tk.Label(self, text="Username").grid(row=0, sticky="e")
tk.Label(self, text="Password").grid(row=1, sticky="e")
self.entry_username = tk.Entry(self)
self.entry_password = tk.Entry(self, show="*")
self.entry_username.grid(row=0, column=1)
self.entry_password.grid(row=1, column=1)
logbtn = tk.Button(self, text="Login as Admin", command=self.lg_admin)
logbtn.grid(columnspan=2)
def adminpage(self):
adp = tk.Toplevel(self)
tk.Label(adp, text='Hello Admin !!', bg='brown', fg='white').grid(row=0, column=1, padx=20, pady=20)
def lg_admin(self):
un = self.entry_username.get()
ps = self.entry_password.get()
if un == "admin" and ps == "pito":
tm.showinfo("Login Info", "Login Successfully")
self.adminpage()
else:
tm.showerror("Login Error", "Incorrect password or username")
adminlog().mainloop()
Here you can see, the login window won't go away (if it does, it will take the Toplevel with it also). So, I would recommend you to use the first method.
I have written a code in python 2.7 and i have created a root window with two buttons: submit and cancel when i press submit button, a new window opens and previous parent/root window gets iconify. Now i want that when i cut the child window, parent window should be deiconify, i am in a trouble that where to put the condition so that parent window gets deiconify?
from Tkinter import *
root = Tk()
root.title("test window")
root.geometry('400x220+500+250')
root.configure(background="dark gray")
def submit(*args):
root.iconify()
popup_root_window = Toplevel()
popup_root_window.geometry('300x50+550+300')
popup_root_window.resizable(width=False, height=False)
popup_root_window.focus_force()
popup_root_window.grab_set()
popup_root_window_label = Label(popup_root_window, text="new window open successfully.")
popup_root_window_label.pack(anchor=CENTER, padx=10, pady=20)
frame = Frame(root, bd=4, relief="raise", height=100, width=250)
frame.pack(fill="both", padx=70, pady=35)
frame.pack_propagate(0)
submit_button = Button(frame, text="Submit", command=submit, width=10)
submit_button.grid(row=0, column=0)
cancel_button = Button(frame, text="Cancel", width=10)
cancel_button.grid(row=0, column=1)
root.mainloop()
I wrote the below in 3.6 but it should still work in 2.7.
from tkinter import *
class App:
def __init__(self, root):
self.root = root
self.label1 = Label(self.root, text="I'm your main window.")
self.button = Button(self.root, text="Submit", command=self.command)
self.label1.pack()
self.button.pack()
def command(self):
self.root.iconify()
self.top = Toplevel(self.root)
self.label2 = Label(self.top, text="I'm your toplevel window.")
self.label2.pack()
self.top.protocol("WM_DELETE_WINDOW", self.close)
def close(self):
self.top.destroy()
self.root.deiconify()
root = Tk()
App(root)
root.mainloop()
You can use .protocol() on the event WM_DELETE_WINDOW to create a callback whenever the X is selected from the title bar of the designated window.
This is tested and working with Python 3.6 on Windows 10.
You can try this one. i have tested this in python 2.7.13 and it working correctly.
from Tkinter import *
root = Tk()
root.title("test window")
root.geometry('400x220+500+250')
root.configure(background="dark gray")
def submit(*args):
def on_closing(*args):
popup_root_window.destroy()
root.deiconify()
root.iconify()
popup_root_window = Toplevel()
popup_root_window.geometry('300x50+550+300')
popup_root_window.resizable(width=False, height=False)
popup_root_window.focus_force()
popup_root_window.grab_set()
popup_root_window_label = Label(popup_root_window, text="new window open successfully.")
popup_root_window_label.pack(anchor=CENTER, padx=10, pady=20)
popup_root_window.protocol("WM_DELETE_WINDOW", on_closing)
frame = Frame(root, bd=4, relief="raise", height=100, width=250)
frame.pack(fill="both", padx=70, pady=35)
frame.pack_propagate(0)
submit_button = Button(frame, text="Submit", command=submit, width=10)
submit_button.grid(row=0, column=0)
cancel_button = Button(frame, text="Cancel", width=10)
cancel_button.grid(row=0, column=1)
root.mainloop()