На этом шаге мы рассмотрим общий алгоритм создания потока.
Для создания потока в PyQt предназначен класс QThread, который объявлен в модуле QtCore и наследует класс QObject. Конструктор класса QThread имеет следующий формат:
<Объект> = QThread([parent = None])
Чтобы использовать потоки, следует создать класс, который будет наследником класса QThread, и определить в нем метод run(). Код, расположенный в методе run(), будет выподняться в отдельном потоке, а после завершения выполнения метода run() этот поток прекратит свое существование. Затем нужно создать экземпляр класса и вызвать метод start(), который после запуска потока вызовет метод run(). Обратите внимание, что если напрямую вызвать метод run(), то код станет выполняться в основном, а не в отдельном потоке. Поэтому, чтобы запустить поток, необходимо вызвать именно метод start(), а не run(). Метод start() имеет следующий формат:
start([priority=QThread.InheritPriority])
Параметр priority задает приоритет выполнения потока по отношению к другим потокам. Следует учитывать, что при наличии потока с самым высоким приоритетом поток с самым низким приоритетом в некоторых операционных системах может быть просто проигнорирован. Перечислим допустимые значения параметра (в порядке увеличения приоритета) и соответствующие им атрибуты из класса QThread:
Задать приоритет потока позволяет также метод setPriority(<Приоритет>). Узнать, какой приоритет использует запущенный поток, можно с помощью метода priority(). После запуска потока генерируется сигнал started(), а после завершения - сигнал finished(). Назначив обработчики этим сигналам, можно контролировать статус потока из основного цикла приложения. Если необходимо узнать текущий статус, следует воспользоваться методами isRunning() и isFinished(). Метод isRunning() возвращает значение True, если поток выполняется, а метод isFinished() возвращает значение True, если поток закончил выполнение.
Потоки выполняются внутри одного процесса и имеют доступ ко всем глобальным переменным. Однако следует учитывать, что из потока нельзя изменять что-либо в GUI-потоке приложения, - например, выводить текст на надпись. Для изменения данных в GUI-потоке нужно использовать сигналы. Внутри потока у нужного сигнала вызывается метод emit(), который, собственно, и выполняет его генерацию. В параметрах метода emit() можно указать данные, которые будут переданы обработчику сигнала. Внутри GUI-потока назначаем обработчик этого сигнала и в обработчике пишем код, который и будет обновлять интерфейс приложения.
На следующем шаге мы закончим изучение этого вопроса.