Qt Forum

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Unsolved

    Solved Connect in derived class to base class slot

    General and Desktop
    inheritance slots
    3
    5
    1498
    Loading More Posts
    • 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
      Lynix last edited by

      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 Reply Quote 0
      • C
        ChrisW67 last edited by

        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 Reply Quote 2
        • L
          Lynix @ChrisW67 last edited by

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

          JonB 1 Reply Last reply Reply Quote 0
          • JonB
            JonB @Lynix last edited by

            @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 Reply Quote 5
            • L
              Lynix @JonB last edited by

              @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 Reply Quote 0
              • First post
                Last post