views:

1111

answers:

6

Hello,

I am writing my first Python app with PyQt4. I have a MainWindow and a Dialog class, which is a part of MainWindow class:

self.loginDialog = LoginDialog();

I use slots and signals. Here's a connection made in MainWindow:

QtCore.QObject.connect(self.loginDialog, QtCore.SIGNAL("aa(str)"), self.login)

And I try to emit signal inside the Dialog class (I'm sure it is emitted):

self.emit(QtCore.SIGNAL("aa"), "jacek")

Unfortunately, slot is not invoked. I tried with no arguments as well, different styles of emitting signal. No errors, no warnings in the code. What might be the problem?

A: 

I haven't used PyQT4 but take a look at here.

erelender
Error:QtCore.QObject.connect(self.loginDialog, QtCore.SIGNAL('aa()'), self, QtCore.SIGNAL('login()'))RuntimeError: underlying C/C++ object has been deletedThanks anyway ;)
Jacek
Should be QtCore.QObject.connect(self.loginDialog, QtCore.SIGNAL('aa()'), self, QtCore.SLOT('login()'))
bialix
You're right Bialix. Unfortunately I still get: QtCore.QObject.connect(self.loginDialog, QtCore.SIGNAL('aa()'), self, QtCore.SLOT('login()'))RuntimeError: underlying C/C++ object has been deleted
Jacek
A: 

Hey,

Looks like you miss the "SLOT" part in your connect call.

Here is an example :

QtCore.QObject.connect(self.loginDialog, QtCore.SIGNAL("NotifyMySignal(int)"), QtCore.SLOT("onNotifyMySignal(int)"));

then

self.emit(QtCore.SIGNAL('NotifyMySignal(1)'));

Hope this helps !

Andy M
SLOT is not necessary in PyQt4. Just callable is enough.
bialix
Oh ok ! My bad...
Andy M
Unfortunataly, it does not work.QtCore.QObject.connect(self.loginDialog, QtCore.SIGNAL('aa'), QtCore.SIGNAL('login'))TypeError: QObject.connect(): arguments did not match any overloaded call: overload 1: argument 3 has unexpected type 'str' overload 2: argument 3 has unexpected type 'str' overload 3: argument 2 has unexpected type 'str'Thanks anyway :)
Jacek
+5  A: 

You don't use the same signal, when emitting and connecting.

QtCore.SIGNAL("aa(str)") is not the same as QtCore.SIGNAL("aa"). Signals must have the same signature. By the way, if you are defining your own signals, don't define parametres. Just write SIGNAL('aa'), because defining parametres is a thing from C++ and Python version of Qt doesn't need this.

So it should look like this:

QtCore.QObject.connect(self.loginDialog, QtCore.SIGNAL("aa"), self.login)

and if you pass any parametres in emit, your login method must accept those parametres. Check, if this helps :-)

gruszczy
That was my mistake in pasting the code. I cut it to be more readable. I didin't do it in the real code. Thanks for a hint ;)
Jacek
But does it work now or do you still have a problem?
gruszczy
I doesn't work.
Jacek
Could you post some more of your code? Maybe the whole snippet. Then I can try to help you.
gruszczy
I would be grateful. The code is avaliable here: http://github.com/jbajor/Pwitter . Code I have problems with: ptwitt_win.py, line 83-98, ptwitter_login.py, line 54-58.
Jacek
I assume, you are sure, that code enters login method in ptwitter_login.py. Try connecting this way:self.connect(self.loginDialog, QtCore.SIGNAL('aa'), self.login)Remember to remove brackets after aa. This kind of connecting always worked for me.
gruszczy
Still the same thing.
Jacek
Well, I have no further idea then. You must have some error somewhere deeper.
gruszczy
A: 

As noted by gruszczy you have to use the same QtCore.SIGNAL('xxx') to connect signal and to emit it. Also I think you should use Qt types in the arguments list of signal function. E.g.:

QtCore.QObject.connect(self.loginDialog, QtCore.SIGNAL("aa(QString&)"), self.login)

And then emit with:

self.emit(QtCore.SIGNAL("aa(QString&)"), "jacek")

Sometimes it makes sense to define signal only once as global variable and use it elsewhere:

MYSIGNAL = QtCore.SIGNAL("aa(QString&)")
...
QtCore.QObject.connect(self.loginDialog, MYSIGNAL, self.login)
...
self.emit(MYSIGNAL, "jacek")
bialix
Still, nothing happens. I also tried to emit with no arguments, I failed again. Thanks for a hint.
Jacek
Which version of PyQt you're using?
bialix
PyQt4 263682 (returned by QtCore.PYQT_VERSION)
Jacek
QtCore.PYQT_VERSION_STR will show you human-readable string. But it seems you're using 4.6.2. I dunno why it does not work for you.
bialix
A: 

What @bialix suggested should have worked, but try an alternative way of connecting:

class Foo(QtCore.QObject):
    mysignal = QtCore.pyqtSignal(str, name='mysignal')

    def connect_to_signal(self):
        # you can use this syntax instead of the 'old' one
        self.mysignal.connect(self.myslot)

        # but this will also work
        self.connect(self, QtCore.SIGNAL('mysignal(QString)'), self.myslot) 

        self.mysignal.emit("hello")

    def myslot(self, param):
        print "received %s" % param

For a more detailed explanation of how signals/slots work in PyQt I'd suggest going through it's documentation, specifically this section.

Idan K
Does not work. Thanks for input though. I would be grateful for any new ideas.
Jacek
Try creating a separate script with the code I've written and call connect_to_signal on a Foo object, do you see any output?
Idan K
+2  A: 

I checked your code and it looks like the problem is in the way how you're connecting your signal

  1. you emit the signal in Ui_Dialog class

    self.emit(QtCore.SIGNAL("aa()"))

  2. you connect to the signal in Ui_MainWindow's setupUi method by calling

    QtCore.QObject.connect(self.loginDialog.ui, QtCore.SIGNAL("aa()"), self.login)

notice first parameter is changed to self.loginDialog.ui; your original connect call was using self.loginDialog which is of the LoginDialog type, whereas signal is emitted by the Ui_Dialog class which is ui property of the LoginDialog. After this change login method of the Ui_MainWindow got called

hope this helps, regards

serge_gubenko