Reputation: 129
I'm making a small program for calculating weighted grades for college classes. Mostly just doing it to experiment with python tkinter. On the one and only window I have four entries, along with four labels, and four buttons. 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. 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. Its strange, because if I click off of the tkinter window putting focus somewhere else before clicking the button, it doesn't usually hang. But if I go straight from using the four entries to clicking the button, then it usually does hang. 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.
It is the generate_report_btn
command defined in view.py
that is hanging. The function that it calls is generate_report
inside command.py
I structured my code similarly to instructions that I found in a Medium post here.
What am I doing wrong?
Here is my code:
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()
Upvotes: 0
Views: 189
Reputation: 129
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. I took out those print statements, and focused on just updating the GUI, and I haven't encountered the issue since. 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.
Upvotes: 0
Reputation: 123541
tkinter
doesn't support multithreading, in the sense that all interactions with it and associated widgets (i.e. the GUI) must occur within the same thread.
Upvotes: 1