How to defer emitting signal?



  • 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?



  • 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.



  • It's what is extensively used inside QNAM as of now, so I think it's perfectly acceptable.



  • 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.



  • 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...



  • 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);
    @



  • But he implements sender. And in the constructor of sender he wants to emit the signal. So the connection is too late.



  • 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.



  • 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 :)



  • 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).



  • 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.



  • [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().



  • 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]


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.