Почему добавление сигнала в pyqtSignal не распространяется на все экземпляры?

import sys
import time
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtCore import  QThread, Qt, pyqtSignal, pyqtSlot


class Thr(QThread):
    signal = pyqtSignal(int)
    
    def __init__(self,*a,**r):
        super().__init__(*a,**r)

    temp=0
    def run(self):
        while True:
            time.sleep(1)
            self.signal.emit(self.temp)
            self.temp+=1
            
            
app = QtWidgets.QApplication(sys.argv)

label = QtWidgets.QLabel()
layout = QtWidgets.QVBoxLayout(label)

dial = QtWidgets.QDial()
dial2 = QtWidgets.QDial()
layout.addWidget(dial)
layout.addWidget(dial2)

thr1=Thr(label)
thr2=Thr(label)
thr1.signal.connect(dial.setValue)
thr2.signal.connect(dial2.setValue)
thr1.start()

label.resize(500, 500)
label.show()
app.exec_()

Я не понимаю, почему когда мы в разных Qt-тредах добавляем в pyqtSignal какой то слот, он привязывается к конкретному классу QThread. Ведь в данном примере signal = pyqtSignal(int) является статическим полем и добавление какого то слота будет распространяться на все классы QThread, и вызов emit в любом экземпляре класса Thr должен распространяться на все подключенные слоты к pyqtSignal всех эксземпляров. В данном примере когда мы добавляем в 2 экземпляра Thr сигналы дляsetValueи не запускаем второй поток, то второй QDial не вращается.


Ответы (1 шт):

Автор решения: S. Nick

Да, в данном примере если вы НЕ запускаете ВТОРОЙ поток thr2.start(), то второй QDial не вращается.

Вы устанавливаете соединение, при котором вы можете получить доступ к обоим объектам (отправителю и получателю).

thr2.signal.connect(dial2.setValue)

Слот (dial2.setValue) вызывается немедленно,
когда сигнал is emitted (self.signal.emit(self.temp)).

Т.е. надо чтобы в методе run(), ДЛЯ ВТОРОГО ПОТОКА, выполнялось self.signal.emit(self.temp):

def run(self):
    while True:
        self.msleep(100)
        self.signal.emit(self.temp)                     # !!!
        self.temp += 1 

Но метод run(), ДЛЯ ВТОРОГО ПОТОКА, начнет выполняться только после thr2.start().

void QThread::start(QThread::Priority priority = InheritPriority)

Начинает выполнение потока с вызова run().

Вот и получам:

  • thr2.start() не сделали;
  • выполнение ВТОРОГО потока, вызов run() не происходит;
  • self.signal.emit(self.temp) не выполняется;
  • thr2.signal.connect(dial2.setValue) не срабатывает.
→ Ссылка