我正在做一个关于机票预订系统的项目。我使用 Tkinter 创建了登录页面和注册页面。我在登录页面创建了一个按钮以转到注册页面,反之亦然。问题是,当我单击登录页面中的“注册”按钮进行注册,然后单击注册页面上的“返回登录”按钮并再次单击登录中的“注册”时,程序退出。
这是登录页面
import tkinter
from tkinter import *
from tkinter import messagebox
from tkinter.messagebox import showinfo
import mysql.connector
win=Tk()
win.title("AirWaves")
win.geometry('1366x768')
win.geometry("+100+50")
win.configure(bg="#fff")
win.resizable(False,False)
def clear():
uentry.delete(0, END)
pentry.delete(0, END)
def login():
db=mysql.connector.connect(host="localhost", database='jagran', user='root', password='1074')
cur=db.cursor()
cur.execute("select * from passengers where username = (%s) and password = (%s)", (uentry.get(),pentry.get()))
if (cur.fetchone()):
messagebox.showinfo("✅", "Login Success!!!")
win.destroy()
import app
else:
messagebox.showerror("Login Failed ❌", "The username or password you have entered is incorrect. Please try again.")
def signup():
win.destroy()
import signup
img = PhotoImage(file="airplane aesthetics.png", master=win)
Label(win,image=img,bg='white', anchor="nw").place(x=-2,y=-2)
h1 = Label(win , text = "AirWaves" , font = 'Perpetua 80 bold', bg="#fff")
h1.place(x=770 , y=60)
h2 = Label(win , text = "Airline Reservation System" , font = 'Perpetua 30 bold', bg="#fff")
h2.place(x=755 , y=160)
uname = Label(win , text = "Username" , font = 'Perpetua 25 bold', bg="#fff")
uname.place(x=755 , y=300)
pswrd = Label(win , text = "Password" , font = 'Perpetua 25 bold', bg="#fff")
pswrd.place(x=755 , y=350)
h3 = Label(win , text = "Dont't have an Account?" , font = 'Perpetua 25 bold', bg="#fff")
h3.place(x=800 , y=550)
username = StringVar()
password = StringVar()
uentry = Entry(win, font = 'Perpetua 25 bold', bg="#fff", textvariable=username)
uentry.place(x=920, y=300)
pentry = Entry(win, font = 'Perpetua 25 bold', bg="#fff", textvariable=password)
pentry.place(x=920, y=350)
b1 = Button(win, text="Clear", width=7, font='Carrier 15', command=clear)
b1.place(x=920,y=410)
b2 = Button(win, text="Login", width=7, font='Carrier 15', command=login)
b2.place(x=1135,y=410)
b3 = Button(win, text="Signup", width=7, font='Carrier 15', command=signup)
b3.place(x=920,y=620)
win.mainloop()
这是注册页面
from tkinter import *
from tkinter import messagebox
from tkinter.messagebox import showinfo
from tkinter import ttk
import mysql.connector
win2=Tk()
win2.title("AirWaves")
win2.geometry('1366x768')
win2.geometry("+100+50")
win2.configure(bg="#fff")
win2.resizable(False, False)
def clear():
fname.delete(0, END)
lname.delete(0, END)
dob.delete(0, END)
pportno.delete(0, END)
phone.delete(0, END)
email.delete(0, END)
username.delete(0, END)
password.delete(0, END)
veripass.delete(0, END)
def login():
win2.destroy()
import login
def signup():
fn = fname.get()
ln = lname.get()
gen = gender.get()
age = dob.get()
ppno = pportno.get()
em = email.get()
phn = phone.get()
uname= username.get()
passwrd = password.get()
vp = veripass.get()
finalpass = ''
if (vp in passwrd):
finalpass = vp
else:
messagebox.showerror('Error', 'Password does Not Match')
tu = (fn, ln, gen, age, ppno, em, phn, uname, finalpass)
conn = mysql.connector.connect(host='localhost', user='root', password='1074', database='jagran')
cur = conn.cursor()
query = "insert into passengers values(%s, %s , %s, %s , %s , %s , %s, %s, %s)"
cur.execute(query, tu)
conn.commit()
messagebox.showinfo('SignUp Success', 'Account Created')
img = PhotoImage(file="signupplane.png", master=win2)
Label(win2, image=img, bg='white', anchor="nw").place(x=420, y=575)
h1 = Label(win2, text ="AirWaves", font ='Perpetua 35 bold', bg="#fff")
h1.place(x=575 , y=5)
h2 = Label(win2, text ="Airline Reservation System", font ='Perpetua 20 bold', bg="#fff")
h2.place(x=530 , y=50)
#Label names
fname = Label(win2, text ="First Name", font ='Perpetua 25 bold', bg="#fff")
fname.place(x=50 , y=140)
lname = Label(win2, text ="Last Name", font ='Perpetua 25 bold', bg="#fff")
lname.place(x=50 , y=220)
gender = Label(win2, text ="Gender", font ='Perpetua 25 bold', bg="#fff")
gender.place(x=50 , y=300)
dob = Label(win2, text ="D.O.B", font ='Perpetua 25 bold', bg="#fff")
dob.place(x=50 , y=380)
pportno = Label(win2, text ="Passport No.", font ='Perpetua 25 bold', bg="#fff")
pportno.place(x=50 , y=460)
phone = Label(win2, text ="Phone", font ='Perpetua 25 bold', bg="#fff")
phone.place(x=780 , y=140)
email = Label(win2, text ="Email", font ='Perpetua 25 bold', bg="#fff")
email.place(x=780 , y=220)
username = Label(win2, text ="Username", font ='Perpetua 25 bold', bg="#fff")
username.place(x=780 , y=300)
password = Label(win2, text ="Password", font ='Perpetua 25 bold', bg="#fff")
password.place(x=780 , y=380)
veripass = Label(win2, text ="Verify Password", font ='Perpetua 25 bold', bg="#fff")
veripass.place(x=780 , y=460)
fname = StringVar()
lname = StringVar()
gender = StringVar()
dob = StringVar()
pportno = StringVar()
phone = StringVar()
email = StringVar()
username = StringVar()
password = StringVar()
#Label name entry
fname = Entry(win2, font ='Perpetua 20 bold', bg="#fff", textvariable=fname)
fname.place(x=250, y=140)
lname = Entry(win2, font ='Perpetua 20 bold', bg="#fff", textvariable=lname)
lname.place(x=250, y=220)
'''gender = Entry(win3, font ='Perpetua 20 bold', bg="#fff", textvariable=gender)
gender.place(x=250, y=300)'''
s=ttk.Style()
s.configure('bg.TRadiobutton', background="#fff", font ='Perpetua 20 bold')
genderm = ttk.Radiobutton(win2, text='Male', value="Male", variable=gender, style='bg.TRadiobutton')
genderm.place(x= 250 , y= 280)
genderf = ttk.Radiobutton(win2, text='Female', value="Female", variable=gender, style='bg.TRadiobutton')
genderf.place(x= 250 , y= 330)
dob = Entry(win2, font ='Perpetua 20 bold', bg="#fff", textvariable=dob)
dob.place(x=250, y=380)
pportno = Entry(win2, font ='Perpetua 20 bold', bg="#fff", textvariable=pportno)
pportno.place(x=250, y=460)
phone = Entry(win2, font ='Perpetua 20 bold', bg="#fff", textvariable=phone)
phone.place(x=1050, y=140)
email = Entry(win2, font ='Perpetua 20 bold', bg="#fff", textvariable=email)
email.place(x=1050, y=220)
username = Entry(win2, font ='Perpetua 20 bold', bg="#fff", textvariable=username)
username.place(x=1050, y=300)
password = Entry(win2, font ='Perpetua 20 bold', bg="#fff", textvariable=password)
password.place(x=1050, y=380)
veripass = Entry(win2, font ='Perpetua 20 bold', bg="#fff", textvariable=veripass)
veripass.place(x=1050, y=460)
#buttons
b1 = Button(win2, text="Clear", width=10, font='Carrier 15', command=clear)
b1.place(x=410,y=525)
b2 = Button(win2, text="Signup", width=10, font='Carrier 15', command=signup)
b2.place(x=600,y=525)
b3 = Button(win2, text="Back to Login", width=13, font='Carrier 15', command=login)
b3.place(x=790,y=525)
win2.mainloop()
当你这样做时
import filename
Python 会找到该文件并创建一个名为 module
的特殊对象。
导入过程涉及加载模块,并且作为加载的一部分,模块被执行(因此出现 tkinter 窗口)。
我假设您期望导入文件名时,其工作方式与将文件作为脚本运行时相同。 在导入的情况下,代码将在第一次导入期间执行一次。 加载后,将在 sys.modules 中找到对该模块的引用。 因此,当您第二次
import filename
时,代码不会执行。
假设我们有两个文件。
login.py
import tkinter as tk
import sys
# this line will be executed in any case
print("login in sys.modules.keys()", "login" in sys.modules.keys())
# this line will only be executed if we call the "open_signup()" function, just like the "print()" function call above
def open_signup():
login_root.destroy()
print("import signup")
import signup
# this line will be executed in any case
login_root = tk.Tk()
if __name__ == "__main__": # case: python login.py
print("Start program")
print("code is executed: login_root created\n")
else: # case: import login
print("module is loaded, code is executed: login_root created\n")
# these lines will be executed in any case
login_root.title("Login")
l = tk.Label(login_root, text="Login")
l.pack()
b = tk.Button(login_root, text="Go to Sign Up", command=open_signup)
b.pack()
login_root.mainloop() # mainloops are blocking normal program execution
# this will be printed after all windows are closed/destroyed
print("after login_root mainloop")
signup.py
import tkinter as tk
import sys
print("signup in sys.modules.keys()", "signup" in sys.modules.keys())
def open_login():
signup_root.destroy()
print("import login")
import login
signup_root = tk.Tk()
print("module is loaded, code is executed: signup_root created\n")
signup_root.title("Sign Up")
l = tk.Label(signup_root, text="Sign Up")
l.pack()
b = tk.Button(signup_root, text="Go to Login", command=open_login)
b.pack()
signup_root.mainloop()
print("after signup_root mainloop")
使用
python login.py
启动程序。在窗口之间切换,直到程序完成。
输出
login in sys.modules.keys() False
Start program
code is executed: login_root created
import signup
signup in sys.modules.keys() True
module is loaded, code is executed: signup_root created
import login
login in sys.modules.keys() True
module is loaded, code is executed: login_root created
import signup
after login_root mainloop
after signup_root mainloop
after login_root mainloop
我们可以看到,当所有模块都导入一次并且所有 GUI 窗口都被销毁时,程序就会退出。
import signup
第二次没有效果。
在大多数情况下,一个根窗口就足够了。 但如果您确实需要多个 Tk 窗口用于登录、注册和应用程序,这是可能的。 您需要将窗口重写为类或将它们包装在函数中。因此,它们可以多次导入和使用。
从
python main.py
开始。
main.py
import login
def main(): # entry-point
print("Start program")
login.create_login()
print("End")
if __name__ == "__main__":
main()
app.py
import tkinter as tk
import login
def logout(root):
root.destroy()
login.create_login()
def create_app(user):
root = tk.Tk()
root.title("Main")
root.geometry("+100+50")
l = tk.Label(root, text="Main Window")
l.pack()
l1 = tk.Label(root, text=user)
l1.pack()
b = tk.Button(root, text="Log Out", command=lambda: logout(root))
b.pack()
root.mainloop()
login.py
import tkinter as tk
import signup
import app
def login_user(login_root, user):
login_root.destroy()
app.create_app(user)
def open_signup(login_root):
login_root.destroy()
signup.create_signup()
def create_login():
login_root = tk.Tk()
login_root.title("Login")
login_root.geometry("+100+50")
l = tk.Label(login_root, text="Login")
l.pack()
b = tk.Button(login_root, text="Go to Sign Up", command=lambda: open_signup(login_root))
b.pack()
b1 = tk.Button(login_root, text="Submit Form", command=lambda: login_user(login_root, "Test User"))
b1.pack()
img = tk.PhotoImage(file=r"image.png", master=login_root)
img_label = tk.Label(login_root, image=img)
img_label.pack()
img_label.image = img # additional reference to image created in function
login_root.mainloop()
signup.py
import tkinter as tk
import login
import app
def signup_user(signup_root, user):
signup_root.destroy()
app.create_app(user)
def open_login(signup_root):
signup_root.destroy()
login.create_login()
def create_signup():
signup_root = tk.Tk()
signup_root.title("Sign Up")
signup_root.geometry("+100+50")
l = tk.Label(signup_root, text="Sign Up")
l.pack()
b = tk.Button(signup_root, text="Go to Login", command=lambda: open_login(signup_root))
b.pack()
b1 = tk.Button(signup_root, text="Submit Form", command=lambda: signup_user(signup_root, "Test User"))
b1.pack()
img = tk.PhotoImage(file=r"image.png", master=signup_root)
img_label = tk.Label(signup_root, image=img)
img_label.pack()
img_label.image = img # additional reference to image created in function
signup_root.mainloop()
在这种方法中,我们管理单个窗口的内容。 您可以根据用户操作简单地重绘小部件。
有一些优势适用于您的情况:
从
python main.py
开始。
main.py
import tkinter as tk
import tkinter.ttk as ttk
import login_view
def main(): # entry-point
win = tk.Tk()
win.title("AirWaves")
win.configure(bg="#fff")
win.geometry("+100+50")
style = ttk.Style(win)
style.configure('bg.TRadiobutton', background="#fff")
style.configure('header.TLabel', background="#fff", anchor="center")
h1 = ttk.Label(win, text="AirWaves", style='header.TLabel')
h1.pack(fill="both")
h2 = ttk.Label(win, text="Airline Reservation System", style='header.TLabel')
h2.pack(fill="both")
main_frame = tk.Frame(win, bg="#fff")
main_frame.pack(fill="both", expand=True)
# default view
login_view.create_login_view(main_frame)
win.mainloop()
if __name__ == "__main__":
main()
main_view.py
import tkinter as tk
import login_view
def create_main_view(parent, username):
for i in parent.winfo_children():
i.destroy()
uname = tk.Label(parent, text=username)
uname.grid(row=0, column=0)
b = tk.Button(parent, text="Log Out", command=lambda: login_view.create_login_view(parent))
b.grid(row=1, column=0)
login_view.py
import tkinter as tk
from tkinter import messagebox
import signup_view
import main_view
def login_user(parent, username, password):
# check username and password in db
if username.get() and password.get():
main_view.create_main_view(parent, username.get())
else:
messagebox.showerror("Login Failed ❌",
"The username or password you have entered is incorrect. Please try again.")
def create_login_view(parent):
for i in parent.winfo_children():
i.destroy()
def clear_login_entries():
uentry.delete(0, tk.END)
pentry.delete(0, tk.END)
img = tk.PhotoImage(file=r"image.png", master=parent.master)
img_label = tk.Label(parent, image=img)
img_label.grid(row=0, column=0, rowspan=4)
img_label.image = img # additional reference to image created in function
uname = tk.Label(parent, text="Username")
uname.grid(row=0, column=1)
pswrd = tk.Label(parent, text="Password")
pswrd.grid(row=1, column=1)
uentry = tk.Entry(parent)
uentry.grid(row=0, column=2)
pentry = tk.Entry(parent)
pentry.grid(row=1, column=2)
b = tk.Button(parent, text="Login", command=lambda: login_user(parent, uentry, pentry))
b.grid(row=2, column=2)
b2 = tk.Button(parent, text="Go to Sign Up", command=lambda: signup_view.create_signup_view(parent))
b2.grid(row=3, column=2)
b3 = tk.Button(parent, text="Clear", command=clear_login_entries)
b3.grid(row=4, column=2)
signup_view.py
import tkinter as tk
import tkinter.ttk as ttk
from tkinter import messagebox
import login_view
import main_view
def signup_user(parent, username, password, veripass):
# check values and save to the database
if all([username.get(), password.get(), veripass.get()]):
main_view.create_main_view(parent, username.get())
else:
messagebox.showerror('Error', 'Something went wrong.')
def create_signup_view(parent):
for i in parent.winfo_children():
i.destroy()
def clear_signup_entries():
uentry.delete(0, tk.END)
pentry.delete(0, tk.END)
vpentry.delete(0, tk.END)
gender.set("")
uname = tk.Label(parent, text="Username" )
uname.grid(row=0, column=0)
pswrd = tk.Label(parent, text="Password")
pswrd.grid(row=1, column=0)
veripass = tk.Label(parent, text="Verify Password")
veripass.grid(row=2, column=0)
uentry = tk.Entry(parent)
uentry.grid(row=0, column=1)
pentry = tk.Entry(parent)
pentry.grid(row=1, column=1)
vpentry = tk.Entry(parent)
vpentry.grid(row=2, column=1)
gender = tk.StringVar()
genderm = ttk.Radiobutton(parent, text='Male', value="Male", variable=gender, style='bg.TRadiobutton')
genderm.grid(row=3, column=1)
genderf = ttk.Radiobutton(parent, text='Female', value="Female", variable=gender, style='bg.TRadiobutton')
genderf.grid(row=4, column=1)
b = tk.Button(parent, text="Sign Up", command=lambda: signup_user(parent, uentry, pentry, vpentry))
b.grid(row=5, column=1)
b2 = tk.Button(parent, text="Go to Login", command=lambda: login_view.create_login_view(parent))
b2.grid(row=6, column=1)
b3 = tk.Button(parent, text="Clear", command=clear_signup_entries)
b3.grid(row=7, column=1)