You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python函数executelogin执行后程序无法继续运行的问题排查

问题:调用executelogin后程序后续代码无法执行

调用executelogin函数完成登录后,程序后面的代码完全不运行。以下是executelogin的代码:

def executelogin():
    global initiate_game_window
    global checker
    counter = 1
    while counter < 4:
        global login_tk, game, us1_entry, us2_entry, us1_pwd_entry, us2_pwd_entry
        login_tk = Tk(screenName="Login - RollADie")
        titlelabel = Label(text="Welcome to rollaDie", font=('Open Sans', '20'))
        titlelabel.grid(column=0, row=0, sticky=NSEW)
        sublabel = Label(text="Login Below: ", font=('Open Sans', '10'))
        sublabel.grid(column=0, row=1, sticky=NSEW)
        
        us1_label = Label(text="User 1:")
        us1_label.grid(row=2, column=0, sticky=NSEW)

        us1_entry = Entry(width=10, textvariable=us1_uname)
        us1_entry.grid(row=3, column=0, sticky=NSEW)

        us1_pwd_label = Label(text="Password:")
        us1_pwd_label.grid(row=4, column=0, sticky=NSEW)

        us1_pwd_entry = Entry(width=10, show="*", textvariable=us1_pwrd)
        us1_pwd_entry.grid(row=5, column=0, sticky=NSEW)

        us2_label = Label( text="User 2:")
        us2_label.grid(row=6, column=0, sticky=NSEW)

        us2_entry = Entry(width=10, textvariable=us2_uname)
        us2_entry.grid(row=7, column=0, sticky=NSEW)

        us2_pwd_label = Label(text="Password:")
        us2_pwd_label.grid(row=8, column=0, sticky=NSEW)

        us2_pwd_entry = Entry(width=10, show="*", textvariable=us2_pwrd)
        us2_pwd_entry.grid(row=9, column=0, sticky=NSEW)

        def get_credentials():
            global us1_entry, us2_entry, us1_pwd_entry, us2_pwd_entry, top_login
            us1_uname = us1_entry.get()
            us1_pwrd = us1_pwd_entry.get()
            us2_uname = us2_entry.get()
            us2_pwrd = us2_pwd_entry.get()
            print(us1_uname, us1_pwrd, us2_uname, us2_pwrd)
            
            global credentials
            credentials = [us1_uname, us1_pwrd, us2_uname, us2_pwrd]
            top_login.destroy()


        global top_login
        top_login = tk.Toplevel()
        top_login.geometry('1x1+0+0')
        top_login.overrideredirect(True)
        submit_button = Button(text="Submit", command=get_credentials)
        submit_button.grid(row=10, column=0, sticky=NSEW)
        top_login.wait_window(top_login)
        
        us1_auth = False
        us2_auth = False

        if login(credentials[0], credentials[1]) == True:
            us1_auth = True
        else:
            pass

        if login(credentials[2], credentials[3]) == True:
            us2_auth = True
        else:
            pass


        if us1_auth ==  True:
            if us2_auth == True:
                print("Auth POS")
                messagebox.showinfo(message="AUTHORISED")
                login_tk.destroy()
                break
            else:
                print("User 2 AUTH NEG")
                messagebox.showinfo(message="User 2 Denied")
                counter += 1
                if counter > 3:
                    messagebox.showinfo(message="MAX ATTEMPTS")
                    quit()
                continue
        else:
            print("AUTH USER 1 NEG")
            messagebox.showinfo(message="USER 1 NOT AUTHORISED")
            counter += 1
            if counter > 3:
                    messagebox.showinfo(message="MAX ATTEMPTS")
                    quit()
            continue
    login_tk.mainloop()

executelogin下方的后续代码:

top = None
top_roll2 = None
faces = {'1':'⚀', '2':'⚁', '3':'⚂', '4':'⚃', '5':'⚄', '6':'⚅'}
root = Tk(className='RollADice', screenName='RollADice')
title = Label(text='RollADice by. Amen', font=('Open Sans', '20')).grid(row=0, column=0, sticky=NSEW)
round_teller = Label(text='Currently: Round {0}'.format(roundnum))
round_teller.grid(row=1, column=0, sticky=NSEW)
dicelabel = Label(root)

问题原因与解决方法

核心问题1:多个Tk实例+主循环阻塞

Tkinter程序绝对不能创建多个Tk()实例,每个程序只能有一个主Tk对象,否则会导致事件循环冲突,程序逻辑混乱。你的代码里,executelogin创建了login_tk = Tk(),后续又创建root = Tk(),这本身就是严重错误。

另外,executelogin最后调用了login_tk.mainloop(),这个主循环会阻塞程序,直到login_tk窗口被销毁,但即使销毁后,后续创建新的Tk实例依然会引发问题。

核心问题2:不必要的wait_window与窗口销毁逻辑

你用了一个隐藏的top_login Toplevel并调用wait_window,这个逻辑可以简化,而且认证成功后销毁login_tk,但之后还调用login_tk.mainloop(),此时窗口已经不存在,无意义且可能阻塞。

