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

密码管理器重构后调用self.bell()出现RecursionError问题求助

问题分析与解决方案

你的RecursionError根源在于**createNewPassword类的继承和初始化逻辑完全错误**,导致调用self.bell()时触发了无限递归。

核心问题拆解

你让createNewPassword继承了tkinter.Tk(主窗口类),但在__init__里却没有正确初始化Tk实例,反而创建了一个Toplevel弹窗。这就导致createNewPassword的实例并不是一个有效的Tk对象,当你调用self.bell()时,内部尝试访问self.tk属性,而这个属性的 getter 因为对象结构混乱陷入了无限递归调用。

另外主文件里还有个小问题:按钮的command直接写了类名createNewPassword,这会直接调用类的构造函数,但没有传入必要的上下文,也不符合GUI弹窗的使用逻辑。

修正步骤

1. 重构createNewPassword类

把它改成继承Toplevel(弹窗类),而不是Tk,并正确初始化父窗口:

from tkinter import *
from tkinter import ttk
import tkinter as tk
import sqlite3  # 别忘了导入sqlite3!
from class_makePassword import *

class createNewPassword(tk.Toplevel):
    def __init__(self, master):
        super().__init__(master)  # 正确初始化Toplevel,传入主窗口作为父级
        self.title('Create a password')
        # 把数据库连接存在实例自身,而不是绑定到Toplevel类上(这是不良实践)
        self.connection = sqlite3.connect("mdp - Copy.db")
        self.cursor = self.connection.cursor()
        # 你的其他tkinter组件和逻辑...

    def savePassword(self, condition):
        if condition:
            # 数据库写入逻辑
            pass
        else:
            print("problem")
            self.bell()  # 现在可以正常调用了

2. 修正主文件的按钮命令

主窗口的按钮需要创建createNewPassword的实例,而不是直接调用类名,用lambda来传递主窗口作为父级:

from tkinter import *
from tkinter import ttk
from class_createNewPassword import createNewPassword
from class_searchDatabase import *
from class_updateDatabase import *

class display(Tk):
    def __init__(self, master=None):
        super().__init__(master)
        self.title('Password Manager')
        
        buttonCreate = ttk.Button(self, text='Create a new password', 
                                 command=lambda: createNewPassword(self))  # 传入主窗口作为父级
        buttonCreate.grid(column=0, row=0)
        
        buttonSearch = ttk.Button(self, text='Search the database', 
                                 command=lambda: SearchDatabase(self))  # 同理修改其他弹窗类
        buttonSearch.grid(column=1, row=2)
        
        buttonUpdate = ttk.Button(self, text='Update the database', 
                                 command=lambda: UpdateDatabase(self))
        buttonUpdate.grid(column=2, row=4)

if __name__ == "__main__":
    app = display()
    app.mainloop()

额外建议

  • 不要把数据库连接绑定到Toplevel类上(Toplevel.connection),这会导致所有弹窗共享同一个连接,容易引发并发问题,应该把连接存在每个实例内部。
  • 所有弹窗类(SearchDatabase、UpdateDatabase)都应该遵循同样的逻辑:继承Toplevel,并接收主窗口作为父参数初始化。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 09:20:53