Connect QT Signals declared in interface
Asked Answered
L

2

9

Is there any way to use Qt5 style Signal & Slot connection if the signals are declared in interfaces ?.

My Interfaces:

class IMyInterfaces{
protected:
    IMyInterfaces() {} //Prohibit instantiate interfaces
public:
    virtual ~IMyInterfaces(){} 

signals:
    virtual void notify_signal() =0;
};
Q_DECLARE_INTERFACE(IMyInterfaces, "IMyInterfaces");

And a class which implements above interfaces:

class MyClass : public QObject, public IMyInterfaces{
    Q_OBJECT
    Q_INTERFACES(IMyInterfaces) //Indicates interface implements
public:
    MyClass():QObject(){
    }
    ~MyClass(){}

signals:
     void notify_signal();
};

In main program I would like to do something like this:

IMyInterfaces * myObject = new MyClass();
//Connect signal using Qt5 style (This will introduce compilation errors)
connect(myObject ,&IMyInterfaces::notify_signal, otherObject, &OtherClass::aSlot);

The old style works but requires to cast to QObject:

QObject::connect(dynamic_cast<QObject *>(m),SIGNAL(notify_signal()),other,SLOT(aSlot())); //This works but need to cast to QObject. 
Lowis answered 30/9, 2015 at 22:41 Comment(2)
virtual signal makes no sense to me as long as the signal has no implementation. Just declare a signal at parent.Separates
Did you find any solution for this?Burgas
M
2

You can declare your signal in the interface as non-virtual. Since the signal won't be implemented by any class that fulfils the interface anyway this will be fine. For example:

Your interface could look like this

#include <QObject>

class IMyInterfaces : public QObject
{
    Q_OBJECT
public:
    virtual ~IMyInterfaces() {}
    virtual void TestNotify() = 0;

signals:
    void notify_signal();
};

Your class that implements the interface would look like this:

Header

#include "imyinterfaces.h"

class MyClass : public IMyInterfaces
{
    Q_OBJECT
public:
    MyClass();
    ~MyClass();
    void TestNotify();
};

Source

#include "myclass.h"

MyClass::MyClass()
{
    // Constructor stuff placed here etc.
}

MyClass::~MyClass()
{
    // Cleanup placed here etc.
}

void MyClass::TestNotify()
{
    emit notify_signal(); // This signal has been inherited from the interface
}

You would then set up the notify signal as so:

IMyInterfaces *myObject = new MyClass();
connect(myObject, &IMyInterfaces::notify_signal, this, &MainWindow::notify_signal);

myObject->TestNotify();

It sounds like the answer from Aurel Branzeanu suggests this implementation but I thought it would help to see an example.

Marthamarthe answered 9/6, 2021 at 15:43 Comment(0)
A
0

Signals could not be virtual. Could be declared in interfaces without virtual clause and should be inherited by lower classes.

Anhydride answered 1/10, 2015 at 21:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.