Как открыть окно tk в tkinter в другом потоке (tkinter не является потокобезопасным) - PullRequest
1 голос
/ 06 мая 2020

Я хочу написать программу с использованием Tkinter GUI, которая выполняет определенную задачу в потоке. Когда во время выполнения задачи возникает ошибка, программа должна вывести окно с ошибкой, например, используя tkMessageBox. Конечно, программа вылетает, когда она должна вывести окно сообщения из нового потока, поскольку Tkinter не является потокобезопасным, но я надеюсь, что есть решение этой проблемы.

Вот простой пример не рабочий код (отредактировал):

from tkinter import *
import tkMessageBox
from threading import *
import time


class App:

    def __init__(self, master):

        frame = Frame(master)
        frame.pack()

        self.button = Button(frame, text = "Task", command = self.thread_task)
        self.button.pack(side=LEFT)

    def thread_task(self):

        thread = Thread(target = self.task)
        thread.start()

    def task(self):

        #perform task...          
        time.sleep(1) #Just as a filler in the code
        #command to open an error popup, e.g. tkMessageBox.showerror("Error", "Problem occured")

root = Tk()
app = App(root)
root.mainloop()

1 Ответ

0 голосов
/ 06 мая 2020

Вы можете использовать try-except внутри потока.

Вот пример, основанный на вашем коде (отредактированный для работы с Python 2):

from Tkinter import *
import tkMessageBox
from threading import *


class App:
    def __init__(self, master):
        frame = Frame(master)
        frame.pack()

        self.button = Button(frame, text="Task", command=self.thread_task)
        self.button.pack(side=LEFT)

    def thread_task(self):
        thread = Thread(target=self.task)
        thread.start()


    def task(self):
        try:
            time.sleep(1)
            self.button["text"] = "Started"
            self.button["state"] = "disabled"
            raise ValueError  # or anything else
        except:
            tkMessageBox.showerror("Error", "Problem occured")
        self.button["text"] = "Task"
        self.button["state"] = "normal"

if __name__ == "__main__":
    root = Tk()
    app = App(root)
    root.mainloop()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...