custom signal pyqt
El objeto PyQt4.QtCore.pyqtSignal no tiene ningún atributo ''connect'' (6)
Tengo problemas con una señal personalizada en una clase que hice.
Código relevante:
self.parse_triggered = QtCore.pyqtSignal()
def parseFile(self):
self.emit(self.parse_triggered)
Ambos pertenecen a la clase: RefreshWidget. En su clase para padres tengo:
self.refreshWidget.parse_triggered.connect(self.tabWidget.giveTabsData())
Cuando intento ejecutar el programa, obtengo el error:
AttributeError: ''PyQt4.QtCore.pyqtSignal'' object has no attribute ''connect''
¿Ayuda? Gracias por adelantado.
¿Por qué te conectas directamente a la señal, mientras que puedes hacer self.connect(widget, SIGNAL(''parse_triggered()''), listener.listening_method)
?
donde el yo es, por ejemplo, la forma misma, y puede ser lo mismo que el oyente
Para usar el sistema de señal / ranura, necesita tener una clase heredada de QObject.
Aquí hay un ejemplo simple:
from PySide import QtCore
class LivingBeing(QtCore.QObject):
bornSignal = QtCore.Signal() # initialise our signal
def __init__(self,name):
QtCore.QObject.__init__(self) # initialisation required for object inheritance
self.bornSignal.connect(self.helloWorld) # connect the born signal to the helloworld function
self.name = name #
self.alive = False
def summonFromClay(self):
self.alive = True
self.bornSignal.emit() # emit the signal
def helloWorld(self):
print "Hello World !, my name is %s, this place is so great !" % self.name
# now try the little piece of code
if __name__ == ''__main__'':
firstHuman = LivingBeing(''Adam'')
firstHuman.summonFromClay()
Recientemente comencé a trabajar con PySide (la versión propia de PyQt de Nokia) y vi exactamente el mismo comportamiento (y solución) con señales personalizadas de estilo nuevo. Mi mayor preocupación con la solución era que usar una variable de clase para mantener la señal arruinaría las cosas cuando tengo varias instancias de esa clase (QThreads en mi caso).
Por lo que pude ver, QtCore.QObject.__init__(self)
encuentra la variable Signal en la clase y crea una copia de esa señal para la instancia. No tengo idea de qué hace QObject.__init__()
, pero Signal hace los métodos connect()
, disconnect()
y emit()
apropiados (y también un método __getitem__()
), mientras que la clase Signal o las variables de Signal independientes creadas fuera de una clase derivada de QObject no tiene estos métodos y no se puede usar correctamente.
También recibe ese mensaje de error si no puede llamar a super()
o QObject.__init__()
en su clase personalizada.
Una lista de verificación para definir señales personalizadas en una clase en Qt en Python:
- su clase se deriva de QObject (directa o indirectamente)
- su clase
__init__
llama asuper()
(o llama aQObject.__init__()
directamente.) - su señal se define como una variable de clase, no como una variable de instancia
- la firma (argumentos formales) de su señal coincide con la firma de cualquier ranura que conectará a la señal, por ejemplo,
()
o(int)
o(str)
o((int,), (str,))
Tuve el mismo problema exacto que tú.
Intenta moverte
self.parse_triggered = QtCore.pyqtSignal()
fuera de tu constructor pero dentro de tu declaración de clase. Entonces, en lugar de verse así:
class Worker(QtCore.QThread):
def __init__(self, parent = None):
super(Worker, self).__init__(parent)
self.parse_triggered = QtCore.pyqtSignal()
Debe tener un aspecto como este:
class Worker(QtCore.QThread):
parse_triggered = QtCore.pyqtSignal()
def __init__(self, parent = None):
super(Worker, self).__init__(parent)
Puede que esto no sea lo que estás buscando, pero funcionó para mí. Volví a cambiar a las señales de estilo antiguo de todos modos porque no he encontrado una manera en las señales de estilo nuevo para tener un número indefinido o tipo de parámetros.
Yo tuve el mismo problema. Olvidé que si una clase usa señales, entonces debe heredar de QObject. Estaba haciendo un re-factoring y no le presté atención a esto.