在Qt/Qt Quick宏浅议一文中,我们将介绍Qt中经常使用的几个宏: Q_OBJECT, SIGNAL与SLOT, Q_SIGNALS 与 Q_SLOTS, Q_EMIT ,Q_INVOKABLE, Q_PROPERTY。相比其他宏,Q_INVOKABLE
显得更加神秘,但Q_INVOKABLE的理解与使用变得越来越重要。本文将围绕Q_INVOKABLE以及相对应的invokeMethod展开讨论。
Q_INVOKABLE
#define Q_INVOKABLE
重新回顾一下Q_INVOKABLE的定义,它在$QTDIR/src/corelib/kernel/qobjectdefs.h 中,简单被define,目的在于让moc识别。
使用Q_INVOKABLE来修饰成员函数,目的在于被修饰的成员函数能够被元对象系统所唤起。
QMetaObject::invokeMethod
静态方法QMetaObject::invokeMethod() 的定义如下:
-
boolQMetaObject::invokeMethod(QObject*obj,constchar*member,Qt::ConnectionTypetype,
-
QGenericReturnArgumentret,QGenericArgumentval0=QGenericArgument(0),…)
invokeMethod的用法为,尝试调用对象obj的方法member(注意member可以为信号或者是槽),如何member可以被调用,则返回真,否则返回假。QMetaObject::invokeMethod可以是异步调用,也可以是同步调用。这取决与它的连接方式Qt::ConnectionType type。如果type为Qt::DirectConnection,则为同步调用,若为Qt::QueuedConnection,则为异步调用。例如:
-
QMetaObject::invokeMethod(object,"methodName",
-
Qt::QueuedConnection,
-
Q_ARG(type1,arg1),
-
Q_ARG(type2,arg2));
上述调用为异步调用。请注意,因为上面所示的参数需要被在构建事件时进行硬拷贝,参数的自定义型别所对应的类需要提供一个共有的构造函数、析构函数以及拷贝构造函数。而且必须使用注册Qt型别系统所提供的qRegisterMetaType() 方法来注册这一自定义型别。
Q_INVOKABLE与QMetaObject::invokeMethod均由元对象系统唤起。这一机制在Qt C++/QML混合编程,跨线程编程,Qt Service Framework 以及Qt/ HTML5混合编程以及里广泛使用。
Qt C++/QML混合编程
QML中调用C++方法借助了Qt元对象系统。考虑在QML中使用Qt C++定义的方法,如下代码所示:
-
importQt4.7
-
importShapes5.0
-
Item{
-
width:300;height:200
-
Ellipse{
-
x:50;y:35;width:200;height:100
-
color:"blue"
-
MouseArea{
-
anchors.fill:parent
-
-
onClicked:parent.color=parent.randomColor()
-
}
-
}
-
}
为了让上述QML代码成功的调用下面这段代码定义的randomColor()函数,最为关键的一点见randomColor方法用Q_INVOKABLE 修饰。
-
#include<QDeclarativeItem>
-
classEllipseItem:publicQDeclarativeItem
-
{
-
Q_OBJECT
-
public:
-
Q_INVOKABLEQColorrandomColor()const;
-
…
-
}
更多细节,请参看我的另一篇博文:QML与C++混合编程使用
在跨线程编程中的使用
我们如何调用驻足在其他线程里的QObject方法呢?Qt提供了一种非常友好而且干净的解决方案:向事件队列post一个事件,事件的处理将以调用我们所感兴趣的方法为主(当然这需要线程有一个正在运行的事件循环)。而触发机制的实现是由moc提供的内省方法实现的。因此,只有信号、槽以及被标记成Q_INVOKABLE的方法才能够被其它线程所触发调用。如果你不想通过跨线程的信号、槽这一方法来实现调用驻足在其他线程里的QObject方法。另一选择就是将方法声明为Q_INVOKABLE,并且在另一线程中用invokeMethod唤起。
更多细节,译文事件循环与线程
Qt Service Framework
Qt服务框架是Qt Mobility 1.0.2版本推出的,一个服务(service)是一个独立的组件提供给客户端(client)定义好的操作。客户端可以通过服务的名称,版本号和服务的对象提供的接口来查找服务。 查找到服务后,框架启动服务并返回一个指针。
服务通过插件(plug-ins)来实现。为了避免客户端依赖某个具体的库,服务必须继承自QObject。这样QMetaObject系统可以用来提供动态发现和唤醒服务的能力。要使QmetaObject机制充分的工作,服务必须满足,其所有的方法都是通过 signal,slot,property
或invokable method和Q_INVOKEBLE来实现
其中,最常见的与servicer交互的方法如下:
- QServiceManagermanager;QObject*storage;
- storage=manager.loadInterface("com.nokia.qt.examples.FileStorage");if(storage)QMetaObject::invokeMethod(storage,"deleteFile",Q_ARG(QString,"/tmp/readme.txt"));
上面的代码通过service的元对象提供的invokeMethod方法,调用文件存储对象的deleteFile() 方法。客户端不需要知道对象的类型,因此也没有链接到具体的service库。 当然在服务端的deleteFile方法,一定要被标记为Q_INVOKEBLE,才能够被元对象系统识别
Qt服务框架的一个亮点是它支持跨进程通信,服务可以接受远程进程。在服务管理器上注册后 进程通过signal,slot,invokable method和property来通信,就像本地对象一样。服务可以设定为在客户端间共享,或针对一个客户端。请注意,在Qt服务框架推出之前,信号、槽以及invokable method仅支持跨线程。 下图是跨进成的服务/客户段通信示意图(图片来自诺基亚论坛)。这里我们可以清楚的看到,invokable
method和Q_INVOKEBLE是跨进城、跨线程对象之间通信的重要利器。
有关Qt Service Framework的更多讨论和用例,请参见Qt Service Framework文档
请尊重原创作品和译文。转载请保持文章完整性,并以超链接形式注明原始作者地址http://blog.csdn.net/changsheng230,方便其他朋友提问和指正。
在Qt/Qt Quick宏浅议一文中,我们将介绍Qt中经常使用的几个宏: Q_OBJECT, SIGNAL与SLOT, Q_SIGNALS 与 Q_SLOTS, Q_EMIT ,Q_INVOKABLE, Q_PROPERTY。相比其他宏,Q_INVOKABLE
显得更加神秘,但Q_INVOKABLE的理解与使用变得越来越重要。本文将围绕Q_INVOKABLE以及相对应的invokeMethod展开讨论。
Q_INVOKABLE
#define Q_INVOKABLE
重新回顾一下Q_INVOKABLE的定义,它在$QTDIR/src/corelib/kernel/qobjectdefs.h 中,简单被define,目的在于让moc识别。
使用Q_INVOKABLE来修饰成员函数,目的在于被修饰的成员函数能够被元对象系统所唤起。
QMetaObject::invokeMethod
静态方法QMetaObject::invokeMethod() 的定义如下:
-
boolQMetaObject::invokeMethod(QObject*obj,constchar*member,Qt::ConnectionTypetype,
-
QGenericReturnArgumentret,QGenericArgumentval0=QGenericArgument(0),…)
invokeMethod的用法为,尝试调用对象obj的方法member(注意member可以为信号或者是槽),如何member可以被调用,则返回真,否则返回假。QMetaObject::invokeMethod可以是异步调用,也可以是同步调用。这取决与它的连接方式Qt::ConnectionType type。如果type为Qt::DirectConnection,则为同步调用,若为Qt::QueuedConnection,则为异步调用。例如:
-
QMetaObject::invokeMethod(object,"methodName",
-
Qt::QueuedConnection,
-
Q_ARG(type1,arg1),
-
Q_ARG(type2,arg2));
上述调用为异步调用。请注意,因为上面所示的参数需要被在构建事件时进行硬拷贝,参数的自定义型别所对应的类需要提供一个共有的构造函数、析构函数以及拷贝构造函数。而且必须使用注册Qt型别系统所提供的qRegisterMetaType() 方法来注册这一自定义型别。
Q_INVOKABLE与QMetaObject::invokeMethod均由元对象系统唤起。这一机制在Qt C++/QML混合编程,跨线程编程,Qt Service Framework 以及Qt/ HTML5混合编程以及里广泛使用。
Qt C++/QML混合编程
QML中调用C++方法借助了Qt元对象系统。考虑在QML中使用Qt C++定义的方法,如下代码所示:
-
importQt4.7
-
importShapes5.0
-
Item{
-
width:300;height:200
-
Ellipse{
-
x:50;y:35;width:200;height:100
-
color:"blue"
-
MouseArea{
-
anchors.fill:parent
-
-
onClicked:parent.color=parent.randomColor()
-
}
-
}
-
}
为了让上述QML代码成功的调用下面这段代码定义的randomColor()函数,最为关键的一点见randomColor方法用Q_INVOKABLE 修饰。
-
#include<QDeclarativeItem>
-
classEllipseItem:publicQDeclarativeItem
-
{
-
Q_OBJECT
-
public:
-
Q_INVOKABLEQColorrandomColor()const;
-
…
-
}
更多细节,请参看我的另一篇博文:QML与C++混合编程使用
在跨线程编程中的使用
我们如何调用驻足在其他线程里的QObject方法呢?Qt提供了一种非常友好而且干净的解决方案:向事件队列post一个事件,事件的处理将以调用我们所感兴趣的方法为主(当然这需要线程有一个正在运行的事件循环)。而触发机制的实现是由moc提供的内省方法实现的。因此,只有信号、槽以及被标记成Q_INVOKABLE的方法才能够被其它线程所触发调用。如果你不想通过跨线程的信号、槽这一方法来实现调用驻足在其他线程里的QObject方法。另一选择就是将方法声明为Q_INVOKABLE,并且在另一线程中用invokeMethod唤起。
更多细节,译文事件循环与线程
Qt Service Framework
Qt服务框架是Qt Mobility 1.0.2版本推出的,一个服务(service)是一个独立的组件提供给客户端(client)定义好的操作。客户端可以通过服务的名称,版本号和服务的对象提供的接口来查找服务。 查找到服务后,框架启动服务并返回一个指针。
服务通过插件(plug-ins)来实现。为了避免客户端依赖某个具体的库,服务必须继承自QObject。这样QMetaObject系统可以用来提供动态发现和唤醒服务的能力。要使QmetaObject机制充分的工作,服务必须满足,其所有的方法都是通过 signal,slot,property
或invokable method和Q_INVOKEBLE来实现
其中,最常见的与servicer交互的方法如下:
- QServiceManagermanager;QObject*storage;
- storage=manager.loadInterface("com.nokia.qt.examples.FileStorage");if(storage)QMetaObject::invokeMethod(storage,"deleteFile",Q_ARG(QString,"/tmp/readme.txt"));
上面的代码通过service的元对象提供的invokeMethod方法,调用文件存储对象的deleteFile() 方法。客户端不需要知道对象的类型,因此也没有链接到具体的service库。 当然在服务端的deleteFile方法,一定要被标记为Q_INVOKEBLE,才能够被元对象系统识别
Qt服务框架的一个亮点是它支持跨进程通信,服务可以接受远程进程。在服务管理器上注册后 进程通过signal,slot,invokable method和property来通信,就像本地对象一样。服务可以设定为在客户端间共享,或针对一个客户端。请注意,在Qt服务框架推出之前,信号、槽以及invokable method仅支持跨线程。 下图是跨进成的服务/客户段通信示意图(图片来自诺基亚论坛)。这里我们可以清楚的看到,invokable
method和Q_INVOKEBLE是跨进城、跨线程对象之间通信的重要利器。
有关Qt Service Framework的更多讨论和用例,请参见Qt Service Framework文档
请尊重原创作品和译文。转载请保持文章完整性,并以超链接形式注明原始作者地址http://blog.csdn.net/changsheng230,方便其他朋友提问和指正。
分享到:
相关推荐
用法 通过导入库 import 'package:open_appstore/open_appstore.dart' ; 您可以在Dart代码中打开AppStore或PlayStore。 要打开“ App Store”页面,您可以传递应用程序ID。 OpenAppstore . launch (androidAppId...
C++通过函数名称字符串调用对应函数
通过public slots输出模式或Q_INVOKABLE标记模式使它可以调用QObject派生出的类型。 C++模式同样可以有参数并且可以返回值。QML支持如下类型: •bool •unsigned int, int •float, double, qreal •QString •...
differ.java 测试静态方法与实例方法之间的区别 forefather.java 一个简单的基类 grandson.java 上面这个类的子类 hasConstructor.java 拥有构造器的类 hasFinalFun.java 拥有最终方法的类 hasRecall.java ...
Qt 使用QMetaObject实现反射机制代码demo
Qt一步一步实现插件通信代码实现,根据信号和槽的机制原理,完成主程序和插件间通信
Flutter视频通话与Vonage集成...将此3个变量(SESSION,TOKEN,API_KEY)传递到_init()方法下的platform.invokeMethod中。 将以下参数替换为您的值void startVideoCall () { FlutterVonageVideoCall . init (
(十三) InvokeMethod 调用方法 (十四) Delay 与WF4中的线程 (十五) TransactionScope 事物容器 (十六) CompensableActivity 补偿 (十七) Bookmark (十八) Flowchar (十九) Persistence 持久化 (二十) ...
VS2005和c#编程写的。禁用无线网卡和开启无线网卡。
WPF的一组可扩展性黑客。 一些有趣的触发器和动作,包括EventTrigger,ReactiveTrigger,InvokeMethodAction和InvokeCommandAction。 还允许根据条件调用触发器和动作。
利用invokeMethod一个简单函数实现QRunnable信号槽
BindingFlags.Instance | BindingFlags.InvokeMethod | BindingFlags.Public, null, this, null); IOleClientSite oleClientSite2 = oleClientSite as IOleClientSite; IOleContainer pObj; oleClientSite2....
解决Eclipse中使用drool时报Caused by: java.lang.RuntimeException: The Eclipse JDT Core jar is not in the classpath的问题。 详细错误: org.drools.RuntimeDroolsException: Unable to load dialect 'org....
C#反射在实际应用中的实例代码,需要的朋友可以参考一下
outPar = mo.InvokeMethod("EnableStatic", inPar, null); //设置网关地址 inPar = mo.GetMethodParameters("SetGateways"); inPar["DefaultIPGateway"] = new string[] { "192.168.16.2", "192.168.16.254" }...
tas_face_detect 一个新的flutter插件,用于获取图像中的面Kong数量。 入门 该项目是Flutter的起点,Flutter是一个特殊的程序包... await App.platformMethodChannel.invokeMethod('findFaces', {"path": imagePath});
本文实例讲述了Laravel框架路由与MVC。分享给大家供大家参考,具体如下: 1、路由 路由的作用就是将用户的不同url请求转发给相应的程序进行处理,laravel的路由定义在routes文件夹中,默认提供了四个路由文件,其中...
17.3.4 使用方法对象 216 17.3.5 为某一特定的实例 添加方法 217 17.4 本章小结 218 第18章 Grails插件开发 219 18.1 创建与发布插件 219 18.2 插件能做什么 221 18.2.1 添加Spring配置信息 223 18.2.2 与Spring...
jmx入门的源码例子,包括所需jar包,下载后把jmxtools.jar加入classpath中,然后启动程序, 可以在IE中查看mbean,也可以jconsole中查看
用于测试工作流InvokeMethod活动异步调用的源代码。详情见http://blog.csdn.net/jemmy0327/article/details/8210483