2016-05-15 3 views
2

Итак, у меня есть два потока python, запущенных внутри класса. Я проверил, используяБесконечные петли в потоках Python

threading.active_count() 

и он говорит, что обе потоки запущены. Первый поток включает в себя окно tkinter, которое отлично работает. Второй поток, который я использую в качестве диспетчера событий для первого окна, который также хорошо работает сам по себе. Однако, когда я запускаю второй поток рядом с первым потоком, первый поток не работает, т.е. окно не появляется. Это даже если первый поток выполняется первым. Когда я удаляю бесконечный цикл из второго потока, первый поток снова работает, может ли кто-нибудь объяснить это мне? Вот класс:

class Quiz(threading.Thread): 

    def __init__(self): 
     threading.Thread.__init__(self) 


    def show(self, question): 
     self.question = quiz[question][0] 
     self.correct = quiz[question][1] 
     self.incorrectA = quiz[question][2] 
     self.incorrectB = quiz[question][3] 
     self.ref = quiz[question][4] 
     questionDisplay.config(text=self.question) 
     correctButton = "answer" + str(self.ref[0]) 
     eval(correctButton).config(text=self.correct, command=lambda : check(True)) 
     incorrect1 = "answer" + str(self.ref[1]) 
     eval(incorrect1).config(text=self.incorrectA, command= lambda : check(False)) 
     incorrect2 = "answer" + str(self.ref[2]) 
     eval(incorrect2).config(text=self.incorrectB, command= lambda : check(False)) 
     return self.correct 

    def run(self): 
     print("thread started") 
     print(threading.active_count()) 

     while True: 
      print(questionQueue.qsize()) 
      if questionQueue.qsize() >= 1: 
       pass 

      else: 
       pass 
      print("looped") 

Благодаря

+0

Если кому-то нужно больше кода, просто скажите мне –

+0

Быстрая точка: поскольку ваш класс наследует '__init__' из' threading.thread', если вы его не определяете, вы можете также опустить этот метод из своего определения. – holdenweb

+0

Вообще говоря, tkinter не поддерживает потоки. Это можно сделать до тех пор, пока GUI работает только в основном потоке и взаимодействует с другими, которые он совершает через блокировки, для управления параллельным доступом к данным и/или потокобезопасным структурам данных, таким как очереди. – martineau

ответ

1

Из кода в настоящее время показано, что это не очевидно, где проблема. Но имейте в виду следующее:

Tk управляется событиями, как в основном, всеми инструментами GUI. Поэтому для работы графического интерфейса вам нужно запустить Tk's mainloop. Единственными частями вашего кода, которые он запускает в основном цикле, являются различные обратные вызовы, связанные с такими вещами, как кнопки, меню и таймеры.

Как и большинство инструментов GUI, Tk не является потокобезопасным из-за накладных расходов, которые потребуются. Чтобы он работал правильно, вы должны только вызывать функции и методы Tk от один поток.

Нити Python - это потоки операционной системы. Это означает, что они подлежат планированию операционной системы. И ОС иногда дает больше времени тем, которые заняты. Поэтому, если поток, который вращается в занятом цикле, предварительно упущен (как это делается регулярно), скорее всего, он снова запускается вместо потока GUI.

+0

Смогу ли я добавить конструкцию окна в тот же поток, что и метод show()? Или это можно сделать в методе __init __()? Это просто я не думаю, что я могу добавить конструкцию окна к тому же методу, что и show(), потому что show() изменяет аспекты окна и, вероятно, понадобится, чтобы, однако, написать код –

+0

Существует мало причин строить класс для него в любом случае. Будь проще. Создайте функцию для запуска во втором потоке и создайте виджеты и запустите 'mainloop' в основном потоке. –

Смежные вопросы