Как реализовать многопоточность qt5 в python?

Пользователь

от cierra , в категории: Python , год назад

Как реализовать многопоточность qt5 в python?

Facebook Vk Ok Twitter LinkedIn Telegram Whatsapp

2 ответа

Пользователь

от linnea , год назад

@cierra 

Для реализации многопоточности в Qt5 на языке Python можно использовать модуль QThread.

  1. Начнем с создания собственного класса, унаследованного от QThread:
1
2
3
4
5
6
7
8
from PyQt5.QtCore import QThread

class MyThread(QThread):
    def __init__(self):
        super().__init__()

    def run(self):
        # здесь должен быть код, который выполнится в отдельном потоке


  1. Далее в методе run() можно указать код, который будет выполняться в отдельном потоке. Например, можно создать цикл, который будет выводить числа:
1
2
3
4
5
6
7
8
9
from PyQt5.QtCore import QThread

class MyThread(QThread):
    def __init__(self):
        super().__init__()

    def run(self):
        for i in range(10):
            print(i)


  1. Создаем объект класса MyThread и запускаем его метод start():
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
from PyQt5.QtCore import QThread

class MyThread(QThread):
    def __init__(self):
        super().__init__()

    def run(self):
        for i in range(10):
            print(i)

my_thread = MyThread()   # создаем объект класса
my_thread.start()        # запускаем поток


  1. Можно добавить сигналы и слоты для обмена информацией между потоками. Например, можно создать сигнал, который будет передавать число из потока в основной поток, и соответствующий слот:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
from PyQt5.QtCore import QThread, pyqtSignal

class MyThread(QThread):
    num_signal = pyqtSignal(int)

    def __init__(self):
        super().__init__()

    def run(self):
        for i in range(10):
            self.num_signal.emit(i)


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
from PyQt5.QtWidgets import QApplication, QLabel, QVBoxLayout, QWidget
from PyQt5.QtCore import Qt, pyqtSlot

class MyWidget(QWidget):
    def __init__(self):
        super().__init__()

        layout = QVBoxLayout()
        self.label = QLabel("Waiting for number...")
        layout.addWidget(self.label)

        self.thread = MyThread()             # создаем объект класса MyThread
        self.thread.num_signal.connect(self.on_num_signal)   # подключаем сигнал к слоту
        self.thread.start()                  # запускаем поток

        self.setLayout(layout)

    @pyqtSlot(int)
    def on_num_signal(self, num):
        self.label.setText(f"Got number: {num}")


  1. Используя многопоточность в Qt5 можно реализовать долгие операции, не блокируя пользовательский интерфейс. Таким образом, приложение не будет зависать во время выполнения задачи в отдельном потоке.

Пользователь

от yasmine , 8 месяцев назад

@cierra 

Прекрасное объяснение! Важно учитывать, что при работе с многопоточностью необходимо корректно управлять доступом к ресурсам, чтобы избежать возможных проблем с параллельными изменениями. Кроме использования QThread, в Qt также существует более высокоуровневый подход к многопоточности с использованием QtConcurrent, который упрощает организацию параллельных задач.


Вот краткий пример использования QtConcurrent для запуска функции в отдельном потоке:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
from PyQt5.QtWidgets import QApplication
from PyQt5.QtCore import Qt
from PyQt5.QtConcurrent import QtConcurrent

def my_function(param):
    return param * 2

def on_finished(result):
    print("Result:", result)

if __name__ == "__main__":
    app = QApplication([])

    future = QtConcurrent.run(my_function, 42)
    future.resultReadyAt.connect(on_finished)

    app.exec_()


Здесь мы создаем функцию my_function, которая будет выполнена в отдельном потоке с использованием QtConcurrent. Функция умножает входной параметр на 2. Мы также подключаем сигнал resultReadyAt, чтобы обработать результат выполнения функции.


Обе подходы - использование QThread и QtConcurrent - предоставляют мощные инструменты для работы с многопоточностью в Qt5 на языке Python, и правильный выбор зависит от конкретной задачи и принятой архитектуры приложения.