Код довольно тяжелый, поэтому я просто опубликую несколько фрагментов.
class Program(QtGui.QWidget):
def __init__(self, parent=None):
super(Program, self).__init__(parent)
...
def main():
app = QtGui.QApplication(sys.argv)
global ex
ex = Program()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
А между ними у меня есть куча меток, текстовых полей, кнопок и 4 QListWidgets внутри вложенных макетов, эти вложенные макеты добавляются в сетку.
Я запускаю переменное количество потоков в зависимости от ввода. Обычно 4 потока. Они запускаются в собственном классе:
class myThread(Thread):
def __init__(self, arguments, more_arguments):
threading.Thread.__init__(self)
def work_it(self, argument, more_arguments):
Program.some_function_in_Program_class(ex, arguments)
И оттуда я вызываю функции внутри класса Program(), чтобы внести фактические изменения в графический интерфейс.
Program.generate_results(ex, arguments, arguments2, more_arguments)
В конце концов, это сводится к списку, который я повторяю, и независимо от того, печатаю ли я каждый элемент или использую:
my_listbox.addItem(item)
Он замораживает графический интерфейс до тех пор, пока все 4 потока не завершат просмотр списка. Тогда все результаты отображаются вместе, а не по одному.
Я сделал это в Tkinter, и я мог видеть, что один за другим элемент списка появляется в виджетах ListBox динамически, без зависания графического интерфейса.
Что касается управления потоками, то я делаю итерацию по списку и в зависимости от его длины создаю несколько потоков:
threadlist = []
for i in self.results:
sub_thread = myThread(i, self.results[i])
self.threadlist.append(sub_thread)
swapAndWaitThread = spawnAndWaitThreadsThread(self.threadlist)
swapAndWaitThread.start()
Я делаю это, чтобы иметь возможность управлять этими 4 потоками и знать, когда они завершены.
class spawnAndWaitThreadsThread(Thread):
def __init__(self, threadlist):
threading.Thread.__init__(self)
self.threadlist = threadlist
def run(self):
for thread in self.threadlist:
thread.start()
for thread in self.threadlist:
thread.join()
print "threads finished.. do something"
Что я делаю не так?
Thread
недостаточно, чтобы сделать фрагмент кода многопоточным. Например, для потоков, унаследованных отthreading.thread
, необходимо поместите нужный код в его методrun
, а затем в какой-то момент вызовитеstart
. Код, который появляется внутри, скажем, метода__init__
, все равно будет выполняться в основном потоке. - person Kevin   schedule 18.02.2015run
и запустить потоки какthread.start(args = (my_program_instance,))
, но глобальная переменная тоже должна работать. В целом вашspawnAndWaitThreadsThread
выглядит нормально. Я думаю, что следующее место, где я буду искать проблемы, это внутриmyThread
- person Kevin   schedule 18.02.2015