修复步骤:

  1. 改用单个主Tk实例:
    先创建主窗口root,一开始隐藏,登录完成后再显示。登录窗口用Toplevel(root)创建,作为主窗口的子窗口。

  2. 移除executelogin中的login_tk.mainloop():
    整个程序只需要在最后调用root.mainloop()即可,避免多次主循环阻塞。

  3. 重构登录窗口逻辑:
    把登录窗口改成Toplevel,去掉多余的隐藏Toplevel,直接用提交按钮触发认证逻辑,认证成功后销毁登录窗口并显示主窗口。

修复后的示例代码:

import tkinter as tk
from tkinter import messagebox

def login(username, password):
    # 这里替换成你的实际认证逻辑
    return username == "user1" and password == "pass1" or username == "user2" and password == "pass2"

def executelogin(root):
    counter = 1
    while counter < 4:
        login_top = tk.Toplevel(root)
        login_top.title("Login - RollADie")
        
        tk.Label(login_top, text="Welcome to rollaDie", font=('Open Sans', '20')).grid(column=0, row=0, sticky=NSEW)
        tk.Label(login_top, text="Login Below: ", font=('Open Sans', '10')).grid(column=0, row=1, sticky=NSEW)
        
        # 用户1输入框
        tk.Label(login_top, text="User 1:").grid(row=2, column=0, sticky=NSEW)
        us1_entry = tk.Entry(login_top, width=10)
        us1_entry.grid(row=3, column=0, sticky=NSEW)
        
        tk.Label(login_top, text="Password:").grid(row=4, column=0, sticky=NSEW)
        us1_pwd_entry = tk.Entry(login_top, width=10, show="*")
        us1_pwd_entry.grid(row=5, column=0, sticky=NSEW)
        
        # 用户2输入框
        tk.Label(login_top, text="User 2:").grid(row=6, column=0, sticky=NSEW)
        us2_entry = tk.Entry(login_top, width=10)
        us2_entry.grid(row=7, column=0, sticky=NSEW)
        
        tk.Label(login_top, text="Password:").grid(row=8, column=0, sticky=NSEW)
        us2_pwd_entry = tk.Entry(login_top, width=10, show="*")
        us2_pwd_entry.grid(row=9, column=0, sticky=NSEW)
        
        credentials = []
        def get_credentials():
            nonlocal credentials
            credentials = [
                us1_entry.get(),
                us1_pwd_entry.get(),
                us2_entry.get(),
                us2_pwd_entry.get()
            ]
            login_top.destroy()
        
        tk.Button(login_top, text="Submit", command=get_credentials).grid(row=10, column=0, sticky=NSEW)
        root.wait_window(login_top)  # 等待登录窗口关闭
        
        if not credentials:
            continue
        
        us1_auth = login(credentials[0], credentials[1])
        us2_auth = login(credentials[2], credentials[3])
        
        if us1_auth and us2_auth:
            print("Auth POS")
            messagebox.showinfo(message="AUTHORISED")
            return True
        elif not us1_auth:
            print("AUTH USER 1 NEG")
            messagebox.showinfo(message="USER 1 NOT AUTHORISED")
        else:
            print("User 2 AUTH NEG")
            messagebox.showinfo(message="User 2 Denied")
        
        counter += 1
        if counter > 3:
            messagebox.showinfo(message="MAX ATTEMPTS")
            root.quit()
            return False
    return False

# 主程序开始
if __name__ == "__main__":
    top = None
    top_roll2 = None
    faces = {'1':'⚀', '2':'⚁', '3':'⚂', '4':'⚃', '5':'⚄', '6':'⚅'}
    roundnum = 1  # 假设roundnum有定义
    
    root = tk.Tk(className='RollADice', screenName='RollADice')
    root.withdraw()  # 先隐藏主窗口
    
    # 执行登录,成功后显示主窗口
    if executelogin(root):
        root.deiconify()
        tk.Label(root, text='RollADice by. Amen', font=('Open Sans', '20')).grid(row=0, column=0, sticky=NSEW)
        round_teller = tk.Label(root, text='Currently: Round {0}'.format(roundnum))
        round_teller.grid(row=1, column=0, sticky=NSEW)
        dicelabel = tk.Label(root)
        
        # 这里添加你的游戏逻辑
        
        root.mainloop()

关键改动说明:

  • 主程序只创建一个root = Tk()实例,一开始隐藏,登录成功后显示。
  • 登录窗口用Toplevel(root)创建,避免多个Tk实例冲突。
  • 用root.wait_window(login_top)等待登录窗口关闭,代替原来的隐藏Toplevel逻辑,更清晰。
  • 移除了所有全局变量的滥用,改用nonlocal和参数传递,代码更健壮。
  • 整个程序只有最后一个root.mainloop(),避免阻塞后续代码执行。

内容的提问来源于stack exchange,提问作者Amen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 19:41:06