Important: Please read the Qt Code of Conduct -

Signal from anonymous object

  • I have a class MyRunnable that uses multiple inheritance, QObject and QRunnable, which emit signals and runs on thread provided by QThreadPool global instance. I want to create more instances of this class and have indicators for number created, waiting to run, running and completed. The problem is how to connect the signals to the slots since I do not keep a reference to the objects. The class of the object emitting the signal is known, but the object is anonymous, namely: connect(????, &MyRunnable::someSignal, this, &MainWindow::handleSignal). What should be substituted for ????.

  • Lifetime Qt Champion

    ???? must be an instance pointer as far as i know.
    Cant you connect it up when you create the instances ?

  • can you show a minimal example of what you are doing?

  • @mrjj

    Say I create one thousand instances, I surely do not want to create a connect statement for each. The Qt documentation seems contradictory it that it says that any object can emit the signal, but all examples plainly show a object as the first parameter. My question is does the connect statement connect an object to the signal or does it connect the class, thus allowing any object of that class to signal and have the connect statement correctly handle the connection between the object and the slot.

    I will try two experiments: 1. I will create an arbitrary MyRunnable to see if that makes the connection and then, if it does, see if any other MyRunnable object connects correctly. 2. I will create another, MySignaler, class an create a singleton and add that to each MyRunnable object and see if the connections to that object works. Will let you know.

  • Say I create one thousand instances, I surely do not want to create a connect statement for each.

    yes... but it's the same for all of them...

    @ofmrew said in signal from anonymous object:

    create a singleton

    singleton in multi-threaded environment is asking for trouble.

    Could you show us in a few lines of code what you'd like to achieve?

  • Say I create one thousand instances, I surely do not want to create a connect statement for each.

    It could be a stupid idea, but I know I wouldn't code 1K connects myself, but I have no issue if the code does. If the application performs well. etc.

    Could you put the connect statement inside the object and maybe at CTOR time pass an reference / pointer to the object you wish to connect SLOT to?

    That way the connect works and you only need to code one connect(); but it gets used as much as you instance up new objects?

    Be interesting to see how much how fast you could throw at this. If you do go that way and do any testing can you let us know?

  • Lifetime Qt Champion

    @6thC said in signal from anonymous object:

    It could be a stupid idea, but I know I wouldn't code 1K connects myself, but I have no issue if the code does

    Why not do this in a loop?

  • @jsulm
    That was the suggestion.

    I didn't really specify a loop or assume to know the circumstances or demand to create instances.

    I was just pointing out that if you defined the connect contained inside your object - should work regardless of what creates them and not have to code a million connects (even if that is what is the actual result of your code).

    The trade off is that you would need to pass it the reference of pointer to the other class so the connect can get it's required slot context/arguments. But I expect that would work.

  • Lifetime Qt Champion

    @6thC Well, the amount of connects does not depend on the way you implement it: whether you use a loop or put the connect into your object - you have the same number of connect() calls. And using a loop you do not code millions of connects by hand (or what do you mean?): actually you can do it with two lines of code (pseudocode):

        connect(sender[i], signal, receiver[i], slot);

  • @jsulm
    sure, you could do that in a loop. I wasn't saying otherwise.
    I was suggesting the same effect though - code it once and use it as many times as you need.

    I was thinking connect inside the object at a glance seems flexible and transports with that object. Things could come and go as they please with ease.

    Obviously requires an object - but that was going to happen anyhow in this case right?
    Inside an object would only be the one line of code, the CTOR would be as:

    connect(this, &MyRunnable::someSignal, targetObject, &TargetObject::handleSlot);

  • Lifetime Qt Champion

    @6thC Sure, you can do this, but then you need to pass the pointer to the other object - you create dependencies between classes this way.
    Signals/slots are often used to make different classes more independent of each other: the sender does not need to know who will connect to its signals and the receiver does not necessarily need to know who sends the signals.

  • @jsulm
    I see what you were getting at. Yes loosely coupled is ideal.

    I honestly haven't even done how I suggested, I don't have thousands of connects but I do have a a lot but not thousands.

    So, thinking about it you're absolutely right. I would do it outside of that object after all.

    My app I have an app object like:
    MyApp : public QApplication
    and all my other classes are instanced here as members, so my connects are all defined inside that and everything is sweet.

    If I had to do thousands of a class, yes, I would expect I'd do it there also and Iterating a container of <T> would be legit and easy.

    How do you design your IOC like code, do you use an application lifetime object, or do you have some other design concept/pattern?
    Just wondering, most of what I have is just what I've learnt myself...

  • My statement about 1000 objects should not be taken literally. What I was trying to demonstrate was how a thread pool could queue runnable objects when the number of runnable objects exceeded the number of processor cores (or hyper threads) or the setting of max threads by having a button that created and started a runnable object—and the button could be pressed 1000 time very fast. (It has no useful value other that to explore what information could be obtained about the states of the runnable objects.) The problem would have been simple it the thread pool class had a signal for a thread completion, but the thread pool object is opaque about its internals. Without that signal the only means was to have the thread do the signaling.

    For the discussion and research I did, I concluded that the only way that connect could be used was if it could be built and destroyed as required. If that can be done and, if so, how to accomplish it will require more research.

    Thank you for your responses. This item is resolved.

Log in to reply