繁体   English   中英

tkinter 程序挂在按钮点击

[英]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 帖子中找到的说明。

我究竟做错了什么?

这是我的代码:

model.py

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

视图.py

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

controller.py

# (...)

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM