Signals and Slots



  • Hello,

    in my app I have a custom class for networking that uses a QNetworkAccessManager object inside it.
    From the QNetworkAccessManager's requestFinished(..) slot I emit some custom signal that carries some data
    and which I want to handle in other classes.

    My problem is following. Imagine in some class B, I tie a slot to the signal I mentioned above.
    Then I tie another slot to this signal. In the end we may have that to my signal (customSignal) there are
    10 slots connected in some other class B. I don't want that once the signal is emitted all these
    10 slots get called simultaneously. Rather at some point in time, I want the signal to call
    only one slot, at another point in time, only another slot and etc.

    How can I achieve this?

    I know I could for example use different my custom network objects (but I was told it is not recommended??).
    e.g., like this:

      [CODE]  MyNetworkClass *network1 = new MyNetworkClass();
    

    bool res = QObject::connect(network1, SIGNAL(signalSuccess(QVariant)), this, SLOT(CustomSLot1(QVariant)));

    MyNetworkClass *network2 = new MyNetworkClass();
    

    bool res = QObject::connect(network2, SIGNAL(signalSuccess(QVariant)), this, SLOT(CustomSLot2(QVariant)));

    MyNetworkClass *network3 = new MyNetworkClass();
    

    bool res = QObject::connect(network3, SIGNAL(signalSuccess(QVariant)), this, SLOT(CustomSLot3(QVariant)));

    [/CODE]

    I think it would work this way also??? Thanks.





  • If I understand your problem correctly... It is never that way that your slots will run in parallel (assuming your application is not multhreaded) - they will be executed one by one in a random order (you can't assume anything here). So if you want to synchronize the calls somehow I think you would have to pass the signal to next slot as soon as the next step of processing is finished.

    I woudln't go into direction of creating a few network access objects - it is wasting of resources and will complicate the functionality.



  • Actually, the order of execution is defined now. It didn't used to be, but not it is officially defined (since 4.7 or so?) to be the order of connection. That is not a code change, it worked like that always. If the signals are cross-thread, all bets are off, of course.



  • Good to know this :-)

    http://qt-project.org/doc/qt-4.8/signalsandslots.html#signals-and-slots

    "If several slots are connected to one signal, the slots will be executed one after the other, in the order they have been connected, when the signal is emitted."

    So the simplest solution for the problem above would be just to make connections in the desired order. This may, however, become dangerous when the mentioned signal become used in a few different places in code so I would recommend it for a small app only.



  • I'm not really sure what the real problem is, so I can't be sure about the solution either. It almost sounds like danpritski wants a round-rubin kind of solution, where a different slot is called for each signal emission.



  • [quote author="danpritski" date="1361344950"]Rather at some point in time, I want the signal to call
    only one slot, at another point in time, only another slot and etc.[/quote]
    How are these points defined?
    If those are really points of time, defined on the timeline, independent of the signal (let's call it strangeSignal()) handling, you have to repatch connections manually (or automatically). For example, create a rotating dispatcher, that repatches connections based on the signals from a QTimer.
    If you just need that each time strangeSignal() was handled with a different slot, all slots in order, then your slots could look like this:

    @void slot1(QVariant const &v) {
    // please, place arbitrary working code instead of this comment
    QObject *sdr(sender()); // Warning: QObject::sender() violates the object-oriented principle of modularity. Never use it again
    sdr->disconnect(SIGNAL(strangeSignal(const QVariant&)), this, SLOT(slot1(const QVariant&)));
    connect(sdr, SIGNAL(strangeSignal(const QVariant&)), SLOT(slot2(const QVariant&)));
    }@

    And slot2, etc., alike.
    Moreover, you can make a set of methodIndexes, filled with slotn indexes, and pick random slot for each reconnection (with QMetaMethod-aware overload of QObject::connect()). :D
    Of course, there are plenty of other possibilities.


Log in to reply
 

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