Qt Forum

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Unsolved

    Update: Forum Guidelines & Code of Conduct

    How to defer emitting signal?

    Qt WebKit
    5
    13
    17917
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • Q
      qiezi 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?

      1 Reply Last reply Reply Quote 1
      • G
        giesbert 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.

        Nokia Certified Qt Specialist.
        Programming Is Like Sex: One mistake and you have to support it for the rest of your life. (Michael Sinz)

        1 Reply Last reply Reply Quote 0
        • D
          dangelog last edited by

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

          Software Engineer
          KDAB (UK) Ltd., a KDAB Group company

          1 Reply Last reply Reply Quote 0
          • M
            mario 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.

            1 Reply Last reply Reply Quote 0
            • G
              giesbert 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...

              Nokia Certified Qt Specialist.
              Programming Is Like Sex: One mistake and you have to support it for the rest of your life. (Michael Sinz)

              1 Reply Last reply Reply Quote 0
              • M
                mario 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);
                @

                1 Reply Last reply Reply Quote 0
                • G
                  giesbert 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.

                  Nokia Certified Qt Specialist.
                  Programming Is Like Sex: One mistake and you have to support it for the rest of your life. (Michael Sinz)

                  1 Reply Last reply Reply Quote 0
                  • Q
                    qiezi 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.

                    1 Reply Last reply Reply Quote 0
                    • M
                      mario 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 :)

                      1 Reply Last reply Reply Quote 0
                      • G
                        giesbert 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).

                        Nokia Certified Qt Specialist.
                        Programming Is Like Sex: One mistake and you have to support it for the rest of your life. (Michael Sinz)

                        1 Reply Last reply Reply Quote 1
                        • M
                          mario 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.

                          1 Reply Last reply Reply Quote 0
                          • A
                            andre 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().

                            1 Reply Last reply Reply Quote 0
                            • Q
                              qiezi 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 Reply Last reply Reply Quote 0
                              • First post
                                Last post