PDA

View Full Version : Runtime dynamic linking + Qt4 problem



_Ramirez_
10th February 2006, 22:11
I have abstract class Interface with one pure virtual method

void Method(QMenuBar *menuBar, QWidget *parent = 0) const = 0;

I inherit this class with my plugin class. This method should add one QMenu widget to QMenuBar of app that loads plugin. App that is loadin my plugin inherits QMainWindow. I can load the plugin and call this method and it adds one menu item, but the problem is when I try to connect it with slot.

1. I have no idea where to put Q_OBJECT, in Interface or in Plugin or boath?
2. Does my class have to inherit QObject to be able to use signals and slots and wich one?

jacek
10th February 2006, 22:28
1. I have no idea where to put Q_OBJECT, in Interface or in Plugin or boath?
You have put Q_OBJECT in every class in which you define new signals, slots or properties. If you want to use meta data (for example through QMetaObject) or you have a widget plugin, you will need Q_OBJECT too.

Also sprach Assistant:
Notice that the Q_OBJECT macro is mandatory for any object that implements signals, slots or properties. You also need to run the Meta Object Compiler on the source file. We strongly recommend the use of this macro in all subclasses of QObject regardless of whether or not they actually use signals, slots and properties, since failure to do so may lead certain functions to exhibit strange behavior


2. Does my class have to inherit QObject to be able to use signals and slots and wich one?
You will probably want to be able to cast your interface to QObject *, so you could use it for example in the connect statement. In such case it must inherit QObject.

_Ramirez_
10th February 2006, 22:56
class Interface
{
public:
Interface() {}
virtual ~Interface() {}

virtual void Method(QMenuBar* menuBar, QWidget* parent = 0) const = 0;
};


class Plugin : public Interface
{
Q_OBJECT

public:
Plugin();
~Plugin();

void Method(QMenuBar* menuBar, QWidget* parent = 0) const;
private slots:
void TestSlot();
};


void Plugin::Method(QMenuBar* menuBar, QWidget* parent) const
{
QAction *pluginAction = new QAction(tr("SomeText"), parent);
connect(pluginAction, SIGNAL(triggered()), parent, SLOT(TestSlot()));
QMenu *pluginMenu = new QMenu(tr("Plugin"));
pluginMenu->addAction(pluginAction);

menuBar->addMenu(pluginMenu);
}

I want to use slots in my Plugin so I've added Q_OBJECT but I get these errors:

error C2039: 'staticMetaObject' : is not a member of 'Interface'
error C2039: 'qt_metacast' : is not a member of 'Interface'
error C2039: 'qt_metacall' : is not a member of 'Interface'
error C3861: 'connect': identifier not found

My .pro file looks like this:

TEMPLATE = lib
CONFIG += qt dll
HEADERS = Interface.h \
Plugin.h
SOURCES = Plugin.cpp

jacek
10th February 2006, 23:34
error C2039: 'staticMetaObject' : is not a member of 'Interface'
error C2039: 'qt_metacast' : is not a member of 'Interface'
error C2039: 'qt_metacall' : is not a member of 'Interface'
error C3861: 'connect': identifier not found
You can place Q_OBJECT only in classes that inherit QObject, because only QObjects can use signals and slots.

Try this:
class Plugin : public QObject, public Interface /* note the order of super classes */
{
Q_OBJECT
public:
// ...
};

_Ramirez_
11th February 2006, 10:19
Thanks, it's working now. You were right, it was the order of QObject and Interface. I've tried it the other way and it didn't work. I'm not realy sure that I understand the diference? And one more thing. Receiver for connect has to be this and not my main app, but I don't know who should be parent for my QAction, this (Plugin) or parent that I pass from main app?

jacek
11th February 2006, 14:28
I'm not realy sure that I understand the diference?
It has nothing to do with C++, it's just a limitation of Qt tools.


I don't know who should be parent for my QAction, this (Plugin) or parent that I pass from main app?
If you use the plugin as a parent, this action will be deleted automatically when you delete the plugin, otherwise you will have to delete it by hand.