我正在编写一个GUI来与数据库连接。 GUI要求用户登录。如果尝试连接到数据库失败,我将创建一个错误对话框。我一直在看任务管理器,每次弹出一个错误对话框时,程序使用的内存会跳转一点。我想我可能对tkinter有误解。任何帮助表示赞赏。所有相关代码如下。我想我已经将漏洞钉在了except
LogInWindow.enter_cb()
内。我知道这个类没有正确缩进。无法正确格式化文本。
main函数在mainloop
上启动LogInWindow。
from tkinter import *
from tkinter import ttk
class ErrorWindow(Tk):
"""Window for displaying database log in errors"""
def __init__(self, exception):
Tk.__init__(self)
self.title('MySQL Error')
self.resizable(False, False)
error = Text(self, height=2, wrap=WORD, relief=FLAT)
error.insert(END, 'MySQL {!r}'.format(exception))
error.tag_configure("center", justify='center')
error.tag_add("center", 1.0, "end")
error.config(state=DISABLED)
error.configure(bg=self.cget('bg'))
error.pack(padx=5, pady=(5, 0))
ok = ttk.Button(self, text='OK', command=self._quit)
ok.bind('<Return>', self._quit)
ok.pack(padx=5, pady=5)
# root.grab_set()
ok.focus_set()
def _quit(self, *args):
self.destroy()
class LogInWindow(Tk):
"""Window for getting the user's database credentials"""
connection = None
def __init__(self):
Tk.__init__(self)
self.title('Enter Credentials')
self.resizable(False, False)
main_frame = ttk.Frame(self)
main_frame.pack(fill=BOTH, expand=True, padx=20, pady=5)
entry_frame = ttk.Frame(main_frame)
entry_frame.pack()
u_label = ttk.Label(entry_frame, text='Username')
p_label = ttk.Label(entry_frame, text='Password')
self.usern = ttk.Entry(entry_frame)
self.passw = ttk.Entry(entry_frame, show='*')
self.usern.bind('<Return>', self.enter_cb)
self.passw.bind('<Return>', self.enter_cb)
u_label.grid(row=0, column=0, padx=15, pady=5)
self.usern.grid(row=0, column=1, padx=(0, 15), pady=5)
p_label.grid(row=1, column=0, padx=15, pady=5)
self.passw.grid(row=1, column=1, padx=(0, 15), pady=5)
button_frame = ttk.Frame(self)
button_frame.pack()
enter = ttk.Button(button_frame, text='Enter', command=self.enter_cb)
cancel = ttk.Button(button_frame, text='Cancel', command=self.cancel_cb)
enter.bind('<Return>', self.enter_cb)
cancel.bind('<Return>', self.cancel_cb)
enter.pack(side=LEFT, padx=10, pady=10)
cancel.pack(side=LEFT, padx=10, pady=10)
self.usern.focus_set()
def enter_cb(self, *args):
"""Enter callback for either creating a database connection or spewing an error dialog"""
try:
# make a conection with the database
import pymysql.cursors
self.connection = pymysql.connect(host='localhost',
user=self.usern.get(),
password=self.passw.get(),
db='databasename',
charset='utf8mb4',
cursorclass=pymysql.cursors.DictCursor)
self.destroy()
except pymysql.err.OperationalError as e:
# create an error dialog
error = ErrorWindow(e)
center(error)
error.mainloop()
# del(error)
def cancel_cb(self, *args):
"""Cancel callback for destroying the window"""
self.destroy()
答案 0 :(得分:2)
问题的至少一部分是你不应该只有一个Tk
个实例。如果要创建对话框,则它必须是Toplevel
的子类,而不是Tk
。
设计良好的tkinter程序应该只显式创建一次根窗口(Tk()
),然后只调用mainloop
一次。