Как управлять многопоточностью приложений Python Tkinter - PullRequest
0 голосов
/ 08 ноября 2018

Я разрабатываю приложение Tkinter с Python. У меня есть две фоновые операции и одна операция с требованием пользователя. Вот мой пример кода:

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

Поэтому, когда пользователь нажимает «начать запись», он запускает 2 фоновые операции. Они должны работать в качестве фона. Затем, когда пользователь нажмет кнопку «летать», операция будет выполнена. Чтобы не блокировать мой основной интерфейс, я поместил их в отдельные потоки.

На самом деле все мои операции работают правильно. Я положил time.sleep для воспроизведения моей операции полета; но когда он работает, он блокирует весь мой, даже если он работает в отдельном потоке.

Не могли бы вы сказать мне, почему я вижу это? Верна ли моя интерпретация в отношении многопоточности в Pyhton tkinter? С наилучшими пожеланиями

1 Ответ

0 голосов
/ 08 ноября 2018

Посмотрите на эту строку кода:

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

Приведенный выше код работает точно так же, как и этот код;

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

Видишь проблему? Вы вызываете свою функцию вне потока. Поскольку static_sim() имеет бесконечный цикл, он никогда не возвращается.

Когда вы устанавливаете цель на Thread, она должна быть вызываемой . Измените код на это (обратите внимание на отсутствие трейлинга ()):

self.thread3 = Thread(target=self.static_sim).start()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...