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
Forum Updated to NodeBB v4.3 + New Features

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 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 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
      2
      • C ChrisW67

        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 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.

        JonBJ 1 Reply Last reply
        0
        • L Lynix

          @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.

          JonBJ Offline
          JonBJ Offline
          JonB
          wrote on 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
          5
          • JonBJ JonB

            @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 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

            • Login

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