PyQt4.QtCore.pyqtSignal object has no attribute &#

2019-01-30 22:43发布

I'm having issues with a custom signal in a class I made.

Relevant code:

self.parse_triggered = QtCore.pyqtSignal()

def parseFile(self):
    self.emit(self.parse_triggered)

Both of those belong to the class: RefreshWidget. In its parent class I have:

self.refreshWidget.parse_triggered.connect(self.tabWidget.giveTabsData())

When I try to run the program, I get the error:

AttributeError: 'PyQt4.QtCore.pyqtSignal' object has no attribute 'connect'

Help? Thanks in advance.

6条回答
时光不老,我们不散
2楼-- · 2019-01-30 23:22

I had the same problem. I forgot that if a class uses Signals, then it must inherit from QObject. I was doing some re-factoring and did not pay attention to this.

查看更多
Evening l夕情丶
3楼-- · 2019-01-30 23:29

I had the same exact problem as you.

Try moving

self.parse_triggered = QtCore.pyqtSignal()

out of your constructor but inside your class declaration. So instead of it looking like this:

class Worker(QtCore.QThread):
    def __init__(self, parent = None):
        super(Worker, self).__init__(parent)

        self.parse_triggered = QtCore.pyqtSignal()

It should look like this:

class Worker(QtCore.QThread):
    parse_triggered = QtCore.pyqtSignal()

    def __init__(self, parent = None):
        super(Worker, self).__init__(parent)

This might not be at all what you are looking for, but it worked for me. I switched back to old-style signals anyways because I haven't found a way in new-style signals to have an undefined number or type of parameters.

查看更多
姐就是有狂的资本
4楼-- · 2019-01-30 23:36

You also get that error message if you fail to call super() or QObject.__init__() in your custom class.

A checklist for defining custom signals in a class in Qt in Python:

  • your class derives from QObject (directly or indirectly)
  • your class __init__ calls super() (or calls QObject.__init__() directly.)
  • your signal is defined as a class variable, not an instance variable
  • the signature (formal arguments) of your signal matches the signature of any slot that you will connect to the signal e.g. () or (int) or (str) or ((int,), (str,))
查看更多
家丑人穷心不美
5楼-- · 2019-01-30 23:37

Why do you connect directly to the signal, while you can do self.connect(widget, SIGNAL('parse_triggered()'), listener.listening_method)?

where self is, for example, the form itself, and may be the same as listener

查看更多
\"骚年 ilove
6楼-- · 2019-01-30 23:42

I have recently started working with PySide (Nokia's own version of PyQt), and saw the exact same behaviour (and solution) with custom new-style signals. My biggest concern with the solution was that using a class variable to hold the signal would mess things up when I have multiple instances of that class (QThreads in my case).

From what I could see, QtCore.QObject.__init__(self) finds the Signal variable in the class and creates a copy of that Signal for the instance. I have no idea what QObject.__init__() does, but the resulting Signal does proper connect(), disconnect() and emit() methods (and also a __getitem__() method), whereas the class Signal or standalone Signal variables created outside of a QObject-derived class do not have these methods and can't be used properly.

查看更多
爷、活的狠高调
7楼-- · 2019-01-30 23:42

To use the signal/slot system you need to have a QObject inherited class.

Here is a simple example:



    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()

 
查看更多
登录 后发表回答