2014-10-06 3 views
0

У меня есть графический интерфейс, который дает пользователю возможность запускать множество тестов.Получение данных из длинной функции для обновления графического интерфейса пользователя

Эти тесты выполняются в потоках, поскольку они используют MIDI-данные.

у меня есть checkQueue() функцию, которая выполняется с помощью after(), но после того, как пользователь выбирает тест, функция checkQueue() больше не вызывается, пока функция не заканчивается.

Как получить checkQueue для продолжения работы во время моей функции buttonTest(), чтобы я мог использовать данные из теста для обновления GUI?

Вот упрощенная версия моего кода:

import Tkinter as tk 
import Queue 

class Program(tk.Frame): 
    def __init__(self,parent): 
     tk.Frame.__init__(self, parent) 
     self.parent = parent 

     self.initUI() 

     self.q = Queue.Queue() 

     self.after(200, checkQueue, self.q, self) 

    def initUI(self): 
     start = tk.Button(self.parent, command=self.runTest, text="Run Test 1") 
     start.pack() 

     self.instruction = tk.Label(self.parent, text="Press Button 1") 
     self.instruction.pack() 

    def runTest(self): 
     buttonTest(self) 

def checkQueue(q,app): 
    print "Calling checkQueue" 
    while not q.empty(): 
     #HandleData (update a label/canvas etc.) 
     app.update() 
    app.after(200, checkQueue,q,app) 

def buttonTest(gui): 
    #Does lots of functions but is just a while for this example 
    x=1 
    while x==1: 
     if x == 100: 
      gui.q.put("Some Data") 



def main(): 
    root = tk.Tk() 
    root.configure(background="black") 
    app = Program(root) 

    root.mainloop() 
    root.destroy() 

if __name__ == "__main__": 
    main() 

ответ

0

Я принимаю buttonTest это функция, которая зовёт тесты, которые работают в других потоках. Несмотря на то, что фактическая работа выполняется в дочерних потоках, buttonTest все еще работает в основном потоке, а его цикл while забивает все циклы обработки основного потока. Попробуйте запустить buttonTest самостоятельно в своей собственной теме. Это даст основной поток передышку, необходимую для обработки ваших звонков checkQueue.

def runTest(self): 
    Thread(target=buttonTest, args=(self,)).start() 
+0

Спасибо за ответ Кевин, как я могу передать аргументы в 'buttonTest()', если бы я использовал этот метод? Поскольку 'buttonTest()' не является частью класса gui, это часть отдельного модуля в моем фактическом коде. – JimiRich

+0

Вы можете указать аргументы, используя аргумент 'args' named. Удалите «я», со второй строки вышеуказанного кода и придерживайтесь любых аргументов, которые вы хотите использовать. – Kevin

+0

Ты звезда, спасибо большое! – JimiRich