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. Connect in derived class to base class slot
QtWS25 Last Chance

Connect in derived class to base class slot

Scheduled Pinned Locked Moved Solved General and Desktop
inheritanceslots
5 Posts 3 Posters 2.8k 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.
  • L Offline
    L Offline
    Lynix
    wrote on 25 Jun 2021, 21:06 last edited by
    #1

    Hello,
    I have a class 'mainwindow' that manages all the GUI stuff and a class 'lending_system' that is supposed to do all the behind the scene things. The class mainwindow needs access to a lot of functions and Data of the class lending_system so I've decided to
    let the class mainwindow inherit from lending_systems. I'm not sure if doing that makes any sense but I guess it gives you the ability to manage all the background stuff without being dependent on the GUI. The issue is that I'm trying to connect a button click (defined in the ctor of mainwindow) to a slot inside lending_system but it doesn't seem to find it.

    class lending_system{
        protected:
            QList<medium*> medlist; //saves all medium objects
            QList<person*> perlist; //saves all person objects
        
            void read_medium();     //loads mediums from file into QList
            void read_person();     //loads persons from file into QList
            void write_medium();    //saves mediums from QList into file
            void write_person();    //saves persons from QList into file
        public:
            lending_system();
        protected slots:
            void delete_person(unsigned int id);       //deletes person from list
    };
    
    class mainwindow: public QMainWindow, public Ui::MainWindow, public lending_system{
        Q_OBJECT
        private:
            lending_system lend;
    
            void create_person_table();
    	public:
    		mainwindow(QMainWindow *parent=0);
    		~mainwindow();
    };
    

    In the constructor of the mainwindow class there is the line:

    connect(btn, SIGNAL(clicked()), this, SLOT(delete_person(perlist[i]->get_id())));
    
    

    It compiles fine but when executing i get:

    QObject::connect: No such slot mainwindow::delete_person(perlist[i]->get_id())
    QObject::connect:  (receiver name: 'MainWindow')
    

    I hope my question isn't too dumb, I'm very new to QT.

    Thanks for any help.

    1 Reply Last reply
    0
    • C Offline
      C Offline
      ChrisW67
      wrote on 25 Jun 2021, 22:58 last edited by
      #2

      This is an old-style Qt connect

      connect(btn, SIGNAL(clicked()), this, SLOT(delete_person(perlist[i]->get_id())));
      

      The second and fourth arguments should the function signature of the signal or slot. This establishes a connection between objects, it does not send data, that happens when the signal is emitted.
      This old-style connect should look like:

      connect(btn, SIGNAL(clicked()),  this, SLOT(some_slot_in_your_class()));
      

      and you need to put logic to do something in the slot some_slot_in_your_class() you have yet to define. Note that the signal clicked() does not send a parameter, and the new slot will not receive one, so you need to work out which person to delete some way.

      Had you used new-style connects this would have failed at compile time.

      There are other unusual things about this design:

      • Class lending_system is not a QObject so it will not support signal/slots.
      • Your code is saying that class mainwindow is-a lending_system. Is it really, or does it just know about a lending_system to operate on it?
      • It is very unusual that a Designer generated UI would be publicly inherited, this should normally be private.
      L 1 Reply Last reply 26 Jun 2021, 01:15
      2
      • C ChrisW67
        25 Jun 2021, 22:58

        This is an old-style Qt connect

        connect(btn, SIGNAL(clicked()), this, SLOT(delete_person(perlist[i]->get_id())));
        

        The second and fourth arguments should the function signature of the signal or slot. This establishes a connection between objects, it does not send data, that happens when the signal is emitted.
        This old-style connect should look like:

        connect(btn, SIGNAL(clicked()),  this, SLOT(some_slot_in_your_class()));
        

        and you need to put logic to do something in the slot some_slot_in_your_class() you have yet to define. Note that the signal clicked() does not send a parameter, and the new slot will not receive one, so you need to work out which person to delete some way.

        Had you used new-style connects this would have failed at compile time.

        There are other unusual things about this design:

        • Class lending_system is not a QObject so it will not support signal/slots.
        • Your code is saying that class mainwindow is-a lending_system. Is it really, or does it just know about a lending_system to operate on it?
        • It is very unusual that a Designer generated UI would be publicly inherited, this should normally be private.
        L Offline
        L Offline
        Lynix
        wrote on 26 Jun 2021, 01:15 last edited by
        #3

        @ChrisW67
        Thank you very much for your answer.
        I misunderstood how slots work I thought it was just like a normal function.

        "Your code is saying that class mainwindow is-a lending_system. Is it really, or does it just know about a lending_system to operate on it?"

        mainwindow is something different from lending_system. I inherited it from lending_system just to be able to use all functions and also protected contents of lending_system without having to explicitly create a lending_system object. I realize that this
        doesn't make a lot of sense and is not how inheritance should be used. I could either put everything in mainwindow or create an object of lending_system inside mainwindow and just work with that. I think I will do the latter one. About that, I have a c++ question. In mainwindow I would have to access a Qlist that is inside the lending_system object. I could do that in 3 ways and I'm not sure what the best or standard way is.

        • write a getter function get_list_at(i) that just does return list[i] and another getter function for the list size
        • write a getter function that returns a pointer to the list which would allow me to directly work on it using [i] and .size()
        • make the list public
          Which one should I pick?

        "It is very unusual that a Designer generated UI would be publicly inherited, this should normally be private."
        Thanks for pointing that out. I followed a pretty old pdf to get started and just used the example to get started. I'm not sure why they did it that way.

        I just found out about QSignalMapper. I think that would be the best way to tell the delete function which entry to delete.

        I will check out the new-style connects.

        Thank you for your help.

        J 1 Reply Last reply 26 Jun 2021, 07:58
        0
        • L Lynix
          26 Jun 2021, 01:15

          @ChrisW67
          Thank you very much for your answer.
          I misunderstood how slots work I thought it was just like a normal function.

          "Your code is saying that class mainwindow is-a lending_system. Is it really, or does it just know about a lending_system to operate on it?"

          mainwindow is something different from lending_system. I inherited it from lending_system just to be able to use all functions and also protected contents of lending_system without having to explicitly create a lending_system object. I realize that this
          doesn't make a lot of sense and is not how inheritance should be used. I could either put everything in mainwindow or create an object of lending_system inside mainwindow and just work with that. I think I will do the latter one. About that, I have a c++ question. In mainwindow I would have to access a Qlist that is inside the lending_system object. I could do that in 3 ways and I'm not sure what the best or standard way is.

          • write a getter function get_list_at(i) that just does return list[i] and another getter function for the list size
          • write a getter function that returns a pointer to the list which would allow me to directly work on it using [i] and .size()
          • make the list public
            Which one should I pick?

          "It is very unusual that a Designer generated UI would be publicly inherited, this should normally be private."
          Thanks for pointing that out. I followed a pretty old pdf to get started and just used the example to get started. I'm not sure why they did it that way.

          I just found out about QSignalMapper. I think that would be the best way to tell the delete function which entry to delete.

          I will check out the new-style connects.

          Thank you for your help.

          J Offline
          J Offline
          JonB
          wrote on 26 Jun 2021, 07:58 last edited by
          #4

          @Lynix
          If you change over to new style connect()s, a further advantage is that you can use C++ lambdas for slots. They allow you to write the slot code you showed "in-line". They also allow passing parameters from the calling code to the slot. So your example might read something like:

          connect(btn, &QPushButton::clicked,
                  this, [this, i]() { delete_person(perlist[i]->get_id()); });
          

          Once you use lambdas to pass parameters the need for QSignalMapper disappears. That is much more limited in what you can pass/do than lambdas, and there is simply little point in using it these days as lambdas can do everything it does plus a variety of other things.

          L 1 Reply Last reply 26 Jun 2021, 13:46
          5
          • J JonB
            26 Jun 2021, 07:58

            @Lynix
            If you change over to new style connect()s, a further advantage is that you can use C++ lambdas for slots. They allow you to write the slot code you showed "in-line". They also allow passing parameters from the calling code to the slot. So your example might read something like:

            connect(btn, &QPushButton::clicked,
                    this, [this, i]() { delete_person(perlist[i]->get_id()); });
            

            Once you use lambdas to pass parameters the need for QSignalMapper disappears. That is much more limited in what you can pass/do than lambdas, and there is simply little point in using it these days as lambdas can do everything it does plus a variety of other things.

            L Offline
            L Offline
            Lynix
            wrote on 26 Jun 2021, 13:46 last edited by
            #5

            @JonB
            Thanks, that worked perfectly.

            Also, I've decided to write a getter that returns a const reference to the list which also
            works perfectly.

            1 Reply Last reply
            0

            5/5

            26 Jun 2021, 13:46

            • Login

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