首页 Qt Qt 4 插件开发(5)

Qt 4 插件开发(5)

6 2.9K

Qt 插件系统所应当解决的最大的一个问题就是交互:包括主程序与插件的交互以及插件与主程序的交互。另外还有一个情况是插件之间的交互,这种情况比较罕见——我们一般不会将插件依赖于其它插件之上(因为我们不能确定这个插件存不存在),除非是非常重大的插件才支持自己的插件,并且这种情况十分类似主程序与插件之间的交互,只要把支持插件的插件理解为主程序就好了。

主程序调用插件提供的函数

主程序如果需要使用插件提供的函数——比如在 OrbitsWriter 中,不同的插件提供了针对不同博客系统的 API 调用,主程序在向博客系统远程发表文章时,就必须调用插件对应的函数——这种情况就是最简单的情况:只需要将插件对象(QPluginManager::instance()获得的对象)转换成接口,就可以调用响应的函数了。

前面我们的例子代码中,调用了插件对象的name()函数,就属于这种情况。

插件调用主程序提供的对象

由于我们使用 C++ 编程,函数一般作为对象的成员,因此,插件需要调用对象成员函数的话,只需要能够获得对象就可以了。

调用主程序对象同调用一般对象没有区别。首先需要引用到对象的头文件,然后就可以调用。 这里需要注意的是,我们想要导出的对象必须使用Q_DECL_EXPORT宏进行修饰。而这个宏要求必须是一个共享库。也就是说,如果你的主程序有对象需要在插件中使用,那么,这些对象必须位于一个共享库中,不能在可执行文件中。

比如,我们希望提供一个类似日志的工具 Logger,这个 Logger 必须位于一个共享库中,并且使用Q_DECL_EXPORT宏修饰。然后,我们需要生成可执行文件时,需要连接这个库。

主程序与插件之间信号槽连接

鉴于 Qt 插件框架的限制(插件只能以纯 C++ 接口的形式提供,不允许将这个接口继承QObject),我们无法定义插件必须提供的信号槽。如果需要将主程序与插件对象进行信号槽连接,需要在接口中提供一个类似getObject()的函数,其返回值是一个QObject *。这样,让插件将所需要进行信号槽连接的对象返回,从而完成与主程序的connect()函数。

6 评论

wyyhzc 2012年11月23日 - 16:53

😆 受教了

回复
LinWM 2016年1月17日 - 15:26

文末的这句话:“如果需要将主程序与插件对象进行信号槽连接,需要在接口中提供一个类似getObject()的函数,其返回值是一个QObject *。这样,让插件将所需要进行信号槽连接的对象返回,从而完成与主程序的connect()函数。”是不是有不一样的理解呢?如果要进行信号槽连接,一般都是想要连接自己定义的槽函数,返回QObject *是否正确呢(这样就只能连接QObejct的槽了)?

回复
豆子 2016年1月17日 - 23:46

你也可以返回 QObject 的子类的指针。之所以返回 QObject *,是因为这是一个公共父类,如果 getObject() 函数需要每个插件都要提供,一般会定义在接口中,这样返回 QObject * 是合适的。

回复
LinWM 2016年8月13日 - 10:35

但返回QObject *还是只能连接QObject的信号和槽了。在具体需求中,一般都是想连接自己定义的信号和槽,这就导致了一种情况:在插件接口设计时,为了达到能够使用Qt信号槽的目的,伴随着插件接口的设计还会产生一个专门用于处理插件实例与主程序之间信号槽交互的类。那么问题来了?这个类应该放在哪里呢?1.放在主程序中,当插件想要连接时就变成为调用主程序的对象,会导致编译失败;2.放在插件实现程序中,由于插件接口和该类的设计早于插件实现程序,所以设计上有违时间先后原则;3.放在共享库中,本人观点,这个应该是最好的解决方案,将该类放到共享库中(接口其实也可以放到此处)供主程序和插件程序访问(实际项目中:我就是以一种放在共享库中类似交换机的类来处理主程序和插件之间的信号槽交互)。以上都是项目开发时的思考,如有不对之处,望不吝赐教,互相进步哦。

回复
William 2016年10月25日 - 17:06

放在共享库中应该是较好的方案,由于没在实际项目中使用过,主程序与插件之间在哪些情况下会使用信号槽机制通信呢?

回复
craigtao 2017年2月8日 - 10:18

博主,你的文章对我帮助很大,特别是那16篇 加 qt的这5篇,感谢你的分享,不过个人有个疑问,一般插件式框架好像都会提供插件之间的交互,听说这块不是太好设计,不过的思路是 通过插件管理系统进行交互,应该是可以的吧? 是不是你可以再次更新一下,加上这么一篇呢?

回复

发表评论

关于我

devbean

devbean

豆子,生于山东,定居南京。毕业于山东大学软件工程专业。软件工程师,主要关注于 Qt、Angular 等界面技术。

主题 Salodad 由 PenciDesign 提供 | 静态文件存储由又拍云存储提供 | 苏ICP备13027999号-2