[英]tkinter program hanging on button click
我正在制作一个小程序来计算大学课程的加权成绩。 主要是为了试验 python tkinter。 在唯一的 window 上,我有四个条目,以及四个标签和四个按钮。 这些用于分别获取加权部分的数量、加权部分的名称、权重和获得的分数。 底部还有第五个按钮用于计算成绩。
我遇到了一个问题,即多次按下最后一个按钮,在调用关联的事件处理程序之前会有 2 或 3 秒的延迟。 我尝试了几种不同的方式来构建程序,并不断遇到同样的问题。 现在我已经让 tkinter 主循环在它自己的线程上运行,并且在另一个线程上运行所有事件处理。 这很奇怪,因为如果我在单击按钮之前单击 tkinter window 将焦点放在其他位置,它通常不会挂起。 但是如果我 go 直接从使用四个条目到单击按钮,那么它通常会挂起。 如果我完全忽略所有条目,只需单击底部按钮,就永远不会挂起。 具体来说,当我单击按钮时,直到 2 或 3 秒后按钮的回调才开始执行。
挂起的是view.py
中定义的generate_report_btn
命令。 它调用的 function 是command.py
中的generate_report
我的代码结构类似于我在此处的 Medium 帖子中找到的说明。
我究竟做错了什么?
这是我的代码:
if __name__ == "__main__":
root = tk.Tk()
q = Queue()
view_ref = view(root, q)
model = SimpleNamespace(
names_count=0,
weights_count=0,
points_count=0,
number_of_sections=0,
sections={},
)
t = Thread(target=controller, args=(view_ref, model, q,))
t.daemon = True
t.start()
tk.mainloop()
def view(root, q):
root.minsize(900, 700)
root.grid_rowconfigure(0, weight=1)
root.grid_rowconfigure(1, weight=1, minsize=75)
root.grid_columnconfigure(0, weight=1, minsize=400)
root.grid_columnconfigure(1, weight=1)
# Define main window widgets
main_frame = ttk.Frame(root, padding="8 8 8 200")
# (...)
# Generate Report widgets
generate_report_frame = ttk.Frame(root)
generate_report_frame.grid_columnconfigure(0, weight=1)
generate_report_frame.grid_rowconfigure(0, weight=1)
generate_report_btn = ttk.Button(
generate_report_frame,
text="Generate Report",
command=lambda: q.put(controller.Messages.GENERATE_REPORT),
)
# Grid main_frame
main_frame.grid(row=0, column=0, sticky="nsew")
# (...)
# Grid generate report widgets
generate_report_frame.grid(row=1, column=0, sticky="nsew")
generate_report_btn.grid(row=0, column=0, pady=20, sticky="s")
# (...)
return SimpleNamespace(
lbl2_var=lbl2_var,
lbl3_var=lbl3_var,
lbl4_var=lbl4_var,
entry1_var=entry1_var,
entry2_var=entry2_var,
entry3_var=entry3_var,
entry4_var=entry4_var,
btn1=btn1,
entry1=entry1,
btn3=btn3,
entry3=entry3,
btn4=btn4,
entry4=entry4,
btn2=btn2,
entry2=entry2,
)
# (...)
def generate_report():
print("generate_report")
def controller(view_ref, model, q):
while True:
msg = q.get()
if msg == Messages.GET_NUMBER_OF_SECTIONS:
# (...)
elif msg == Messages.GET_SECTION_NAME:
# (...)
elif msg == Messages.GET_SECTION_WEIGHT:
# (...)
elif msg == Messages.GET_SECTION_POINTS:
# (...)
elif msg == Messages.GENERATE_REPORT:
generate_report()
tkinter
不支持多线程,因为与它和相关小部件(即 GUI)的所有交互都必须发生在同一个线程中。
我认为问题与打印到控制台有关。 我在 function 中使用了与滞后相关的打印语句,用于调试目的。 我拿出了那些打印语句,专注于更新 GUI,从那以后我就没有遇到过这个问题。 希望就是这样。
只是想发布此内容以进行澄清,以防将来遇到类似问题的人遇到此线程。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.