Override Qt slot in subclass

11,817

Solution 1

You don't need to put the same connect in the subclass constructor. When a SubB object is created, the connect in the Base constructor will connect the right slot (the one overridden in SubB).

Solution 2

It gets better: you don't need any special treatment for the slot in the derived class. There's no need to make it virtual (it already is per C++ semantics), and there's no need to make it a slot again (it already is per Qt semantics). It is incorrect to add the second connection in Derived, it'll simply result in the slot being activated twice per every activation of the signal.

Remember that signals and slots are regular C++ methods, and that slots are invoked from machine-generated code that looks exactly as if you called the slot without specifying the particular class it should be in. Thus a virtual slot acts as you think it should, given the semantics of C++.

The below is sufficient:

class Base : public QObject
{
  Q_OBJECT
public:
  Base(QObject * src, QObject * parent = 0) : QObject(parent)
  { connect(src, SIGNAL(mySignal), SLOT(mySlot)); }
  Q_SLOT virtual void mySlot() {}
};

class Derived : public Base
{
  Q_OBJECT
public:
  Derived(QObject * src, QObject * parent = 0) : Base(src, parent) {}
  void mySlot() Q_DECL_OVERRIDE { ... }
};
Share:
11,817

Related videos on Youtube

Simon
Author by

Simon

Programmer coming from HTML via Java and C# to C++ and finally C. SOreadytohelp

Updated on June 14, 2022

Comments

  • Simon
    Simon about 2 years

    I have a base class, which defines a Qt slot

    class Base
    {
    public:
        Base()
        {
            connect(otherobject, SIGNAL(mySignal), this, SLOT(mySlot));
        }
    public slots:
        virtual void mySlot()
        {}
    }
    

    Subclass A just implements some other stuff. Subclass B overrides the slot

    class SubB : Base
    {
    public:
        SubB() : Base() 
        {
            // Necessary?
            connect(otherobject, SIGNAL(mySignal), this, SLOT(mySlot));
        }
    public slots:
        virtual void mySlot() override
        {}
    }
    

    Does the override of the slot also replace the connection, which was done before in the Bass constructor (I.e. The connect in SubB would be unnecessary)?

    • Яois
      Яois over 9 years
      To be 100% correct, don't forget that Base should inherit from QObject and you have to put the Q_OBJECT macro inside both classes ;)
  • Simon
    Simon over 9 years
    That's what I was hoping. Couldn't find anything in the docs.
  • Kuba hasn't forgotten Monica
    Kuba hasn't forgotten Monica over 9 years
    @Simon It'd really help to look at the code generated by moc for the implementation of Base. You can easily see how the slot is called.