c++ - 我无法从 QMetaObject 获取方法,方法偏移量和计数相等

标签 c++ qt metaobject

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

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

在同一 header 的另一个类中,我创建了该类的一个实例,然后我尝试从“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;
        //}
    }

但是这并没有显示我添加了任何方法,因为方法偏移量等于方法计数,为什么可以呢?我不明白原因,谢谢任何帮助。

最佳答案

您需要为希望在 QMetaObject 中看到的每个方法使用 Q_INVOKABLE 宏。

From the documentation :

Q_INVOKABLE

Apply this macro to declarations 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().

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

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


此外,对于示例的第一行,您应该(可能)只调用

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

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

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

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

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

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


此外,Q_DECLARE_METATYPE 不是您想要的。

关于c++ - 我无法从 QMetaObject 获取方法,方法偏移量和计数相等,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14576078/

相关文章:

c++ - 如何创建一个继承自QWidget的qt插件

c++ - 接受 char* 的模板化函数

c++ - 更改 Qt 项目构建目录时出现大量链接器错误

android - QT Android 应用程序应该在 android 启动日志之后启动

c++ - 向后迭代 QList

Qt - 调用将自定义指针作为参数的槽

qt - 生成的 moc 名称不正确

c++ - 整数的计数频率

c++ - delete[] arr 和循环删除元素有什么区别

c++ - 使用额外的模板类型参数作为类型别名声明以在函数的签名中使用