简体   繁体   English

tkinter 程序挂在按钮点击

[英]tkinter program hanging on button click

I'm making a small program for calculating weighted grades for college classes.我正在制作一个小程序来计算大学课程的加权成绩。 Mostly just doing it to experiment with python tkinter.主要是为了试验 python tkinter。 On the one and only window I have four entries, along with four labels, and four buttons.在唯一的 window 上,我有四个条目,以及四个标签和四个按钮。 These are for getting the number of weighted sections, the names of the weighted sections, the weights, and the points earned, respectively.这些用于分别获取加权部分的数量、加权部分的名称、权重和获得的分数。 There is also a fifth button at the bottom for calculating the grade.底部还有第五个按钮用于计算成绩。

I'm running into an issue where many times that the last button is pressed there is a 2 or 3 second delay before the associated event handler is called.我遇到了一个问题,即多次按下最后一个按钮,在调用关联的事件处理程序之前会有 2 或 3 秒的延迟。 I've tried structuring the program several different ways, and keep running into to the same issue.我尝试了几种不同的方式来构建程序,并不断遇到同样的问题。 Right now I've got the tkinter mainloop running on its own thread, and another thread where all of the event handling happens.现在我已经让 tkinter 主循环在它自己的线程上运行,并且在另一个线程上运行所有事件处理。 Its strange, because if I click off of the tkinter window putting focus somewhere else before clicking the button, it doesn't usually hang.这很奇怪,因为如果我在单击按钮之前单击 tkinter window 将焦点放在其他位置,它通常不会挂起。 But if I go straight from using the four entries to clicking the button, then it usually does hang.但是如果我 go 直接从使用四个条目到单击按钮,那么它通常会挂起。 If I completely ignore the entries all together, and just click the bottom button, there is never any hanging.如果我完全忽略所有条目,只需单击底部按钮,就永远不会挂起。 To be specific, when I click the button, it isn't until 2 or 3 seconds later that the button's callback begins executing.具体来说,当我单击按钮时,直到 2 或 3 秒后按钮的回调才开始执行。

It is the generate_report_btn command defined in view.py that is hanging.挂起的是view.py中定义的generate_report_btn命令。 The function that it calls is generate_report inside command.py它调用的 function 是command.py中的generate_report

I structured my code similarly to instructions that I found in a Medium post here .我的代码结构类似于我在此处的 Medium 帖子中找到的说明。

What am I doing wrong?我究竟做错了什么?

Here is my code:这是我的代码:

model.py 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()

view.py视图.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 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 doesn't support multithreading, in the sense that all interactions with it and associated widgets (ie the GUI) must occur within the same thread. tkinter不支持多线程,因为与它和相关小部件(即 GUI)的所有交互都必须发生同一个线程中。

I think the problem has to do with printing out to the console.我认为问题与打印到控制台有关。 I was using print statements in the function that was associated with the lagging, for debugging purposes.我在 function 中使用了与滞后相关的打印语句,用于调试目的。 I took out those print statements, and focused on just updating the GUI, and I haven't encountered the issue since.我拿出了那些打印语句,专注于更新 GUI,从那以后我就没有遇到过这个问题。 Hopefully that is it.希望就是这样。

Just wanted to post this for clarification in case someone with a similar issue comes across this thread in the future.只是想发布此内容以进行澄清,以防将来遇到类似问题的人遇到此线程。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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