Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. (Ab)using abstract classes for ID system for QWidgets

(Ab)using abstract classes for ID system for QWidgets

Scheduled Pinned Locked Moved Solved General and Desktop
11 Posts 6 Posters 632 Views 2 Watching
  • 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.
  • B Offline
    B Offline
    Binary91 0
    wrote on last edited by Binary91 0
    #1

    Hi,

    for my current and for further Qt projects, I'm developing an ID system for better identifying the origin of signals of my QWidgets and other QObjects.

    The system consists of an ID class that can hold an individual ID (QVariant) as well as a "group ID" (integer).
    The sense of the group ID is that it can be shared and updated automatically. This is realized by a second class "IDList" that holds a QVector<int*>.

    Well, the ID system should manage its IDs by itsself without any further need to ensure appending/inserting/removing IDs. To ensure this, I'd like to have the private sector of those two classes "unaccessable". Well, I could now tell other users only to inherit from those base classes so it is ensured that the private data is safe, but there would still be the possibility to accidentally create a base class object. A second problem is that I'd like to define the ID base class as a friend of the IDList class (a second reason why it is so important not to accidentally directly use one of those classes).

    Well, my idea was now to make those base classes abstract by declaring a non-sense pure virtual function inside it. By doing so, inheritance and total restriction of the private sector is ensured (as far as other users wont willfully cast the object), right?

    Is this good programming style? Or is it maybe completely senseless?

    Thank you for your opinions.

    jsulmJ 1 Reply Last reply
    0
    • B Binary91 0

      Hi,

      for my current and for further Qt projects, I'm developing an ID system for better identifying the origin of signals of my QWidgets and other QObjects.

      The system consists of an ID class that can hold an individual ID (QVariant) as well as a "group ID" (integer).
      The sense of the group ID is that it can be shared and updated automatically. This is realized by a second class "IDList" that holds a QVector<int*>.

      Well, the ID system should manage its IDs by itsself without any further need to ensure appending/inserting/removing IDs. To ensure this, I'd like to have the private sector of those two classes "unaccessable". Well, I could now tell other users only to inherit from those base classes so it is ensured that the private data is safe, but there would still be the possibility to accidentally create a base class object. A second problem is that I'd like to define the ID base class as a friend of the IDList class (a second reason why it is so important not to accidentally directly use one of those classes).

      Well, my idea was now to make those base classes abstract by declaring a non-sense pure virtual function inside it. By doing so, inheritance and total restriction of the private sector is ensured (as far as other users wont willfully cast the object), right?

      Is this good programming style? Or is it maybe completely senseless?

      Thank you for your opinions.

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

      @Binary91-0 said in (Ab)using abstract classes for ID system for QWidgets:

      I'm developing an ID system for better identifying the origin of signals of my QWidgets and other QObjects

      I'm wondering why you need this?

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

      B 1 Reply Last reply
      1
      • jsulmJ jsulm

        @Binary91-0 said in (Ab)using abstract classes for ID system for QWidgets:

        I'm developing an ID system for better identifying the origin of signals of my QWidgets and other QObjects

        I'm wondering why you need this?

        B Offline
        B Offline
        Binary91 0
        wrote on last edited by Binary91 0
        #3

        @jsulm For example to identify a specific button of a group with a shared slot. I like it better to identify the buttons by a specific ID than by its (sometimes variable) buttonText.
        But beside the need of this, is this coding style good or bad or something between?

        JonBJ jsulmJ 2 Replies Last reply
        0
        • B Binary91 0

          @jsulm For example to identify a specific button of a group with a shared slot. I like it better to identify the buttons by a specific ID than by its (sometimes variable) buttonText.
          But beside the need of this, is this coding style good or bad or something between?

          JonBJ Offline
          JonBJ Offline
          JonB
          wrote on last edited by JonB
          #4

          @Binary91-0 said in (Ab)using abstract classes for ID system for QWidgets:

          @jsulm For example to identify a specific button of a group with a shared slot.

          Although you can do signal/slots this way, or even use QSignalMapper, the easier way these days is to connect your signals to lambdas which pass the necessary identifying number (or even the widget) as parameter of the sender to the slot.

          EDIT @jsulm has shown you the code for just this in his response below.

          1 Reply Last reply
          1
          • B Binary91 0

            @jsulm For example to identify a specific button of a group with a shared slot. I like it better to identify the buttons by a specific ID than by its (sometimes variable) buttonText.
            But beside the need of this, is this coding style good or bad or something between?

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

            @Binary91-0 You can use lambdas for that and pass the pointer to the calling widget as parameter to the slot:

            QPushButton *button = ui->button1;
            connect(button, &QPushButton::clicked, [button, this]() { // do something with button});
            

            There is really no point in implementing heavy ID solution.

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

            1 Reply Last reply
            4
            • Chris KawaC Offline
              Chris KawaC Offline
              Chris Kawa
              Lifetime Qt Champion
              wrote on last edited by
              #6

              As others pointed out there's usually no need for and ID system but if you want a simple one you can just use custom QObject properties without any special classes:

              some_button->setProperty("id", 42);
              some_button->setProperty("id_group", "some_group");
              

              If you really want to you can add some "manager" class to set those or do things like rename group or find its members, but I wouldn't add a special class with special requirements that users need to inherit from. That's a little much for just an id.

              As for friends - remember that "friend is your enemy" :) It hides unexpected dependencies really well and leads to awful problems in complex systems.

              1 Reply Last reply
              4
              • SGaistS Offline
                SGaistS Offline
                SGaist
                Lifetime Qt Champion
                wrote on last edited by
                #7

                Hi,

                In addition to my fellow, there's something already available: the objectName property.

                Interested in AI ? www.idiap.ch
                Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                1 Reply Last reply
                2
                • B Offline
                  B Offline
                  Binary91 0
                  wrote on last edited by Binary91 0
                  #8

                  Well, at first, thank you really much for all those suggestions! I see, I'm neighter well informed about QObject's already existing functionallity (setProperty, objectName), nor do I know how to easy and well-performend handle Qt's events.

                  I heard about lambdas sometimes, but to be honest, I don't know anything about this stuff. I started learning it know, and from one point to another point and from there to another point, I'm walking through function pointers, functors and currently I'm in template systems. Maybe this will help me understanding basic C++ functionallity better.
                  I also see know, that my method to connect SIGNALS and SLOTS is obsolete and the new way of doing this is by passing function pointers (again a reason to get used to that stuff I think..). What I (till now) still not know is how the example above from jsulm works, as far as it connects SIGNAL to SLOT by passing 3 instead of normally 4 parameters. But maybe I will get that after I understand how to use lambdas..

                  JonBJ 1 Reply Last reply
                  0
                  • B Binary91 0

                    Well, at first, thank you really much for all those suggestions! I see, I'm neighter well informed about QObject's already existing functionallity (setProperty, objectName), nor do I know how to easy and well-performend handle Qt's events.

                    I heard about lambdas sometimes, but to be honest, I don't know anything about this stuff. I started learning it know, and from one point to another point and from there to another point, I'm walking through function pointers, functors and currently I'm in template systems. Maybe this will help me understanding basic C++ functionallity better.
                    I also see know, that my method to connect SIGNALS and SLOTS is obsolete and the new way of doing this is by passing function pointers (again a reason to get used to that stuff I think..). What I (till now) still not know is how the example above from jsulm works, as far as it connects SIGNAL to SLOT by passing 3 instead of normally 4 parameters. But maybe I will get that after I understand how to use lambdas..

                    JonBJ Offline
                    JonBJ Offline
                    JonB
                    wrote on last edited by
                    #9

                    @Binary91-0
                    All of signals/slots/lambdas is covered with little examples in https://doc.qt.io/qt-5/signalsandslots.html. It's not easy reading for a beginner, but is worth working through a couple of times while you get the hang of what's going on.

                    1 Reply Last reply
                    1
                    • VRoninV Offline
                      VRoninV Offline
                      VRonin
                      wrote on last edited by VRonin
                      #10
                      • if you use SIGNAL() and SLOT() stile of connection (you shouldn't), you can call sender() in the slot to get a pointer to the object that emitted the signal
                      • if you are using the new connection you can just add an argument to the slot that takes a pointer to the sender, for example:
                      class Receiver : public QObject{
                      Q_OBJECT
                      Q_DISABLE_COPY_MOVE(Receiver)
                      public:
                      explicit Receiver(QObject* parent = nullptr) : QObject(parent) {}
                      public slots:
                      void doSomething(int value, QObject* sender);
                      };
                      

                      then you can connect using:

                      connect(emitter1, &Emitter::someSignal, myReceiver, std::bind(&Receiver::doSomething,myReceiver,emitter1));
                      connect(emitter2, &Emitter::someSignal, myReceiver, std::bind(&Receiver::doSomething,myReceiver,emitter2));
                      // etc
                      
                      • if you just need this tracing for debug purposes you can just use GammaRay

                      "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

                      1 Reply Last reply
                      2
                      • B Offline
                        B Offline
                        Binary91 0
                        wrote on last edited by
                        #11

                        Hi again,

                        it took some time for me reading all the stuff about function pointers, functors (and lambdas) as well as virtual functions, templates and the std function type.

                        Now I think I did understand the basic about that all and since I understood that lambdas are "converted into functors" or, if no capturing is specified, treated as function pointers, I also understand how they are handled in the QObject::connect system.

                        The way I'm doing my connections now is just defining a lambda that calls an individual method with individual captured parameters, mostly a pointer to sender itsself, like this:

                        connect(this->pbSomeButton, &QPushButton::clicked, this, [this]() -> void {this->privatePropertyClass->DoSomethingSpecial(this);});
                        

                        This way gives me the benefit of calling private Properties of the sender object. By solving this via QObject::sender() inside the slot, I could not call private members of it so I think the lambda solution is pretty nice, I like it! The second benefit is that I am totally free what method I'm calling, I don't need to define specific slot methods with equal signature to the signal methods.

                        Thank you all for your help, great job!

                        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