继承至QObject的类使用QMetaObject不能找到相应方法(Q_INVOKABLE)



I can not get methods from QMetaObject, methods offset and count are equals

i have a class that inherits from QObject and have the Q_OBJECT macro:

class SomeClass: public QObject
{
    Q_OBJECT
public:
    SomeClass(QObject *parent = 0);
    void method1();
    void method2();
    ...
};

in another class in the same header i create an instance of that class, and then i try to get all Methods from 'SomeClass' and store it in a QMap:

this->someclass = new SomeClass(); // in constructor.

...

cout<<"init some class methods"<<endl;
    const QMetaObject *metaobj = dynamic_cast<QObject*>(this->someclass)->metaObject();
    cout<<"offset "<<metaobj->methodOffset()<<endl;
    for(int i = metaobj->methodOffset();i < metaobj->methodCount();i++){
        QMetaMethod metamethod = metaobj->method(i);
        //if(metamethod.methodType() == QMetaMethod::Method){
            QString methodname = QString(metamethod.signature());
            methodname = methodname.replace(QRegExp("\\(.*\\)"),"");
            controlmethods.insert(methodname,metamethod);
            cout<<"added method: "<<metamethod.signature()<<" as "<<methodname.toAscii().data()<<endl;
        //}
    }

But this do not showed me any method added because the methods offset is equals to the methods count, why can be? i dont get with the reason, Thanks any help.

share | improve this question
 
   
Try declaring your class as a meta type with this macro –  tmpearce Jan 29 '13 at 5:21

2 Answers 2

up vote 3 down vote accepted

You need to use the Q_INVOKABLE macro for each method you want to see in the QMetaObject.

From the documentation:

Q_INVOKABLE

Apply this macro to definitions of member functions to allow them to be invoked via the meta-object system. The macro is written before the return type, as shown in the following example:

class Window : public QWidget {
    Q_OBJECT

public:
    Window();
    void normalMethod();
    Q_INVOKABLE void invokableMethod(); };

The invokableMethod() function is marked up using Q_INVOKABLE, causing it to be registered with the meta-object system and enabling it to be invoked using QMetaObject::invokeMethod(). Since normalMethod() function is not registered in this way, it cannot be invoked using QMetaObject::invokeMethod().

You can also use the slots macro. I think Q_INVOKABLE may be more minimal, though.

QMetaObject is only aware of signals, slots, properties and other invokable member functions, occasionally referred to as "meta-methods" as a group.


Also, for the first line of your example, you should (probably) just call

const QMetaObject *metaobj = someClass->metaObject();

This isn't just cosmetic. The dynamic_cast would move type-checking to runtime, which isn't necessary if you know at compile time that someClass is a pointer to a QObject-derived class. (dynamic_casting to QObject* will work, and will get you the correct QMetaObject because of virtual inheritance, but it's unnecessary, less safe, and unclear.)

You don't actually need an instance of the class to get the meta-object:

const QMetaObject *metaobj = SomeClass::staticMetaObject();

This is possible because there is one QMetaObject per class, not per object.

For anyone who wants to know more about the meta-object system, I recommend coffee and the documentation. Usually you don't need to deal with QMetaObject instances directly, unless you're writing a scripting engine or something equally 'meta'. It's easy to unintentionally duplicate functionality Qt already provides.


Also, Q_DECLARE_METATYPE is not what you want.

share | improve this answer
 
   
All is right, also i was using Q_INVOKABLE but not works until i used the StaticMetaObject, now all works fine :) –  Diego Fernando Murillo Valenci Jan 29 '13 at 15:12
   
OK, glad I could help. I wonder why metaObject() didn't work, there must be something more going on that I don't understand. –  typelist Jan 29 '13 at 15:36

There is some kind of ambiguity in the official docs.

First we see:

method() and methodCount() provide information about a class's meta-methods (signals, slots and other invokable member functions).

But later:

int QMetaObject::methodCount() const Returns the number of methods in this class, including the number of properties provided by each base class. These include signals and slots as well as normal member functions.

But actually we can't have access to 'normal' methods through Qt MetaObject System.

So, to get access to your methods, you should declare them with the Q_INVOKABLE macro:

Q_INVOKABLE void method1();
Q_INVOKABLE void method2();
share | improve this answer
 
   
Note that the linked docs are Qt5, while the question seems about Qt4 (as it uses QMetaMethod::signature()) –  Frank Osterfeld Jan 29 '13 at 7:15
   
@Frank Osterfeld I didn't know that :) Although docs 5, 4.6, 4.7 say the same about methodCount(), but 4.8 is different, it says directly: "member functions declared with the Q_INVOKABLE macro". –  hank Jan 29 '13 at 7:31
   
You are right there is an ambiguity in the docs, and the macro Q_INVOKABLE makes a method available for QMetaObject but in my code is needed also to use the staticMetaObject of SomeClass instead of the meta object of an instance for that works. –  Diego Fernando Murillo Valenci Jan 29 '13 at 15:06
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值