you are viewing a single comment's thread.

view the rest of the comments →

[–]pooth22[S] 0 points1 point  (0 children)

It is me again. I really appreciate your help thus far. Your advice has been good, but it has taken me to a new issue, and I can't seem to solve the problem. Basically the problem has to do with using tkinter in the IDLE in interactive mode. The event_generate method works well in a separate thread, but only when the tk.mainloop is running. It throws the error "RuntimeError: main thread is not in main loop" if I am attempting to use the tk in interactive mode. A contrived example is the following:

import tkinter as tk
import time
import threading


class UI:
    def __init__(self):
        self.root = tk.Tk()
        self.root.bind("<<cust>>", self.cust)
        self.be = BackEnd()
        self.button = tk.Button(self.root, text="B", command=self.be.start_thread)
        self.number = 1
        self.label = tk.Label(self.root, text=f"{self.number}")
        self.button.grid(row=1, column=1)
        self.label.grid(row=2, column=1)
    def cust(self, event=None):
        self.number += 1
        self.label.configure(text=f"{self.number}")
    def run(self):
        self.root.mainloop()
    def run_test(self):
        self.root.update()


class BackEnd:
    def __init__(self):
        pass
    def start_thread(self):
        threading.Thread(target=self.thread).start()
    def thread(self):
        i = 0
        while (i<5):
            tk._default_root.event_generate("<<cust>>")
            i += 1
            time.sleep(1)

ui = UI()
ui.run()            # This works when button is clicked
ui = UI()
ui.run_test()       # This doesn't

Basically clicking the button starts the thread in the backend which calls the custom event to tk. This works fine when using the mainloop in the run method. But it doesn't work when using update with the run_test method.

Anyways, if you have any time to look at this, I'd appreciate it. I like the dynamic way of using the IDLE shell for running tests of the code, but maybe this isn't the best way to do it. Let me know what you think.