Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Mobile and Embedded
  4. Is it possible to mimic the functionality of an array of signals?
Forum Updated to NodeBB v4.3 + New Features

Is it possible to mimic the functionality of an array of signals?

Scheduled Pinned Locked Moved Solved Mobile and Embedded
12 Posts 5 Posters 852 Views
  • 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.
  • JeKK666J Offline
    JeKK666J Offline
    JeKK666
    wrote on last edited by JeKK666
    #1

    Essentially, i'm trying to write less code possible to create a remappable keypad, and i would like to give the user the possbility of changing the selected map on the fly, based on a global setting.
    The global setting would be selected via a QPushButton which belongs to an autoexclusive QButtonGroup.

    The keypad is a 4 button hardware; once the button has been decoded the corresponding signal is emitted;
    each button, button combination, short and long press, has its own signal like for example

    signals:
        void keypadTopLeft();
        void keypadTopRight();
    ...
    

    each signal is connected to different parts of the HMI application; connections are changed based on which page of a stacked widget is currently selected.

    There are many connections in place, and i'm trying to avoid rewriting all the connections like so:

    /*when widget1 is displayed*/
    if (keypad_map == 1) {
        connect (keypad, SIGNAL(keypadTopLeft()), destinationWidget1, SLOT(on_keypadTopLeft()));
    else if (keypad_map == 2) 
        connect (keypad, SIGNAL(keypadTopLeft()), destinationWidget1, SLOT(on_keypadTopRight()));
    ...
    /*when widget2 is displayed*/
    if (keypad_map == 1) {
        connect (keypad, SIGNAL(keypadTopLeft()), destinationWidget2, SLOT(on_keypadTopLeft()));
    else if (keypad_map == 2) 
        connect (keypad, SIGNAL(keypadTopLeft()), destinationWidget2, SLOT(on_keypadTopRight()));
    
    /*in keypad class*/
    switch(button) {
        case (topLeft)
            emit keypadTopLeft();
        break;
    ...
     }
    

    So, to avoid rewriting all the existing code, i thought of building kind of a signal lookup table, so i would need to change the name of the signal for each existing connect and emit, but i'd avoid adding if statements everywhere, would also be a mess to disconnect properly.
    The lookup table would be a 2D array where one index is the global keypad mapping option, and the second index is the result of the button decoding, like this:

    decltype(SIGNAL(keypadTopLeft())) keypadRemapper[KEYPAD_MAP_1][TOP_LEFT] = SIGNAL(keypadTopLeft());
    ...
    decltype(SIGNAL(keypadTopLeft())) keypadRemapper[KEYPAD_MAP_2][TOP_LEFT] = SIGNAL(keypadTopRight());
    

    Of course this does not work, nor does trying to declare an array of signals like signals: void signalTable[][](); , which doesn't even compile...

    I tried wrapping my head around the QSignalMapper class, but while having some trouble to understand the reasoning behind it in the first place, it also seems such class would be better suited for handling signals sent by graphical things... maybe?

    Let me try to explain what i understood from the docs: they read "The QSignalMapper class bundles signals from identifiable senders" and also "re-emits them with integer, string or widget parameters corresponding to the object that sent the signal", so in my case, where i have only the class Keypad inheriting from QObject, i would not be able to distinguish the button because each button would need to be an object itself, did i get this right?

    Still haven't learned Lambdas...

    jsulmJ 1 Reply Last reply
    0
    • J.HilkJ Offline
      J.HilkJ Offline
      J.Hilk
      Moderators
      wrote on last edited by
      #10

      @JeKK666

      QMetaObject for the rescue:

      #include <array>
      
      class SomeClass : public QObject
      {
          Q_OBJECT
      
          std::array<const char*, 3>  arrayOfSignals{"signal1", "signal2", "signal3"};
          std::array<const char*, 3>  arrayOfSlots{"slot1", "slot2", "slot3"};
      
      public:
          SomeClass(QObject *parent = nullptr) : QObject(parent)
          {
              QObject::connect(this, &SomeClass::signal1, this, &SomeClass::slot1);
              QObject::connect(this, &SomeClass::signal2, this, &SomeClass::slot2);
              QObject::connect(this, &SomeClass::signal3, this, &SomeClass::slot3);
      
              qDebug() << "Call slots via signal array";
              for(auto entry : arrayOfSignals){
                  QMetaObject::invokeMethod(this, entry);
              }
      
              qDebug() << "Call Slots vis slot array";
              for(auto entry : arrayOfSlots){
                  QMetaObject::invokeMethod(this, entry);
              }
          }
      
      signals:
          void signal1();
          void signal2();
          void signal3();
      
      public slots:
          void slot1(){qDebug() <<  Q_FUNC_INFO;}
          void slot2(){qDebug() <<  Q_FUNC_INFO;}
          void slot3(){qDebug() <<  Q_FUNC_INFO;}
      };
      

      does this do, what you want it to?


      Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


      Q: What's that?
      A: It's blue light.
      Q: What does it do?
      A: It turns blue.

      JeKK666J 1 Reply Last reply
      1
      • JeKK666J JeKK666

        Essentially, i'm trying to write less code possible to create a remappable keypad, and i would like to give the user the possbility of changing the selected map on the fly, based on a global setting.
        The global setting would be selected via a QPushButton which belongs to an autoexclusive QButtonGroup.

        The keypad is a 4 button hardware; once the button has been decoded the corresponding signal is emitted;
        each button, button combination, short and long press, has its own signal like for example

        signals:
            void keypadTopLeft();
            void keypadTopRight();
        ...
        

        each signal is connected to different parts of the HMI application; connections are changed based on which page of a stacked widget is currently selected.

        There are many connections in place, and i'm trying to avoid rewriting all the connections like so:

        /*when widget1 is displayed*/
        if (keypad_map == 1) {
            connect (keypad, SIGNAL(keypadTopLeft()), destinationWidget1, SLOT(on_keypadTopLeft()));
        else if (keypad_map == 2) 
            connect (keypad, SIGNAL(keypadTopLeft()), destinationWidget1, SLOT(on_keypadTopRight()));
        ...
        /*when widget2 is displayed*/
        if (keypad_map == 1) {
            connect (keypad, SIGNAL(keypadTopLeft()), destinationWidget2, SLOT(on_keypadTopLeft()));
        else if (keypad_map == 2) 
            connect (keypad, SIGNAL(keypadTopLeft()), destinationWidget2, SLOT(on_keypadTopRight()));
        
        /*in keypad class*/
        switch(button) {
            case (topLeft)
                emit keypadTopLeft();
            break;
        ...
         }
        

        So, to avoid rewriting all the existing code, i thought of building kind of a signal lookup table, so i would need to change the name of the signal for each existing connect and emit, but i'd avoid adding if statements everywhere, would also be a mess to disconnect properly.
        The lookup table would be a 2D array where one index is the global keypad mapping option, and the second index is the result of the button decoding, like this:

        decltype(SIGNAL(keypadTopLeft())) keypadRemapper[KEYPAD_MAP_1][TOP_LEFT] = SIGNAL(keypadTopLeft());
        ...
        decltype(SIGNAL(keypadTopLeft())) keypadRemapper[KEYPAD_MAP_2][TOP_LEFT] = SIGNAL(keypadTopRight());
        

        Of course this does not work, nor does trying to declare an array of signals like signals: void signalTable[][](); , which doesn't even compile...

        I tried wrapping my head around the QSignalMapper class, but while having some trouble to understand the reasoning behind it in the first place, it also seems such class would be better suited for handling signals sent by graphical things... maybe?

        Let me try to explain what i understood from the docs: they read "The QSignalMapper class bundles signals from identifiable senders" and also "re-emits them with integer, string or widget parameters corresponding to the object that sent the signal", so in my case, where i have only the class Keypad inheriting from QObject, i would not be able to distinguish the button because each button would need to be an object itself, did i get this right?

        jsulmJ Offline
        jsulmJ Offline
        jsulm
        Lifetime Qt Champion
        wrote on last edited by jsulm
        #2

        @JeKK666 Why don't you use a mapping between key and method pointer? Then you just need to change this mapping if you want to remap the keys. Something like:

        enum class Keys
        {
            TopLeft,
            TopRight,
            BottomLeft,
            BottomRight
        }
        QMap<Keys, HERE_METHOD_POINTER> mapping;
        connect (this, &MyClass::keypadTopLeft, [this]() { mapping[Keys::TopLeft](); });
        ...
        connect (this, &MyClass::keypadBottomRight, [this]() { mapping[Keys::BottomRight](); });
        

        https://forum.qt.io/topic/113070/qt-code-of-conduct

        JeKK666J 2 Replies Last reply
        3
        • jsulmJ jsulm

          @JeKK666 Why don't you use a mapping between key and method pointer? Then you just need to change this mapping if you want to remap the keys. Something like:

          enum class Keys
          {
              TopLeft,
              TopRight,
              BottomLeft,
              BottomRight
          }
          QMap<Keys, HERE_METHOD_POINTER> mapping;
          connect (this, &MyClass::keypadTopLeft, [this]() { mapping[Keys::TopLeft](); });
          ...
          connect (this, &MyClass::keypadBottomRight, [this]() { mapping[Keys::BottomRight](); });
          
          JeKK666J Offline
          JeKK666J Offline
          JeKK666
          wrote on last edited by
          #3

          @jsulm :O i did not know of QMap, will give it i try, thanks! :)

          Still haven't learned Lambdas...

          1 Reply Last reply
          0
          • jsulmJ jsulm

            @JeKK666 Why don't you use a mapping between key and method pointer? Then you just need to change this mapping if you want to remap the keys. Something like:

            enum class Keys
            {
                TopLeft,
                TopRight,
                BottomLeft,
                BottomRight
            }
            QMap<Keys, HERE_METHOD_POINTER> mapping;
            connect (this, &MyClass::keypadTopLeft, [this]() { mapping[Keys::TopLeft](); });
            ...
            connect (this, &MyClass::keypadBottomRight, [this]() { mapping[Keys::BottomRight](); });
            
            JeKK666J Offline
            JeKK666J Offline
            JeKK666
            wrote on last edited by
            #4

            @jsulm It would seem i am not able to declare a QMap which uses a pointer to a method as the T value, as in QMap<Key, T>.

            I also have troubles reading your code:

            • i don't understand what results putting curly braces within connect() is going to produce;
            • i don't get what the square brackets around [this] mean;
            • i fail to grasp this overload of connect(), which is not the standard connect(senderObject, SIGNAL(sig()), receiverObject, SLOT(on_sig()))
              Could you elaborate more?

            Still haven't learned Lambdas...

            JonBJ jsulmJ 2 Replies Last reply
            0
            • JeKK666J JeKK666

              @jsulm It would seem i am not able to declare a QMap which uses a pointer to a method as the T value, as in QMap<Key, T>.

              I also have troubles reading your code:

              • i don't understand what results putting curly braces within connect() is going to produce;
              • i don't get what the square brackets around [this] mean;
              • i fail to grasp this overload of connect(), which is not the standard connect(senderObject, SIGNAL(sig()), receiverObject, SLOT(on_sig()))
                Could you elaborate more?
              JonBJ Offline
              JonBJ Offline
              JonB
              wrote on last edited by JonB
              #5

              @JeKK666
              All your questions are covered by New Signal Slot Syntax. Change over from old SIGNAL/SLOT() macros, and learn what a C++ lambda is (search that page for examples).

              1 Reply Last reply
              1
              • JeKK666J JeKK666

                @jsulm It would seem i am not able to declare a QMap which uses a pointer to a method as the T value, as in QMap<Key, T>.

                I also have troubles reading your code:

                • i don't understand what results putting curly braces within connect() is going to produce;
                • i don't get what the square brackets around [this] mean;
                • i fail to grasp this overload of connect(), which is not the standard connect(senderObject, SIGNAL(sig()), receiverObject, SLOT(on_sig()))
                  Could you elaborate more?
                jsulmJ Offline
                jsulmJ Offline
                jsulm
                Lifetime Qt Champion
                wrote on last edited by
                #6

                @JeKK666 said in Is it possible to mimic the functionality of an array of signals?:

                i don't understand what results putting curly braces within connect() is going to produce;
                i don't get what the square brackets around [this] mean;

                Please read about lambdas in C++.

                enum class Keys
                {
                    TopLeft,
                    TopRight,
                    BottomLeft,
                    BottomRight
                }
                typedef void (MyClass::*MethodPointer)();
                QMap<Keys, MethodPointer> mapping; // I assume mapping is class member
                connect (this, &MyClass::keypadTopLeft, [this]() { (this->*mapping[Keys::TopLeft])(); });
                ...
                connect (this, &MyClass::keypadBottomRight, [this]() { (this->*mapping[Keys::BottomRight])(); });
                

                https://forum.qt.io/topic/113070/qt-code-of-conduct

                1 Reply Last reply
                1
                • JeKK666J Offline
                  JeKK666J Offline
                  JeKK666
                  wrote on last edited by
                  #7

                  @JonB I wanted to retain the signal/slot model, since conceptually i connect the keypad to different Widgets, and each widget has a dedicated slot for the keypad signal to be connected to it; also, it is how this old software, tried and true, born with Qt4.8 is structured, so since it technically ain't broke, i am not going to fix it :P (code was subsequently ported to Qt 5.3.2, but never rewritten to use newer constructs).

                  @jsulm I always had trouble grasping how lambdas work, therefore i never used them and a can't recognize them at a glance; i followed your suggestions, and smashed my head on it a little bit longer, i think i now have a better understading.

                  The QMap was still giving me troubles until i read @jsulm's first answer, as i was not able to figure out the syntax i had to use for as a member function pointer.
                  It did, however, provide me a suggestion on how to manually implement a similar strategy, resorting to a more basic approach: since a matrix of signals is not available, i created a matrix of function pointers called keypadMapper, where each function is a stupid wrapper for a call to emit signal(); .

                  This gives me the code readability that i want while also avoiding code duplication for the connect-disconnect section in the main program:
                  in the keypad class, after decoding the button, i will call

                  (this->*keypadMapper[TOP_LEFT][KP_MAP_TYPE])(); 
                  

                  It might not be the most elegant solution, but it fits into the rest of the codebase with minimal effort on the rest of the classes, and to me also looks quite easy to read, which is a plus for maintainability.

                  Thanks!

                  Still haven't learned Lambdas...

                  VRoninV 1 Reply Last reply
                  1
                  • JeKK666J JeKK666

                    @JonB I wanted to retain the signal/slot model, since conceptually i connect the keypad to different Widgets, and each widget has a dedicated slot for the keypad signal to be connected to it; also, it is how this old software, tried and true, born with Qt4.8 is structured, so since it technically ain't broke, i am not going to fix it :P (code was subsequently ported to Qt 5.3.2, but never rewritten to use newer constructs).

                    @jsulm I always had trouble grasping how lambdas work, therefore i never used them and a can't recognize them at a glance; i followed your suggestions, and smashed my head on it a little bit longer, i think i now have a better understading.

                    The QMap was still giving me troubles until i read @jsulm's first answer, as i was not able to figure out the syntax i had to use for as a member function pointer.
                    It did, however, provide me a suggestion on how to manually implement a similar strategy, resorting to a more basic approach: since a matrix of signals is not available, i created a matrix of function pointers called keypadMapper, where each function is a stupid wrapper for a call to emit signal(); .

                    This gives me the code readability that i want while also avoiding code duplication for the connect-disconnect section in the main program:
                    in the keypad class, after decoding the button, i will call

                    (this->*keypadMapper[TOP_LEFT][KP_MAP_TYPE])(); 
                    

                    It might not be the most elegant solution, but it fits into the rest of the codebase with minimal effort on the rest of the classes, and to me also looks quite easy to read, which is a plus for maintainability.

                    Thanks!

                    VRoninV Offline
                    VRoninV Offline
                    VRonin
                    wrote on last edited by
                    #8

                    @JeKK666 said in Is it possible to mimic the functionality of an array of signals?:

                    where each function is a stupid wrapper for a call to emit signal();.

                    You don't need that. emit is meaningless to the compiler, it's just for readability. Just create a pointer to the signal directly. A signal is not magic, it's a public member. The only special feature is that it's body is not written by you but by moc

                    "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                    ~Napoleon Bonaparte

                    On a crusade to banish setIndexWidget() from the holy land of Qt

                    JeKK666J 1 Reply Last reply
                    3
                    • VRoninV VRonin

                      @JeKK666 said in Is it possible to mimic the functionality of an array of signals?:

                      where each function is a stupid wrapper for a call to emit signal();.

                      You don't need that. emit is meaningless to the compiler, it's just for readability. Just create a pointer to the signal directly. A signal is not magic, it's a public member. The only special feature is that it's body is not written by you but by moc

                      JeKK666J Offline
                      JeKK666J Offline
                      JeKK666
                      wrote on last edited by
                      #9

                      @VRonin I tried that several times over already (inspired from this): i based my assumptions on the fact that the declaration of a signal is syntactically identical to the declaration of a function prototype, save for the signals: keyword prepended to it, so i proceded to try and use a function pointer when passing arguments to the connect().

                      Alas, i was never able to guess the correct syntax which would allow the darn thing to compile, i remember getting compile errors on the connect(), but could not reproduce now.
                      Also, that would still require me to write switch-case connects based on the currently selected keypad map, or at least switch-case assignment of the signal pointer, since when i emit the signal, it still wouldn't accept array indexing (even more: decltype<...> threw at me all sorts of error, and i would also need a pointer for each signal)

                      Still haven't learned Lambdas...

                      1 Reply Last reply
                      0
                      • J.HilkJ Offline
                        J.HilkJ Offline
                        J.Hilk
                        Moderators
                        wrote on last edited by
                        #10

                        @JeKK666

                        QMetaObject for the rescue:

                        #include <array>
                        
                        class SomeClass : public QObject
                        {
                            Q_OBJECT
                        
                            std::array<const char*, 3>  arrayOfSignals{"signal1", "signal2", "signal3"};
                            std::array<const char*, 3>  arrayOfSlots{"slot1", "slot2", "slot3"};
                        
                        public:
                            SomeClass(QObject *parent = nullptr) : QObject(parent)
                            {
                                QObject::connect(this, &SomeClass::signal1, this, &SomeClass::slot1);
                                QObject::connect(this, &SomeClass::signal2, this, &SomeClass::slot2);
                                QObject::connect(this, &SomeClass::signal3, this, &SomeClass::slot3);
                        
                                qDebug() << "Call slots via signal array";
                                for(auto entry : arrayOfSignals){
                                    QMetaObject::invokeMethod(this, entry);
                                }
                        
                                qDebug() << "Call Slots vis slot array";
                                for(auto entry : arrayOfSlots){
                                    QMetaObject::invokeMethod(this, entry);
                                }
                            }
                        
                        signals:
                            void signal1();
                            void signal2();
                            void signal3();
                        
                        public slots:
                            void slot1(){qDebug() <<  Q_FUNC_INFO;}
                            void slot2(){qDebug() <<  Q_FUNC_INFO;}
                            void slot3(){qDebug() <<  Q_FUNC_INFO;}
                        };
                        

                        does this do, what you want it to?


                        Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                        Q: What's that?
                        A: It's blue light.
                        Q: What does it do?
                        A: It turns blue.

                        JeKK666J 1 Reply Last reply
                        1
                        • J.HilkJ J.Hilk

                          @JeKK666

                          QMetaObject for the rescue:

                          #include <array>
                          
                          class SomeClass : public QObject
                          {
                              Q_OBJECT
                          
                              std::array<const char*, 3>  arrayOfSignals{"signal1", "signal2", "signal3"};
                              std::array<const char*, 3>  arrayOfSlots{"slot1", "slot2", "slot3"};
                          
                          public:
                              SomeClass(QObject *parent = nullptr) : QObject(parent)
                              {
                                  QObject::connect(this, &SomeClass::signal1, this, &SomeClass::slot1);
                                  QObject::connect(this, &SomeClass::signal2, this, &SomeClass::slot2);
                                  QObject::connect(this, &SomeClass::signal3, this, &SomeClass::slot3);
                          
                                  qDebug() << "Call slots via signal array";
                                  for(auto entry : arrayOfSignals){
                                      QMetaObject::invokeMethod(this, entry);
                                  }
                          
                                  qDebug() << "Call Slots vis slot array";
                                  for(auto entry : arrayOfSlots){
                                      QMetaObject::invokeMethod(this, entry);
                                  }
                              }
                          
                          signals:
                              void signal1();
                              void signal2();
                              void signal3();
                          
                          public slots:
                              void slot1(){qDebug() <<  Q_FUNC_INFO;}
                              void slot2(){qDebug() <<  Q_FUNC_INFO;}
                              void slot3(){qDebug() <<  Q_FUNC_INFO;}
                          };
                          

                          does this do, what you want it to?

                          JeKK666J Offline
                          JeKK666J Offline
                          JeKK666
                          wrote on last edited by JeKK666
                          #11

                          @J-Hilk Yes! I had also tried using the QMetaObject::invokeMethod(), but never got around to make it work: no compile time errors, just no execution of the slot whatsoever, and was never able to narrow it down to either signal emission or sig/slot connection...

                          Anyhow, call me dumb but i find the syntax for this overall thing a lot more convoluted than a matrix of function pointers >.<'
                          Still, a much more elegant solution nonetheless, that's great.

                          Thanks!

                          Still haven't learned Lambdas...

                          J.HilkJ 1 Reply Last reply
                          1
                          • JeKK666J JeKK666

                            @J-Hilk Yes! I had also tried using the QMetaObject::invokeMethod(), but never got around to make it work: no compile time errors, just no execution of the slot whatsoever, and was never able to narrow it down to either signal emission or sig/slot connection...

                            Anyhow, call me dumb but i find the syntax for this overall thing a lot more convoluted than a matrix of function pointers >.<'
                            Still, a much more elegant solution nonetheless, that's great.

                            Thanks!

                            J.HilkJ Offline
                            J.HilkJ Offline
                            J.Hilk
                            Moderators
                            wrote on last edited by
                            #12

                            @JeKK666 said in Is it possible to mimic the functionality of an array of signals?:

                            Anyhow, call me dumb but i find the syntax for this overall thing a lot more convoluted than a matrix of function pointers >.<'

                            I would say, thats a debatable point :D

                            #include <array>
                            
                            class SomeClass : public QObject
                            {
                                typedef void (SomeClass::*SomeClassFunction)();
                                Q_OBJECT
                            
                            //    std::array<const char*, 3>  arrayOfSignals{"signal1", "signal2", "signal3"};
                            //    std::array<const char*, 3>  arrayOfSlots{"slot1", "slot2", "slot3"};
                            
                                    std::array<SomeClassFunction,3> arrayOfSignalsPointers{&SomeClass::signal1,&SomeClass::signal2, &SomeClass::signal3};
                                    std::array<SomeClassFunction, 3> arrayOfSlotsPointers{&SomeClass::slot1, &SomeClass::slot2, &SomeClass::slot3};
                            
                            public:
                                SomeClass(QObject *parent = nullptr) : QObject(parent)
                                {
                                    QObject::connect(this, &SomeClass::signal1, this, &SomeClass::slot1);
                                    QObject::connect(this, &SomeClass::signal2, this, &SomeClass::slot2);
                                    QObject::connect(this, &SomeClass::signal3, this, &SomeClass::slot3);
                            
                            //        qDebug() << "Call slots via signal array";
                            //        for(auto entry : arrayOfSignals){
                            //            QMetaObject::invokeMethod(this, entry);
                            //        }
                            
                            //        qDebug() << "Call Slots vis slot array";
                            //        for(auto entry : arrayOfSlots){
                            //            QMetaObject::invokeMethod(this, entry);
                            //        }
                            
                                    //----
                                    for(auto entry : arrayOfSignalsPointers){
                                        (this->*entry)();
                                    }
                            
                                    for(auto entry : arrayOfSlotsPointers){
                                        (this->*entry)();
                                    }
                                }
                            signals:
                                void signal1();
                                void signal2();
                                void signal3();
                            
                            public slots:
                                void slot1(){qDebug() <<  Q_FUNC_INFO;}
                                void slot2(){qDebug() <<  Q_FUNC_INFO;}
                                void slot3(){qDebug() <<  Q_FUNC_INFO;}
                            };
                            

                            Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                            Q: What's that?
                            A: It's blue light.
                            Q: What does it do?
                            A: It turns blue.

                            1 Reply Last reply
                            0

                            • Login

                            • Login or register to search.
                            • First post
                              Last post
                            0
                            • Categories
                            • Recent
                            • Tags
                            • Popular
                            • Users
                            • Groups
                            • Search
                            • Get Qt Extensions
                            • Unsolved