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. Signals, slots, a vector of objects and their holy mother
Forum Updated to NodeBB v4.3 + New Features

Signals, slots, a vector of objects and their holy mother

Scheduled Pinned Locked Moved Solved General and Desktop
12 Posts 3 Posters 3.6k Views 1 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.
  • alexRHTA Offline
    alexRHTA Offline
    alexRHT
    wrote on last edited by alexRHT
    #1

    Hi there,
    This is going to be my first post so I hope I explain myself correctly. I have been using Qt and OOP for a short time so please forgive my inexperience.

    So, there is something I want to accomplish and for the moment I am not being able. I will write a simple example related to my problem to simplify things:

    1 - I have created a class "Dog" which looks like this:

    class Dog: public QObject
    {
        Q_OBJECT
    public:
        Dog();
        ~Dog();
        int getID();
    public slots:
        void setName(QString name);
        void setID(int id);
        void setAlive(bool living);
    private:
        // Attributes
        int ID;
        QString name;
        bool isItAlive;
    };
    

    2 - I have a UI with a ComboBox, a TextEdit and a CheckButton. When I create the UI, there is a list of an unknown number of IDs (idNumber) listed in the ComboBox as a result of this code:

    Dog *dogs = new Dog[idNumber]();
    for (int i = 0; i < idNumber; ++i)
    {
         dogs[i].setID(i);
         ui->idComboBox->addItem(QString::number(dogs[i].getID());
    }
    

    The idea is to update the attributes of each dog (name and isItAlive) using the ComboBox to select the specific dog to get its information updated, and the TextEdit and the CheckBox for the contents of said attributes. Every time the EditText is changed or the CheckBox is toggled, a signal should have to be emitted so the specific dog (identified by the ID selected in the ComboBox at the time of the change) gets its corresponding name and status.

    3 - I create in the MainWindow.cpp a connection between (for instance) the CheckBox and the Dog class:

    connect(ui->aliveCheckBox, SIGNAL(toggled(bool)), dogs, SLOT(setAlive(bool)));
    

    The connection seems to be OK but... How do I say which dog gets updated from the dogs array? How do I pass the content of the TextEdit as a parameter of the signal so the slot can update the corresponding attribute of the specific dog?

    Maybe using signals and slots is not the best way to deal with this problem, but I want to avoid declaring dogs as global (which would solve all my problems as I could access it everywhere). Thank you very much in advance for your wisdom and help.

    raven-worxR jsulmJ 2 Replies Last reply
    0
    • alexRHTA alexRHT

      Hi there,
      This is going to be my first post so I hope I explain myself correctly. I have been using Qt and OOP for a short time so please forgive my inexperience.

      So, there is something I want to accomplish and for the moment I am not being able. I will write a simple example related to my problem to simplify things:

      1 - I have created a class "Dog" which looks like this:

      class Dog: public QObject
      {
          Q_OBJECT
      public:
          Dog();
          ~Dog();
          int getID();
      public slots:
          void setName(QString name);
          void setID(int id);
          void setAlive(bool living);
      private:
          // Attributes
          int ID;
          QString name;
          bool isItAlive;
      };
      

      2 - I have a UI with a ComboBox, a TextEdit and a CheckButton. When I create the UI, there is a list of an unknown number of IDs (idNumber) listed in the ComboBox as a result of this code:

      Dog *dogs = new Dog[idNumber]();
      for (int i = 0; i < idNumber; ++i)
      {
           dogs[i].setID(i);
           ui->idComboBox->addItem(QString::number(dogs[i].getID());
      }
      

      The idea is to update the attributes of each dog (name and isItAlive) using the ComboBox to select the specific dog to get its information updated, and the TextEdit and the CheckBox for the contents of said attributes. Every time the EditText is changed or the CheckBox is toggled, a signal should have to be emitted so the specific dog (identified by the ID selected in the ComboBox at the time of the change) gets its corresponding name and status.

      3 - I create in the MainWindow.cpp a connection between (for instance) the CheckBox and the Dog class:

      connect(ui->aliveCheckBox, SIGNAL(toggled(bool)), dogs, SLOT(setAlive(bool)));
      

      The connection seems to be OK but... How do I say which dog gets updated from the dogs array? How do I pass the content of the TextEdit as a parameter of the signal so the slot can update the corresponding attribute of the specific dog?

      Maybe using signals and slots is not the best way to deal with this problem, but I want to avoid declaring dogs as global (which would solve all my problems as I could access it everywhere). Thank you very much in advance for your wisdom and help.

      raven-worxR Offline
      raven-worxR Offline
      raven-worx
      Moderators
      wrote on last edited by raven-worx
      #2

      @alexRHT
      QSignalMapper may help you here.

      But the simplest solution would be to connect to a onDataChanged() slot and in there you get the currently selected dog and update it with the current data of your checkbox and textedit.

      --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
      If you have a question please use the forum so others can benefit from the solution in the future

      alexRHTA 1 Reply Last reply
      2
      • alexRHTA alexRHT

        Hi there,
        This is going to be my first post so I hope I explain myself correctly. I have been using Qt and OOP for a short time so please forgive my inexperience.

        So, there is something I want to accomplish and for the moment I am not being able. I will write a simple example related to my problem to simplify things:

        1 - I have created a class "Dog" which looks like this:

        class Dog: public QObject
        {
            Q_OBJECT
        public:
            Dog();
            ~Dog();
            int getID();
        public slots:
            void setName(QString name);
            void setID(int id);
            void setAlive(bool living);
        private:
            // Attributes
            int ID;
            QString name;
            bool isItAlive;
        };
        

        2 - I have a UI with a ComboBox, a TextEdit and a CheckButton. When I create the UI, there is a list of an unknown number of IDs (idNumber) listed in the ComboBox as a result of this code:

        Dog *dogs = new Dog[idNumber]();
        for (int i = 0; i < idNumber; ++i)
        {
             dogs[i].setID(i);
             ui->idComboBox->addItem(QString::number(dogs[i].getID());
        }
        

        The idea is to update the attributes of each dog (name and isItAlive) using the ComboBox to select the specific dog to get its information updated, and the TextEdit and the CheckBox for the contents of said attributes. Every time the EditText is changed or the CheckBox is toggled, a signal should have to be emitted so the specific dog (identified by the ID selected in the ComboBox at the time of the change) gets its corresponding name and status.

        3 - I create in the MainWindow.cpp a connection between (for instance) the CheckBox and the Dog class:

        connect(ui->aliveCheckBox, SIGNAL(toggled(bool)), dogs, SLOT(setAlive(bool)));
        

        The connection seems to be OK but... How do I say which dog gets updated from the dogs array? How do I pass the content of the TextEdit as a parameter of the signal so the slot can update the corresponding attribute of the specific dog?

        Maybe using signals and slots is not the best way to deal with this problem, but I want to avoid declaring dogs as global (which would solve all my problems as I could access it everywhere). Thank you very much in advance for your wisdom and help.

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

        @alexRHT In the combobox you select one specific dog, right? This way you know which one to modify. You should not connect the toggled(bool) signal to the vector or a dog, but to a slot in your MainWindow. In that slot you get the currently selected dog and modify it. No need to pass content of the TextEdit - you can get it in the slot I mentioned above.

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

        alexRHTA 1 Reply Last reply
        2
        • jsulmJ jsulm

          @alexRHT In the combobox you select one specific dog, right? This way you know which one to modify. You should not connect the toggled(bool) signal to the vector or a dog, but to a slot in your MainWindow. In that slot you get the currently selected dog and modify it. No need to pass content of the TextEdit - you can get it in the slot I mentioned above.

          alexRHTA Offline
          alexRHTA Offline
          alexRHT
          wrote on last edited by
          #4

          @jsulm Ok, let me see if I have understood. What I would do is to detect that any change has been made on any of my UI elements and have a slot in my MainWindow to deal with changes. Inside this slot I get the ui->Whatever->getText or isChecked and even the ComboBox->currentIndex. But, how do I pass to this slot the dogs pointer so I can access to the 'currentIndex' dog? I'm sorry if this is too obvious...

          jsulmJ 1 Reply Last reply
          0
          • raven-worxR raven-worx

            @alexRHT
            QSignalMapper may help you here.

            But the simplest solution would be to connect to a onDataChanged() slot and in there you get the currently selected dog and update it with the current data of your checkbox and textedit.

            alexRHTA Offline
            alexRHTA Offline
            alexRHT
            wrote on last edited by
            #5

            @raven-worx I will investigate the QSignalMapper option too. Thanks!

            1 Reply Last reply
            0
            • alexRHTA alexRHT

              @jsulm Ok, let me see if I have understood. What I would do is to detect that any change has been made on any of my UI elements and have a slot in my MainWindow to deal with changes. Inside this slot I get the ui->Whatever->getText or isChecked and even the ComboBox->currentIndex. But, how do I pass to this slot the dogs pointer so I can access to the 'currentIndex' dog? I'm sorry if this is too obvious...

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

              @alexRHT You do not pass the dog pointer to the slots - you find the current dog in the slot. In that slot you do it like this (dog is the currently selected one):

              Dog *dog = &Dogs[ui->idComboBox->currentIndex()];
              dog->setName(name);
              dog->setID(id);
              dog->setAlive(living);
              

              You can use the selected item index from the combobox to access the dog from your vector.

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

              alexRHTA 1 Reply Last reply
              1
              • jsulmJ jsulm

                @alexRHT You do not pass the dog pointer to the slots - you find the current dog in the slot. In that slot you do it like this (dog is the currently selected one):

                Dog *dog = &Dogs[ui->idComboBox->currentIndex()];
                dog->setName(name);
                dog->setID(id);
                dog->setAlive(living);
                

                You can use the selected item index from the combobox to access the dog from your vector.

                alexRHTA Offline
                alexRHTA Offline
                alexRHT
                wrote on last edited by alexRHT
                #7

                @jsulm It looked promising but it did not compile as I implemented it. So, I understand that you are here creating a temporary pointer which is pointing to the currentIndex() index of my previously created *dogs vector? Inside the slot I have no access to *dogs so... I feel dumb

                jsulmJ 2 Replies Last reply
                0
                • alexRHTA alexRHT

                  @jsulm It looked promising but it did not compile as I implemented it. So, I understand that you are here creating a temporary pointer which is pointing to the currentIndex() index of my previously created *dogs vector? Inside the slot I have no access to *dogs so... I feel dumb

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

                  @alexRHT Without your code I have no idea what is wrong.
                  Where did you define your dogs array/vector? You should have it somewhere.

                  Yes the pointer points to the dog which is stored at currentIndex() position in your dogs array/vector.

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

                  alexRHTA 1 Reply Last reply
                  0
                  • alexRHTA alexRHT

                    @jsulm It looked promising but it did not compile as I implemented it. So, I understand that you are here creating a temporary pointer which is pointing to the currentIndex() index of my previously created *dogs vector? Inside the slot I have no access to *dogs so... I feel dumb

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

                    @alexRHT Actually it shouldn't be a pointer. This should work as well:

                    Dog &dog = Dogs[ui->idComboBox->currentIndex()];
                    dog.setName(name);
                    dog.setID(id);
                    dog.setAlive(living);
                    

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

                    1 Reply Last reply
                    0
                    • jsulmJ jsulm

                      @alexRHT Without your code I have no idea what is wrong.
                      Where did you define your dogs array/vector? You should have it somewhere.

                      Yes the pointer points to the dog which is stored at currentIndex() position in your dogs array/vector.

                      alexRHTA Offline
                      alexRHTA Offline
                      alexRHT
                      wrote on last edited by
                      #10

                      @jsulm said:

                      @alexRHT Without your code I have no idea what is wrong.
                      Where did you define your dogs array/vector? You should have it somewhere.

                      My dogs array/vector is defined at the constructor of MainWindow.cpp, where I also define the texts and states of the elements of the UI. The line of code that creates this array/vector is the one I posted previously:

                      Dog *dogs = new Dog[idNumber]();  //idNumber is extracted from the number of lines of an external .txt file
                      

                      Isn't this the way to declare the array? Maybe I failed here...
                      The thing is that the SLOT is a public method of MainWindow and, unless I declare *dogs as global or pass it as a parameter to the SLOT function, I don't have access to it. Am I mistaken?

                      jsulmJ 1 Reply Last reply
                      0
                      • alexRHTA alexRHT

                        @jsulm said:

                        @alexRHT Without your code I have no idea what is wrong.
                        Where did you define your dogs array/vector? You should have it somewhere.

                        My dogs array/vector is defined at the constructor of MainWindow.cpp, where I also define the texts and states of the elements of the UI. The line of code that creates this array/vector is the one I posted previously:

                        Dog *dogs = new Dog[idNumber]();  //idNumber is extracted from the number of lines of an external .txt file
                        

                        Isn't this the way to declare the array? Maybe I failed here...
                        The thing is that the SLOT is a public method of MainWindow and, unless I declare *dogs as global or pass it as a parameter to the SLOT function, I don't have access to it. Am I mistaken?

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

                        @alexRHT If you define dogs in constructor then it will only exist inside the constructor!
                        You have to put it in your class as private field.

                        class MyClass: public QMainWindow
                        {
                        public slots:
                            void mySlot();
                        
                        private:
                            Dogs *dogs;
                        };
                        
                        MyClass::MyClass()
                        {
                            dogs = new Dog[idNumber];
                        }
                        
                        void MyClass::mySlot()
                        {
                            Dog &dog = dogs[ui->idComboBox->currentIndex()];
                            dog.setName(name);
                            dog.setID(id);
                            dog.setAlive(living);
                        }
                        

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

                        alexRHTA 1 Reply Last reply
                        1
                        • jsulmJ jsulm

                          @alexRHT If you define dogs in constructor then it will only exist inside the constructor!
                          You have to put it in your class as private field.

                          class MyClass: public QMainWindow
                          {
                          public slots:
                              void mySlot();
                          
                          private:
                              Dogs *dogs;
                          };
                          
                          MyClass::MyClass()
                          {
                              dogs = new Dog[idNumber];
                          }
                          
                          void MyClass::mySlot()
                          {
                              Dog &dog = dogs[ui->idComboBox->currentIndex()];
                              dog.setName(name);
                              dog.setID(id);
                              dog.setAlive(living);
                          }
                          
                          alexRHTA Offline
                          alexRHTA Offline
                          alexRHT
                          wrote on last edited by
                          #12

                          @jsulm Newbie's mistake. Now it compiled!! Thanks for your patience and help.

                          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