Использование Python Tk в качестве внешнего интерфейса для многопоточного кода - PullRequest
1 голос
/ 26 июля 2011

Я знаю, что у интерфейса Python Tk есть некоторые проблемы при использовании потоков, и я уже столкнулся с проблемами с ним. Моя идея теперь состоит в том, чтобы использовать Queue.Queue для какой-либо передачи событий в основной цикл Tk, аналогично следующему примеру.

from Tkinter import *
import Queue
import time

# this queue will be filled by other threads
queue = Queue.Queue()
queue.put("Helloooo!")
queue.put("hi there, everyone!")

class Application(Frame):
    def update(self):
        while True:
            try:
                text = queue.get(False)
                self.hi_there["text"] = text
                time.sleep(3)
            except Queue.Empty:
                self.quit()

    def create_widgets(self):
        self.hi_there = Label(self)
        self.hi_there["text"] = "Hello"

        self.hi_there.pack({"side": "left"})

    def __init__(self, master=None):
        Frame.__init__(self, master)
        self.pack()
        self.create_widgets()

root = Tk()
app = Application(master=root)
app.update()
app.mainloop()

Конечно, я не должен сам вызывать update (это выполнит все до того, как пользовательский интерфейс даже будет показан), но мне нужен Tk, чтобы обработать это во время основного цикла.

Есть ли надежный способ сделать это с Tk, который не сломается при определенных обстоятельствах? Или я должен просто прибегнуть к Qt для этого?

1 Ответ

3 голосов
/ 26 июля 2011

Как общее практическое правило, приложение с графическим интерфейсом никогда и никогда не должно вызывать sleep, никогда не должно иметь бесконечный цикл (за исключением цикла обработки событий), и вы никогда не должны вызывать update.Единственное исключение из того, что вы никогда не вызываете update, - это нормально, только если вы действительно понимаете, почему не следует этого делать.

Создайте метод, который выполняет две вещи: проверяет очередь, а затем использует «после», чтобы вызвать себя через какой-то небольшой промежуток времени.Затем вызовите этот метод один раз в начале вашей программы, непосредственно перед началом цикла обработки событий, после того, как произойдет вся остальная инициализация.таймер с использованием tkinter?

...