Правильно отображать идентификатор потока с помощью QThread - PullRequest
0 голосов
/ 03 октября 2019

Я пытаюсь правильно отобразить идентификатор потока, используя QThread, но я получаю некоторые запутанные результаты.

Я уже читал это: PyQt: подключение сигнала к слоту для запускафоновая операция , но она охватывает конкретный вопрос о слоте и сигнале. Это не вариант. Меня не интересует порядок подключения слотов, основное внимание уделяется пониманию того, какая часть кода выполняется в определенном потоке.

Пожалуйста, рассмотрите следующий код:

from PyQt5.QtCore import QObject, QThread, pyqtSignal


class Worker(QObject):
    started = pyqtSignal()
    finished = pyqtSignal()
    def __init__(self, message):
        super(Worker, self).__init__()
        self.message = message
    def process(self, message):
        i = 0
        cicle = 10000
        j = 0
        while j < 5:
            i = i + 1
            if i % cicle == 0:
                j = float(i/cicle)
                print(message, j)
        print("Worker", int(QThread.currentThread().currentThreadId()))
        self.finished.emit()

worker1 = Worker("Worker 1:")
thread1 = QThread()
thread1.started.connect(lambda: worker1.process(worker1.message))
worker1.finished.connect(thread1.quit)
worker1.finished.connect(worker1.deleteLater)
thread1.finished.connect(thread1.deleteLater)
worker1.moveToThread(thread1)
print("Main app:", int(QThread.currentThread().currentThreadId()))


thread1.start()

Я получаю следующее:

Main App: 13420
Worker 1: 1.0
Worker 1: 2.0
Worker 1: 3.0
Worker 1: 4.0
Worker 1: 5.0
Worker 13420

Мне интересно, почему первая и последняя строки показывают одно и то же целое числоid: почему, если я перемещаю worker1 в другой поток, я получаю тот же результат?

РЕДАКТИРОВАТЬ: я снова редактирую это qasting, чтобы spacify (снова), что проблема не в порядке подключения. Я пробовал этот код:

class Worker(QObject):
    started = pyqtSignal()
    finished = pyqtSignal()
    def __init__(self, message):
        super(Worker, self).__init__()
        self.message = message
    def process(self, message):
        i = 0
        cicle = 10000
        j = 0
        while j < 5:
            i = i + 1
            if i % cicle == 0:
                j = float(i/cicle)
                print(message, j)
        # print(int(QThread.currentThread().currentThreadId()))
        print("Worker", int(QThread.currentThread().currentThreadId()))
        self.finished.emit()

worker1 = Worker("Worker 1:")
thread1 = QThread()
worker1.moveToThread(thread1)
print("Main app:", int(QThread.currentThread().currentThreadId()))
thread1.started.connect(lambda: worker1.process(worker1.message))
worker1.finished.connect(thread1.quit)
worker1.finished.connect(worker1.deleteLater)
thread1.finished.connect(thread1.deleteLater)

thread1.start()

с теми же результатами.

Не стесняйтесь редактировать вопрос, если он не подходит для сайта, и спасибо за любые предложения.

Ответы [ 2 ]

1 голос
/ 03 октября 2019

Ниже приведен полностью рабочий пример. Обратите внимание, что для решения проблемы используется декоратор pyqtSlot. Если эта строка закомментирована, пример больше не будет работать, поскольку рабочий перемещается в поток после , когда слоты подключены.

from PyQt5.QtCore import *
from PyQt5.QtWidgets import *

class Worker(QObject):
    started = pyqtSignal()
    finished = pyqtSignal()
    def __init__(self, message):
        super(Worker, self).__init__()
        self.message = message
    @pyqtSlot()
    def process(self):
        i = 0
        cicle = 10000
        j = 0
        while j < 5:
            i = i + 1
            if i % cicle == 0:
                j = float(i/cicle)
                print(self.message, j)
        print("Worker", int(QThread.currentThread().currentThreadId()))
        self.finished.emit()

app = QApplication(['test'])

worker1 = Worker("Worker 1:")
thread1 = QThread()
print("Main app:", int(QThread.currentThread().currentThreadId()))
thread1.started.connect(worker1.process)
worker1.finished.connect(thread1.quit)
worker1.finished.connect(worker1.deleteLater)
thread1.finished.connect(app.quit)
worker1.moveToThread(thread1)

thread1.start()

app.exec_()
0 голосов
/ 03 октября 2019

Хорошо,

Я обнаружил, что проблема была в лямбда-функции. Простое удаление решило проблему. Порядок подключения не влияет на вывод. Вот рабочий пример:

from PyQt5.QtCore import QObject, QThread, pyqtSignal


class Worker(QObject):
    started = pyqtSignal()
    finished = pyqtSignal()
    def __init__(self, message):
        super(Worker, self).__init__()
        self.message = message
    def process(self, message):
        i = 0
        cicle = 10000
        j = 0
        while j < 5:
            i = i + 1
            if i % cicle == 0:
                j = float(i/cicle)
                print(message, j)
        print("Worker", int(QThread.currentThread().currentThreadId()))
        self.finished.emit()

worker1 = Worker("Worker 1:")
thread1 = QThread()
thread1.started.connect(worker1.process(worker1.message))
worker1.finished.connect(thread1.quit)
worker1.finished.connect(worker1.deleteLater)
thread1.finished.connect(thread1.deleteLater)
worker1.moveToThread(thread1)
print("Main app:", int(QThread.currentThread().currentThreadId()))


thread1.start()

output:

Main App: 11624
Worker 1: 1.0
Worker 1: 2.0
Worker 1: 3.0
Worker 1: 4.0
Worker 1: 5.0
Worker 12552

Абсолютно нет способа для нового пользователя вывести это решение из полученного здесь ответа: PyQt: подключение сигнала к слоту для запуска фоновой операции .

...