我无法从QMetaObject获取方法,方法offset和count是等于

时间:2013-01-29 05:11:57

标签: c++ qt metaobject

我有一个继承自QObject并具有Q_OBJECT宏的类:

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

在同一个头文件中的另一个类中我创建了该类的实例,然后我尝试从“SomeClass”获取所有方法并将其存储在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;
        //}
    }

但这并没有向我展示任何添加的方法,因为方法偏移量等于方法计数,为什么可以呢?我没理由,谢谢你的帮助。

2 个答案:

答案 0 :(得分:5)

您需要为Q_INVOKABLE中要查看的每种方法使用QMetaObject宏。

From the documentation

  

<强> Q_INVOKABLE

     

将此宏应用于成员函数的声明,以允许通过元对象系统调用它们。宏在返回类型之前写入,如以下示例所示:

class Window : public QWidget {
    Q_OBJECT

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

使用Q_INVOKABLE标记invokableMethod()函数,使其在元对象系统中注册,并使用QMetaObject :: invokeMethod()调用它。由于normalMethod()函数未以这种方式注册,因此无法使用QMetaObject :: invokeMethod()调用它。

您还可以使用slots宏。我认为Q_INVOKABLE可能会更小。

QMetaObject只知道信号,插槽,属性和其他可调用的成员函数,有时候称为“元方法”作为一个组。


另外,对于你的例子的第一行,你应该(可能)只是调用

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

这不仅仅是化妆品。 dynamic_cast会将类型检查移动到运行时,如果您在编译时知道someClass是指向QObject派生类的指针,则不需要这样做。 (dynamic_castQObject*将起作用,并且由于虚拟继承而将为您提供正确的QMetaObject,但这是不必要的,不太安全且不清楚。)

您实际上并不需要该类的实例来获取元对象:

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

这是可能的,因为每个类有一个QMetaObject,而不是每个对象。

对于想要了解更多关于元对象系统的人,我推荐咖啡和documentation。通常您不需要直接处理QMetaObject实例,除非您正在编写脚本引擎或同样的“meta”。很容易无意中重复Qt已经提供的功能。


此外,Q_DECLARE_METATYPE不是您想要的。

答案 1 :(得分:2)

the official docs中存在某种歧义。

首先我们看到:

  

method()和methodCount()提供有关类的信息   元方法(信号,槽和其他可调用的成员函数)。

但后来:

  

int QMetaObject :: methodCount()const返回的方法数   这个类,包括每个基地提供的属性数量   类。这些包括信号和插槽以及普通成员   功能

但实际上我们无法通过Qt MetaObject System访问“普通”方法。

因此,要访问您的方法,您应该使用Q_INVOKABLE宏声明它们:

Q_INVOKABLE void method1();
Q_INVOKABLE void method2();