PDA

View Full Version : Specifying method metadata



brcain
20th September 2006, 22:00
Hello,

QMetaProperty data for a class can be specified using the Q_PROPERTY macro. What is the equivalent for QMetaMethod?

I know how to query it ... just not how to specify in the class declaration.


Q_PROPERTY(type name
READ getFunction
[WRITE setFunction]
[RESET resetFunction]
[DESIGNABLE bool]
[SCRIPTABLE bool]
[STORED bool])

Thanks,
Ben

jacek
20th September 2006, 22:52
What is the equivalent for QMetaMethod?
Q_OBJECT, which means that QMetaMethod and QMetaObject work only with classes that inherit QObject.

brcain
20th September 2006, 23:13
My class does indeed inherit from QObject. My question is ... how do I specify the methods for runtime introspection using a macro similar to Q_PROPERTY?


class cMyClass : public QObject
{
Q_OBJECT
Q_PROPERTY(int mData
READ getData()
WRITE setData()
RESET resetData())
Q_METHOD(??? // <--- How do I do this?
public:
cMyClass() : mData(7) {}
type0 someMethod(type1 foo1, type2 foo2, type3 foo3, ...);
int const getData() { return mData; }
void setData(int data) { mData = data; }
void resetData() { mData = 0; }
private:
int mData;
};


So that I can query like this ...



cMyClass * instance(new cMyClass);
cout << "Inspecting methods ..." << endl;
int count(instance->metaObject()->methodCount());
for(int i=0; i<count; i++)
{
cout << "\t" << instance->metaObject()->method(i).signature() << endl;
}

gfunk
21st September 2006, 00:34
Hmm, you can use the signals and slots keywords in your class declaration to make Qt create the method metadata for those functions. QMetaMethod seems to suggest support for a 3rd method type

enum MethodType (http://doc.trolltech.com/4.1/qmetamethod.html#MethodType-enum) { Method, Signal, Slot }


QMetaMethod::Method 0 The function is a plain member function.

I don't know how you make Qt recognize these plain methods/functions.

jacek
21st September 2006, 00:49
how do I specify the methods for runtime introspection using a macro similar to Q_PROPERTY?
You don't have to do anything to make signals or slots available, but the docs don't say anything about ordinary methods. Yet we have the Source ;)


#include <QCoreApplication>
#include <QObject>
#include <QMetaObject>

#include <QtDebug>

class Test : public QObject
{
Q_OBJECT
public:
Test() : QObject( 0 ), _x( 0 ) {}

Q_INVOKABLE void bar( int i ){ _x = i; }
int foo() { return _x; }

private:
int _x;
};

int main( int argc, char **argv )
{
QCoreApplication app( argc, argv );

Test t;

qDebug() << "foo = " << t.foo();
QMetaObject::invokeMethod( &t, "bar", Q_ARG( int, 42 ) );
qDebug() << "foo = " << t.foo();

return 0;
}

#include "main.moc"
I couldn't make it work for methods that return something, but you actually don't need it as you can always declare all interesting methods as slots.

I've found also this: http://lists.trolltech.com/qt4-preview-feedback/2005-04/thread00458-0.html.

Phonon Backend Development (http://developer.kde.org/documentation/library/cvs-api/kdelibs-apidocs/phonon/html/phonon_backend_development_page.html):
"The first step is to understand how the Phonon frontend calls the backend: In the frontend objects all backend objects are "only" QObjects. But QObject has powerful introspection capabilities that Phonon uses to call methods in the backend. If you're interested look at QMetaObject::invokeMethod. In order to make sure that a backend is fully operational (there are no abstract classes that tell the backend developer what method signatures are wrong or what methods are missing) there are two test programs compiled with kdelibs (if KDE4_BUILD_TESTS is set in cmake) that inspects the backend.

In short that requires the backend classes to inherit from QObject and to make all methods that are to be called from the frontend slots or prefixed with Q_INVOKABLE (the latter doesn't work reliable with Qt 4.1.3 at least, so you should simply make those methods slots."

gfunk
21st September 2006, 00:54
Would there be anything particularly bad about just declaring all your plain methods as slots? aside from the metaobject overhead, won't they just behave the same as regular methods?

jacek
21st September 2006, 01:02
Would there be anything particularly bad about just declaring all your plain methods as slots?
No, it will only make qt_metacall() and its data structures a bit bigger.

brcain
21st September 2006, 01:07
Would there be anything particularly bad about just declaring all your plain methods as slots?

I think I'll just do that. It seems to be giving me the results I need.


You don't have to do anything to make signals or slots available, but the docs don't say anything about ordinary methods. Yet we have the Source

Much thanks for the detailed post!