How to defer emitting signal?
-
wrote on 27 Mar 2011, 14:50 last edited by
I want to custom QNetworkAccessManager to load resource from memory, and I implemented a QMyReply:
@
QMyReply::QMyReply(...)
{
// ... init some data
emit readyRead();
emit finished();
}
@It can't work, because no slot connected to readyRead/finished signal when emit signal.
My solution is:
@
QMyReply::QMyReply(...)
{
// ... init some data
QTimer::singleShot(0, this, SLOT(deferEmitSignals()));
}void QMyReply::deferEmitSignals()
{
emit readyRead();
emit finished();
}
@It's ugly.
What is the better way that defer emitting signal?
-
wrote on 27 Mar 2011, 15:33 last edited by
Hi quizi
it does not make sense to emit signas in the constructor.
If you really need similar stuff; i see no other chance than to use a single shot timer.But you should ensure, that the connects can be done then.
-
wrote on 27 Mar 2011, 17:03 last edited by
It's what is extensively used inside QNAM as of now, so I think it's perfectly acceptable.
-
wrote on 27 Mar 2011, 17:45 last edited by
You can also use queued connections when connecting the signal. Probably you want to do have this in a private wrapper class to be sure that the connections are queued.
-
wrote on 27 Mar 2011, 18:03 last edited by
Queued connects do not help here, as he wants to emit the signals in his constructor. In the constructor, no connects to the signals ob the objects exist! The queued connect could only replace the single shot timer, which is no difference...
-
wrote on 27 Mar 2011, 18:13 last edited by
I just wanted to tell him that he can use queued connection to accomplish the same thing as timers.
For example:
@
connect(sender, SIGNAL(finished()), SIGNAL(finished()), QueuedConnection);
@ -
wrote on 27 Mar 2011, 18:38 last edited by
But he implements sender. And in the constructor of sender he wants to emit the signal. So the connection is too late.
-
wrote on 27 Mar 2011, 22:51 last edited by
Thanks all.
I don't know where QNetworkAccessMnager::createRequest is called, I guess the code is:
@
QNetworkReply* reply = networkAccessManager->createRequest();
connect(reply, SIGNAL(finished()), someObj, SLOG(someSlot()));
// reply->someMethod();
@Is there a method call like reply->someMethod() after connect? I want to emit signal in this method.
-
wrote on 28 Mar 2011, 06:31 last edited by
Gerolf: Something like this should work
@
class Dummy : public QObject
{
...
public:
void emitFinished();
signal:
void finished();
}QMyReply::QMyReply(...)
{
Dummy *dummy = new QObject(this);
connect(dummy, SIGNAL(finished()), SIGNAL(finished()), QueuedConnection);dummy->emitFinished();
}
@I didn't say it would be easier/cleaner, only that he could also use QueuedConnection :)
-
wrote on 28 Mar 2011, 06:38 last edited by
Hi mario,
but it makes the whole complex more complex, requires more memory and QObject event does not have a finished signal. So he needs to implement some object with that signal.
Then it would be easier to make a queued call to one self:"QMetaObject::invokeMethod": http://doc.qt.nokia.com/latest/qmetaobject.html#invokeMethod with some parameters for queued function call or use an internal own slot with queued connection (which a single shot timer also does).
-
wrote on 28 Mar 2011, 06:44 last edited by
Ah, sweet. I totally forgot about invokeMethod. The funny thing is that I recently considered to use invokeMethod myself to replace a switch/case statement by simply doing invokeMethod for a bunch of signals :)
But I agree, seems that timer is the easiest approach in this case.
-
wrote on 28 Mar 2011, 11:53 last edited by
[quote author="qiezi" date="1301266313"]Thanks all.
Is there a method call like reply->someMethod() after connect? I want to emit signal in this method.[/quote]There is, actually. Take a look at QObject::connectNotify() and QObject::disconnectNotify().
-
wrote on 28 Mar 2011, 12:47 last edited by
Great! Thank you.
Thanks everyone.
[quote author="Gerolf" date="1301294329"]Hi mario,
but it makes the whole complex more complex, requires more memory and QObject event does not have a finished signal. So he needs to implement some object with that signal.
Then it would be easier to make a queued call to one self:"QMetaObject::invokeMethod": http://doc.qt.nokia.com/latest/qmetaobject.html#invokeMethod with some parameters for queued function call or use an internal own slot with queued connection (which a single shot timer also does).
[/quote]
1/13