Объект PyQt4.QtCore.pyqtSignal не имеет атрибута 'connect'
У меня возникают проблемы с пользовательским сигналом в классе, который я сделал.
Соответствующий код:
self.parse_triggered = QtCore.pyqtSignal()
def parseFile(self):
self.emit(self.parse_triggered)
Оба из них относятся к классу RefreshWidget.
В родительском классе у меня есть:
self.refreshWidget.parse_triggered.connect(self.tabWidget.giveTabsData())
Когда я пытаюсь запустить программу, я получаю сообщение об ошибке:
AttributeError: 'PyQt4.QtCore.pyqtSignal' object has no attribute 'connect'
Помощь?
Спасибо заранее.
Ответы
Ответ 1
У меня была такая же точная проблема, как и вы.
Попробуйте переместить
self.parse_triggered = QtCore.pyqtSignal()
из вашего конструктора, но внутри вашего объявления класса. Поэтому вместо этого выглядит так:
class Worker(QtCore.QThread):
def __init__(self, parent = None):
super(Worker, self).__init__(parent)
self.parse_triggered = QtCore.pyqtSignal()
Он должен выглядеть так:
class Worker(QtCore.QThread):
parse_triggered = QtCore.pyqtSignal()
def __init__(self, parent = None):
super(Worker, self).__init__(parent)
Это может быть совсем не то, что вы ищете, но это сработало для меня. Я все равно переключился на сигналы старого стиля, потому что я не нашел способ в сигналах нового стиля иметь номер undefined или тип параметров.
Ответ 2
Вы также получите это сообщение об ошибке, если в своем пользовательском классе вы не вызываете super()
или QObject.__init__()
.
Контрольный список для определения пользовательских сигналов в классе в Qt в Python:
- ваш класс происходит от QObject (прямо или косвенно)
- ваш класс
__init__
вызывает super()
(или вызывает QObject.__init__()
напрямую.)
- ваш сигнал определяется как переменная класса, а не переменная экземпляра
- подпись (формальные аргументы) вашего сигнала соответствует сигнатуре любого слота, который вы будете подключать к сигналу, например.
()
или (int)
или (str)
или ((int,), (str,))
Ответ 3
Недавно я начал работать с PySide (собственная версия PyQt от Nokia) и увидел то же самое поведение (и решение) с пользовательскими сигналами нового стиля. Моя самая большая проблема с решением заключалась в том, что использование переменной класса для хранения сигнала может повредить вещи, когда у меня есть несколько экземпляров этого класса (QThreads в моем случае).
Из того, что я мог видеть, QtCore.QObject.__init__(self)
находит переменную Signal в классе и создает копию этого сигнала для экземпляра. Я понятия не имею, что делает QObject.__init__()
, но полученный в результате сигнал имеет правильные методы connect()
, disconnect()
и emit()
(а также метод __getitem__()
), тогда как класс Signal или автономные сигнальные переменные, созданные за пределами Класс, основанный на QObject, не имеет этих методов и не может использоваться должным образом.
Ответ 4
Для использования системы сигналов/слотов вам необходимо унаследовать класс QObject.
Вот простой пример:
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()
Ответ 5
У меня была та же проблема.
Я забыл, что если класс использует Сигналы, то он должен наследовать от QObject. Я делал повторный факторинг и не обращал на это внимания.
Ответ 6
Почему вы подключаетесь напрямую к сигналу, в то время как вы можете делать
self.connect(widget, SIGNAL('parse_triggered()'), listener.listening_method)
?
где self - это, например, сама форма и может быть такой же, как слушатель