Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Override Qt slot in subclass

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)?

like image 340
Simon Avatar asked Mar 20 '15 15:03

Simon


People also ask

Can slot be virtual?

Yes, just like regular c++ pure virtual methods. The code generated by MOC does call the pure virtual slots, but that's ok since the base class can't be instantiated anyway... Again, just like regular c++ pure virtual methods, the class cannot be instantiated until the methods are given an implementation.

What is private slots in Qt?

Slots are a Qt-specific extension of C++. It only compiles after sending the code through Qt's preprocessor, the Meta-Object Compiler (moc). See http://doc.qt.io/qt-5/moc.html for documentation.

How does Qt signal slot work?

In Qt, we have an alternative to the callback technique: We use signals and slots. A signal is emitted when a particular event occurs. Qt's widgets have many predefined signals, but we can always subclass widgets to add our own signals to them. A slot is a function that is called in response to a particular signal.


2 Answers

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 { ... }
};
like image 142
Kuba hasn't forgotten Monica Avatar answered Sep 21 '22 08:09

Kuba hasn't forgotten Monica


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

like image 23
Яois Avatar answered Sep 20 '22 08:09

Яois