Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Define and emit signal from main



  • I have an applications such as this:

    int main(int argc, char *argv[])
    {
      QGuiApplication app(argc, argv);
    
    #if TARGET_OS_IPHONE || TARGET_OS_IPHONE_SIMULATOR
      // register our user default preferences (iOS)
      UserPreferenceUtility user_prefs;
      user_prefs.registerDefaultPrefs();
    #endif
      
      TapDisplaySingleton* mainClass = new TapDisplaySingleton(&app);
    
    ...
    

    Is it possible to define a signal and connect it to mainClass? Do I need to define a class which derives from QObject, instantiate it and move my processing there?



  • Hi!

    Is it possible to define a signal and connect it to mainClass?

    No.

    Do I need to define a class which derives from QObject, instantiate it and move my processing there?

    Yes.

    :-)



  • class YourClass: public QObject{
    Q_OBJECT;
    ...
    public signals:
    void yourSignal();
    };
    
    ...
    
    class SecondClass{
    Q_OBJECT;
    ...
    public slots:
    void slotFunc();
    }
    
    YourClass *youObject = new YourClass ;
    
    
    connect(YourClass, SIGNAL(yourSignal()), SecondClassObject, SLOT(someSlot()));
    

    We need to keep main function minimal.



  • @Wieland Thanks.



  • @DRoscoe that helped i guess.

    Thanks,



  • Can you tell us what are you trying to do? defining and connecting a signal that will not be emitted by anyone is useless. what is your aim?

    My guess is that what you are after is either QMetaObject::invokeMethod or QTimer::singleShot(0



  • @VRonin I wanted to emit a signal from main.cpp that would be picked up by mainClass when the event loop was started. I never said anything about defining a signal that would be picked up by no one. As soon as you mentioned the single-shot timer, I smacked myself in the head, because I am already doing that exact thing to send a signal to mainClass to tell it to initialize when the event loop starts. I didn't connect the dots to extend that to my current problem.

    @Pradeep-Kumar I already know HOW to create properly derived classes for signals and slots. My project currently defines hundreds of them. I was only wondering if I would have to define a class derived from QObject in main.cpp, instantiate it and transfer my main.cpp processing to it. Both your response and that of @Wieland pretty much confirmed what I was hoping to avoid, so yes.. it was helpful. Thanks!

    -Dave


  • Qt Champions 2017

    You can attach a lambda to the single shot timer (as per @VRonin), so you don't actually have to write separate QObject subclass.

    QTimer::singleShot(0, [] () -> void  {
        // We have an active event loop here.
    });
    

    Also you can do deferred signal emission with QMetaObject::invokeMethod:

    QMetaObject::invokeMetod(emitter, "signalName", Qt::QueuedConnection); //< You can even pass arguments
    

    But I'm with @VRonin, what are you trying to do exactly?



  • @kshegunov I think I've been pretty clear about what I am trying to do. I want to emit a signal from my main.cpp entry point to be picked up by my derived mainClass. If the particulars matter, the mainClass has a thread-safe logger that isn't created until the class is initialized. Having the event queued on its event loop ensures it gets written in a thread-safe manner after the logger is instantiated and the log file is created. It is primarily to capture issues with command line arguments in an environment where a console window will not be available (such as in an aircraft cockpit).


  • Qt Champions 2017

    @DRoscoe said in Define and emit signal from main:

    I think I've been pretty clear about what I am trying to do.

    Apparently not. But in any case a signal will always require an emitter object, it can't float in the empty space, so I suppose your best bet is to just queue the call through the event loop with a zero-timeout timer event (i.e. QTimer::singleShot). If you just want to call a slot after the event loop starts then you can also use the QMetaObject::invokeMethod approach:

    QMetaObject::invokeMethod(receiver, "slotName", Qt::QueuedConnection); //< You can even pass arguments
    


  • @kshegunov thank you!


  • Qt Champions 2017

    You're welcome.

    PS. My personal preference is with invokeMethod() but the function unfortunately doesn't support the pointer-to-member syntax, so its usage is getting ever so rare.


Log in to reply