Aybars
Aybars

Reputation: 383

How to manage Python Tkinter app multithreading

I am developing a Tkinter app with Python. I have a two background operations and one operation with user demand. Here is my sample code:

from threading import Thread
import tkinter as tk
import time


class Controller(object):
    def __init__(self, master):
        self.master = master
        self.btn1 = tk.Button(self.master, text="Start Recording", width=16, height=5, command=lambda: self.start_background_opt())
        self.btn1.grid(row=2, column=0)
        self.btn3 = tk.Button(self.master, text="Fly", width=16, height=5, command=lambda: self.fly_button())
        self.btn3.grid(row=3, column=0)
        self.entry = tk.Entry(self.master)
        self.entry.grid(row=4, column=0)
        self.connect_button_clicked = False
        self.thread1 = None
        self.thread2 = None
        self.thread3 = None
        self.flight_completed = False

    def background_opt1(self):

        while True:
            if self.connect_button_clicked:
                print("Battery Fetching")
            else:
                return

    def background_opt2(self):
        while True:
            if self.connect_button_clicked:
                print("Signal Fetching")
            else:
                return

    def start_background_opt(self):
        if not self.connect_button_clicked:
            self.connect_button_clicked = True
            self.thread1 = Thread(target=self.background_opt1).start()
            self.thread2 = Thread(target=self.background_opt2).start()
        else:
            self.connect_button_clicked = False
            self.thread1 = None
            self.thread2 = None

    def flight_operation_controller(self):
        if self.flight_completed:
            self.thread3 = None

    def fly_button(self):
        self.flight_completed = False
        self.thread3 = Thread(target=self.static_sim()).start()

    def static_sim(self):
        while True:
            if not self.flight_completed:
                for _ in range(100):
                    print('Simulating')
                    time.sleep(0.1)
                print("Simulation completed")
                self.flight_completed = True
            else:
                return


if __name__ == '__main__':
    root = tk.Tk()
    # Set the window size
    root.geometry("900x600+0+0")
    control = Controller(root)
    root.mainloop()

So when user click to "start recording", it starts 2 background operations. They should run as a background. Then when user click to "fly" button, fly operation should be executed. In order to not blocking my main UI, I have put them in seperate threads.

Actually my all operations are working properly. I have put time.sleep for replicating my fly operation; but when it runs, it blocks my entire, even though it is running in seperate thread.

Could you please tell me why I am seeing this? Is my interpretation okey regarding the multithreading in Pyhton tkinter? Best Regards

Upvotes: 0

Views: 95

Answers (1)

Bryan Oakley
Bryan Oakley

Reputation: 386210

Take a look at this line of code:

self.thread3 = Thread(target=self.static_sim()).start()

The above code works exactly the same way as this code;

result = self.static_sim()
self.thread3 = Thread(target=result).start()

See the problem? You are calling your function outside of the thread. Because static_sim() has an infinite loop, it never returns.

When you set the target for Thread, it must be a callable. Change the code to this (note the lack of trailing ()):

self.thread3 = Thread(target=self.static_sim).start()

Upvotes: 1

Related Questions