首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >我无法从QMetaObject获取方法,方法offset和count等于

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

Stack Overflow用户
提问于 2013-01-29 05:11:57
回答 2查看 3.9K关注 0票数 5

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class SomeClass: public QObject
{
    Q_OBJECT
public:
    SomeClass(QObject *parent = 0);
    void method1();
    void method2();
    ...
};

在同一标头的另一个类中,我创建了该类的一个实例,然后尝试从“SomeClass”中获取所有方法,并将其存储在QMap中:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
this->someclass = new SomeClass(); // in constructor.

..。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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;
        //}
    }

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

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-01-29 07:27:14

对于希望在QMetaObject中看到的每个方法,都需要使用Q_INVOKABLE宏。

From the documentation

Q_INVOKABLE

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

类窗口:公共窗口{ Q_OBJECT public: QWidget ();void normalMethod();Q_INVOKABLE void invokableMethod();};

使用Q_INVOKABLE标记invokableMethod()函数,使其注册到元对象系统,并使用QMetaObject::invokeMethod()调用它。因为normalMethod()函数不是以这种方式注册的,所以不能使用QMetaObject::invokeMethod()调用它。

也可以使用slots宏。不过,我认为Q_INVOKABLE可能更简约。

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

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
const QMetaObject *metaobj = someClass->metaObject();

这不仅仅是表面上的。dynamic_cast会将类型检查转移到运行时,如果您在编译时知道someClass是指向QObject-derived类的指针,则不需要这样做。(dynamic_castQObject*将会起作用,并且会得到正确的QMetaObject,因为虚拟继承,但这是不必要的,不太安全,而且不明确。)

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
const QMetaObject *metaobj = SomeClass::staticMetaObject();

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

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

而且,Q_DECLARE_METATYPE也不是你想要的。

票数 6
EN

Stack Overflow用户

发布于 2013-01-29 07:02:04

the official docs中存在某种模棱两可的情况。

首先我们来看一下:

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

但后来:

int QMetaObject::methodCount() const返回该类中方法的数量,包括每个基类提供的属性数量。这些函数包括信号和插槽以及正常的成员函数。

但实际上我们无法通过Qt MetaObject系统访问“正常”方法。

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Q_INVOKABLE void method1();
Q_INVOKABLE void method2();
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14576078

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文