Nyaruko
Nyaruko

Reputation: 4459

What's the purpose of Q_INTERFACES macro?

I am reading other people's code and see this:

class UAVItem:public QObject,public QGraphicsItem
{
    Q_OBJECT
    Q_INTERFACES(QGraphicsItem)
...

But I didn't see they are using any sort of plug-in in this program. Therefore, can I just remove the line:

    Q_INTERFACES(QGraphicsItem)

?

Upvotes: 7

Views: 13747

Answers (2)

Oktalist
Oktalist

Reputation: 14714

If you have a class Derived which inherits from a class Base, which in turn inherits from QObject, and both Derived and Base contain the Q_OBJECT macro, then qobject_cast can be used to safely cast from a pointer (or reference) to Base, to a pointer (or reference) to Derived, similar to dynamic_cast in standard C++ but without RTTI.

If Base does not inherit from QObject, then qobject_cast can still be used in this way, but only if Base has a corresponding Q_DECLARE_INTERFACE macro and Derived contains Q_INTERFACES(Base).

In your case, Q_INTERFACES(QGraphicsItem) being present in UAVItem means that qobject_cast can be used to cast from a pointer (or reference) to QGraphicsItem to a pointer (or reference) to UAVItem, despite QGraphicsItem not inheriting from QObject.

Upvotes: 19

Sazzad Hissain Khan
Sazzad Hissain Khan

Reputation: 40156

From reference doc,

class ToolInterface
{
public:
    virtual QString toolName() const = 0;
};
Q_DECLARE_INTERFACE(ToolInterface, "in.forwardbias.tool/1.0");

// Hammer in hammer.h (our Hammer plugin)
#include "toolinterface.h"
class Hammer : public QObject, public ToolInterface
{
    Q_OBJECT
    Q_INTERFACES(ToolInterface)
public:
    QString toolName() const { return "hammer"; }
};
Q_EXPORT_PLUGIN2(hammer, Hammer);

When moc runs on the hammer.h code, it inspects Q_INTERFACES. It generates code for a function called qt_metacall - void *Hammer::qt_metacast(const char *iname). This goal of this 'casting' function is to return a pointer to an interface depending on iname. moc also verifies whether the interface names that you have put inside Q_INTERFACES have indeed been declared. It can do this by inspecting the header files and looking for a Q_DECLARE_INTERFACE. In our case, there is a Q_DECLARE_INTERFACE inside toolinterface.h.

Upvotes: 3

Related Questions