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

How to emit signal dynamically



  • Hello, everyone.

    In the project I am developing, a requirement came up to update values for different modules (classes).
    I am developing a class which will translate the value and its module name and emit a signal that is connected to a slot in the specified module.
    The only problem is: how can I emit a specific signal for each model without the need of hardcoded code?
    There's a example of how I am currently implementing it.

    Header example:

    #define MODULE_NAME_1 "Module1"
    
    public slots:
       void onValueUpdate(QString moduleName, int value);
    signals:
        void notifyToModule1(int value);
        void notifyToModule2(int value);
        ....
    

    Cpp example:

    void ValueUpdate(QString moduleName, int value)
    {
        if(notifyToModule1.contains(moduleName))
        {
            emit notifyToModule1(value);
        }
        if(notifyToModule2.contains(moduleName))
        {
            emit notifyToModule2(value);
        }
        ....
    }
    

    There was a solution: Use an unique signal that is connected to each module's slots. Then, each slot would verify if its name equals the parameter "moduleName" and discard the value if not. However, this implementation could cause each slot to be called every 1 ms and I can't see this being okay.
    Still, in my opinion, this implementation is very ugly. Therefore, I would like some thoughts about how I can do this differently by using any kind of design pattern or Qt feature.


  • Moderators

    @Luis-Ortiz
    you'll have to branch eventually,
    either before emitting the signal or in the connected slots.

    What you could do is replace the module name with an enum, Integer comparing is much faster than string



  • The classic way to prevent branching is to use a array ( or map ) of class pointers, each module implementing the same interface ( notifyToModule ) like this:

    QMap(QString, ModuleInterface*)
    and simply call:
    map[ModuleName]->notifyToModule(value);

    In modern c++ (>= C++11) I think it should be possible to store function pointers or even lambda for each module.



  • @mpergand That is exactly what I was looking for. Such a simple implementation. I don't know how I was not able to think about this by myself.
    Actually, trying to use Qt features exclusively may be the problem as I keep forgetting about C++ features.
    Thank you very much!

    @J-Hilk That is what I thought. I will use the @mpergand instead. Thanks!



  • @Luis-Ortiz said in How to emit signal dynamically:

    I will use the @mpergand instead

    Could your issue be called as solved? If so, please don't forget to mark your post as such.


Log in to reply