我有一个继承自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;
//}
}
但是这并没有给我显示任何方法的添加,因为方法的偏移量等于方法的计数,为什么可以呢?我不明白原因,谢谢你的帮助。
发布于 2013-01-29 07:27:14
对于希望在QMetaObject
中看到的每个方法,都需要使用Q_INVOKABLE
宏。
Q_INVOKABLE
将此宏应用于成员函数的声明,以允许通过元对象系统调用它们。宏写在返回类型之前,如下例所示:
类窗口:公共窗口{ Q_OBJECT public: QWidget ();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
-derived类的指针,则不需要这样做。(dynamic_cast
到QObject*
将会起作用,并且会得到正确的QMetaObject,因为虚拟继承,但这是不必要的,不太安全,而且不明确。)
您实际上不需要类的实例来获取元对象:
const QMetaObject *metaobj = SomeClass::staticMetaObject();
这是可能的,因为每个类都有一个QMetaObject,而不是每个对象。
对于任何想要更多地了解元对象系统的人,我推荐使用咖啡和documentation。通常,您不需要直接处理QMetaObject实例,除非您正在编写脚本引擎或类似的“元”。很容易无意中复制Qt已经提供的功能。
而且,Q_DECLARE_METATYPE
也不是你想要的。
发布于 2013-01-29 07:02:04
the official docs中存在某种模棱两可的情况。
首先我们来看一下:
method()和methodCount()提供关于类的元方法(信号、槽和其他可调用的成员函数)的信息。
但后来:
int QMetaObject::methodCount() const返回该类中方法的数量,包括每个基类提供的属性数量。这些函数包括信号和插槽以及正常的成员函数。
但实际上我们无法通过Qt MetaObject系统访问“正常”方法。
因此,要访问您的方法,您应该使用Q_INVOKABLE
宏来声明它们:
Q_INVOKABLE void method1();
Q_INVOKABLE void method2();
https://stackoverflow.com/questions/14576078
复制相似问题