Python Tkinter 程序在单击按钮后退出

问题描述 投票:0回答:1

我正在做一个关于机票预订系统的项目。我使用 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()
python tkinter button
1个回答
0
投票

说明

当你这样做时

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()

单根窗口

在这种方法中,我们管理单个窗口的内容。 您可以根据用户操作简单地重绘小部件。

有一些优势适用于您的情况:

  • 您只能定义一次窗口参数(几何形状、调整大小)。
  • 您可以为所有 ttk 小部件创建一个样式对象。
  • 您只能为所有视图定义一次公共元素,例如标题。

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)
© www.soinside.com 2019 - 2024. All rights reserved.