dimanche 28 août 2016

Using object type of interface class to connect virtual signal

As a follow up question to Connection of pure virtual signal of interface class I would like to know how I can connect a signal of an interface class by using the deduced type of that base class at construction, not the one of the derived class. This would be usefull when iteration over a collection of base class objects (see example in cpp file)

When I try to connect object of AnimalInterface * dog2 = new Dog; there is the error qt_metacall is not a member of 'AnimalInterface' and static assertion failed: No Q_OBJECT in the class with the signal.

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

class AnimalInterface{
public:
    virtual ~AnimalInterface();

    virtual void makeSound() = 0;

/*signals*/
    virtual void madeSound() = 0;
};
Q_DECLARE_INTERFACE(AnimalInterface,"interface")




class Dog : public QObject, public AnimalInterface
{
    Q_OBJECT
    Q_INTERFACES(AnimalInterface)
public:
    void makeSound();
signals:
    void madeSound();
};




class Widget : public QWidget
{
    Q_OBJECT
    Dog *dog_;
public:
    Widget(QWidget *parent = 0);
    ~Widget();

    template< class T,
              typename =
                typename std::enable_if<std::is_base_of<AnimalInterface, T>::value>::type >
    void listenToAnimal(T * animal) {
      connect(animal, &T::madeSound, this, []{ qDebug() << "animal made sound"; });
    }
};

cpp:

Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
    dog_ = new Dog;
    AnimalInterface *dog2 = new Dog;

    listenToAnimal(dog_);
    listenToAnimal(dog2); // Error: qt_metacall is not a member of 'AnimalInterface'

    dog_->makeSound();
    dog2->makeSound();
}

Aucun commentaire:

Enregistrer un commentaire