ImageVerifierCode 换一换
你正在下载:

QT_plugin.doc

[预览]
格式:DOC , 页数:15 ,大小:172KB ,
资源ID:7674433      下载积分:10 金币
快捷注册下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

开通VIP
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.zixin.com.cn/docdown/7674433.html】到电脑端继续下载(重复下载【60天内】不扣币)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

开通VIP折扣优惠下载文档

            查看会员权益                  [ 下载后找不到文档?]

填表反馈(24小时):  下载求助     关注领币    退款申请

开具发票请登录PC端进行申请

   平台协调中心        【在线客服】        免费申请共赢上传

权利声明

1、咨信平台为文档C2C交易模式,即用户上传的文档直接被用户下载,收益归上传人(含作者)所有;本站仅是提供信息存储空间和展示预览,仅对用户上传内容的表现方式做保护处理,对上载内容不做任何修改或编辑。所展示的作品文档包括内容和图片全部来源于网络用户和作者上传投稿,我们不确定上传用户享有完全著作权,根据《信息网络传播权保护条例》,如果侵犯了您的版权、权益或隐私,请联系我们,核实后会尽快下架及时删除,并可随时和客服了解处理情况,尊重保护知识产权我们共同努力。
2、文档的总页数、文档格式和文档大小以系统显示为准(内容中显示的页数不一定正确),网站客服只以系统显示的页数、文件格式、文档大小作为仲裁依据,个别因单元格分列造成显示页码不一将协商解决,平台无法对文档的真实性、完整性、权威性、准确性、专业性及其观点立场做任何保证或承诺,下载前须认真查看,确认无误后再购买,务必慎重购买;若有违法违纪将进行移交司法处理,若涉侵权平台将进行基本处罚并下架。
3、本站所有内容均由用户上传,付费前请自行鉴别,如您付费,意味着您已接受本站规则且自行承担风险,本站不进行额外附加服务,虚拟产品一经售出概不退款(未进行购买下载可退充值款),文档一经付费(服务费)、不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
4、如你看到网页展示的文档有www.zixin.com.cn水印,是因预览和防盗链等技术需要对页面进行转换压缩成图而已,我们并不对上传的文档进行任何编辑或修改,文档下载后都不会有水印标识(原文档上传前个别存留的除外),下载后原文更清晰;试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓;PPT和DOC文档可被视为“模板”,允许上传人保留章节、目录结构的情况下删减部份的内容;PDF文档不管是原文档转换或图片扫描而得,本站不作要求视为允许,下载前可先查看【教您几个在下载文档中可以更好的避免被坑】。
5、本文档所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用;网站提供的党政主题相关内容(国旗、国徽、党徽--等)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
6、文档遇到问题,请及时联系平台进行协调解决,联系【微信客服】、【QQ客服】,若有其他问题请点击或扫码反馈【服务填表】;文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“【版权申诉】”,意见反馈和侵权处理邮箱:1219186828@qq.com;也可以拔打客服电话:0574-28810668;投诉电话:18658249818。

注意事项

本文(QT_plugin.doc)为本站上传会员【xrp****65】主动上传,咨信网仅是提供信息存储空间和展示预览,仅对用户上传内容的表现方式做保护处理,对上载内容不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知咨信网(发送邮件至1219186828@qq.com、拔打电话4009-655-100或【 微信客服】、【 QQ客服】),核实后会尽快下架及时删除,并可随时和客服了解处理情况,尊重保护知识产权我们共同努力。
温馨提示:如果因为网速或其他原因下载失败请重新下载,重复下载【60天内】不扣币。 服务填表

QT_plugin.doc

1、基于QT Plugin框架结构 日常总结 2009-04-24 18:56:02 阅读168 评论0   字号:大中小 订阅 一:qt plugin 介绍       Qt Plugin和其他类型的插件一样,是一种计算机应用程序,它和主应用程序(host application)互相交互,以提供特定的功能。应用程序支持Plugin有许多原因,一些主要原因包括:使得第三方开发者有能力扩展应用程序,以提供无法先期预料的特色;减小应用程序的大小;由于软件版权之间的不兼容性将源代码和应用程序分享。Qt Plugin 分动态插件和静态插件两种。 二:qt plugin 创建和使用方法 Qt

2、有两种与插件有关的API。一种用来扩展Qt本身的功能,如自定义数据库驱动,图像格式,文本编解码,自定义分格,等等,称为Higher-Level API。另一种用于应用程序的功能扩展,称为Lower-Level API。前一种是建立在后一种的基础之上的。这里讨论的是后一种,即用来扩展应用程序的Lower-level API。 让应用程序支持插件扩展的步骤:   1. 定义一个接口集(只有纯虚函数的类),用来与插件交流。   2. 用宏Q_DECLARE_INTERFACE()将该接口告诉Qt元对象系统。  Q_DECLARE_INTERFACE(BrushInterface,"com.t

3、rolltech.PlugAndPaint.BrushInterface/1.0")   3. 应用程序中用QPluginLoader来装载插件。   4. 用宏qobject_cast()来确定一个插件是否实现了接口。  QObject *obj = new QTimer;   QTimer *timer = qobject_cast(obj); 写一个插件的步骤:   1. 声明插件类,该类从QObject和该插件希望实现的接口继承而来。   2. 用宏Q_INTERFACES()将该接口告诉Qt元对象系统。    class BasicToolsPl

4、ugin : public QObject,                             public BrushInterface,                             public ShapeInterface,                             public FilterInterface    {        Q_OBJECT        Q_INTERFACES(BrushInterface ShapeInterface FilterInterface)    public:        ...    };

5、   3. 用宏Q_EXPORT_PLUGIN2()导出插件。   Q_EXPORT_PLUGIN2 ( PluginName, ClassName )   4. 用适当的.pro文件构建插件。 下面的代码声明了一个接口类:   class FilterInterface  {  public:         virtual ~FilterInterface() {}         virtual QStringList filters() const = 0;         virtual QImage filterImage(const QString &fil

6、ter, const QImage &image, QWidget* parent)=0;   }; Q_DECLARE_INTERFACE(FilterInterface, "com.trolltech.PlugAndPaint.FilterInterface/1.0") 这里是实现该接口的插件类的定义:    #include  #include  #include  #include  class ExtraFiltersPlugin : publi

7、c QObject, public FilterInterface  {  Q_OBJECT  Q_INTERFACES(FilterInterface)  public:      QStringList filters() const;      QImage filterImage(const QString &filter, const QImage &image,      QWidget *parent);  }; 根据插件的类型不同,pro文件中配置上有不同。下面是pro文件分析: TEMPLATE      = lib                    

8、              // 声明为lib,动态和静态插件一样。 CONFIG       += plugin static                // 声明为plugin,带static表面为静态,否则为动态。 INCLUDEPATH  += ../.. HEADERS       = basictoolsplugin.h SOURCES       = basictoolsplugin.cpp TARGET        = $$qtLibraryTarget(pnp_basictools)           // 指明插件的名称 DESTDIR       =

9、/../plugandpaint/plugins 加载插件的主应用程序默认在当前目录下的plugins文件夹中寻找可用插件,如果是动态插件,则直接放在plugins文件夹中便可,如果是静态,则需要在主应用程序的main函数的开始的地方用宏:Q_IMPORT_PLUGIN(pluginname(和pro文件中声明的一致))声明需要加载的插件并在工程配置中指明插件的lib位置。 三:基于qt plugin 技术的框架结构设想 1.      愿景 由于我们目前系统功能多,模块多,缺乏系统的整体性。我们想借助Qt Plugin技术,把各个独立的功能模块实现为一个个插件,统一在主体框架中,

10、并能根据不同地方的用户的不同需求,在主框架中加载不同的功能模块,以实现整个系统的功能集中,体现出系统的整体性。 2.      plugin 接口 通过技术验证得出,目前我们采用动态插件,各个功能的插件实现定义的统一接口,具体功能放在插件界面中实现,此部分就像开发独立的应用程序,只是需要注意的是: ① 功能部分的主界面需要继承至插件界面基类:PluginWidget,插件接口中用具体的实现类指针给插件界面基类指针赋值,在加载插件的主框架中通过插件接口中定义的基类指针统一调用,利用C++动态技术动态识别具体指向的实现类。 ② 插件界面类必须实现基类的虚函数:CreateActions()

11、用于创建Action ③ 创建Action需要使用基类的方法newAction创建,在此函数中加入了保存创建的Action功能。 插件接口定义如下: class QPluginInterface { public:     // 析构函数     virtual ~QPluginInterface() {}         // 插件名称     virtual    QString    PluginName() = 0;         // 插件显示在主框架中的图标文件路径     virtual    QString PluginIconurl() = 0

12、         // 插件提供的对外操作接口集     virtual QList* Actions() = 0;       // 创建插件提供的操作方法     virtual    void CreateActions()=0;       // 插件的主界面     virtual QWidget* Widget() = 0; protected:     // 插件的主界面基类     PluginWidget *pluginWidget; }; 插件界面基类定义如下: class PluginWidget :public QM

13、ainWindow {     Q_OBJECT public:     PluginWidget(QWidget*parent=0);     ~PluginWidget();     QList*  Actions();     virtual void      CreateActions(){}     QAction *  newAction(const QIcon &icon,const QString &text,QObject*parent);     QAction *         newAction(const QString &t

14、ext,QObject*parent);     void       AppendAction(QAction*act); protected:     // action链表     QList *m_actlist; }; 下图是一个实现案例中各类之间的关系图: 3.      插件调用 插件在主框架中动态加载,目前考虑主框架基本结构是继承至QMainWindow,工具栏上显示当前加载的插件的功能键,并留有返回键可以回退到上一级。主工作区是一个QStackWidget,保存插件的界面,并把插件序号和插件对应的界面建立映射,保存在QMap

15、Widget>中。通过序号到QStackWidget中切换界面。 下图是把DBManager做成插件加载到主框架的运行界面: 下图是把一个简单的绘图程序做成了插件,加载到主框架的运行界面: 四:总结         目前只是通过实现两个动态插件在主框架中运行,基本算是功能性的验证,离具体实施还有很多工作需要进一步的研究,比如主框架的风格,插件的管理等等。由于本人的能力有限,可能有很多认识不够的地方,请指正。 [QT]qt plugin插件 plugin是作为dll的一种特殊的应用而存在的. 也就 是说,在linux下面,他是so的一种应用而已. 动

16、态链接装入器例程 dlopen 需要在文件系统 中查找共享目标文件以打开文件并创建句柄. 有 4 种方式用以指定文件的位置: 1.dlopen call 中的绝对文件路径 2.在 LD_LIBRARY_PATH 环境变量中指定的目录中 3.在 /etc/ld.so.cache 中指定的库列表之中,可以用命令更新ld.so.cache: ldconfig -C ld.so.cache -n ../lib -v 4.先在 /usr/lib 之中,然后在 /lib 之中 今天主要是看了qt相关的plugin的东西. 并且尝试了一个plugin的程序,对

17、于我们来说, plugin是一个非常非常有用的东西,以后要多用. 对于qt而言,plugin是做成动态链接库的形式存在的,但是qt的plugin有一些特殊的地方. 事 实上,qt的plugin有两种,高层次和低层次的. qt的高层(high level)plugin是有qt的 meta-object system自动管理的. 也就是说你必须把你的plugin放在特定的子目录下面不能 修改,qt会自动寻找这些plugin. 当然我们可以用QLibrary重新设定qt lib的path,但是我觉 得这样是非常不礼貌的做法. 当然了,高层plugin也会自动搜寻系统的当前执行目录下的子

18、 目录来寻找plugin. 高层的plugin包括了许多有用的东西,包括了image,textcode,style等 等. 而对于我们更加有用的低层次的plugin,这种plugin可以用QPluginLoader来加载,我们可以 利用qApp::applicationDirPath()来得到我们当前的程序运行path,然后利用 QDir::cd("plugins")这样的操作进入我们的plugins子目录,然后load之. 对于这类的 plugin我们需要遵循下列的step ap: 1.定义一个Interface,并且用Q_DECLARE_INTERFACE宏告知

19、qt meta-object system有这 样一个interface; 2.用QPluginLoader加载这个plugin,用qobject_cast<>测试这个interface是否可用; plugin: 1.定义一个plugin的类,必须从interface继承,并在.h用Q_INTERFACE告诉meta-object system我们的类支持这样的interface; 2.实现这个类并用Q_EXPORT_PLUGIN2(pluginName,class)导出这个plugin,建立合适的 .pro文件来编译这个plugin 要注意

20、的是默认的plugin是编译在debug模式下的,如果ap是release模式的话不能load debug模式的plugin的. 我们可以在.pro中加入"config += release"这样的语句来改变 build模式. 结构上,我们的interfaces.h(包含Q_DECLARE_INTERFACE)可以为ap和plugin公共include没 有问题. 我们要注意的有: 1.interfaces.h(包含Q_DECLARE_INTERFACE); 2.Q_INTERFACE(interface1 interface2 interface3)放在plugin.h

21、中; 3.Q_EXPORT_PLUGIN2(pluginName,class)放在plugin.cpp中; 4.plugin.pro文件中一定要定义TARGET的内容,并且这个内容必须和Q_EXPORT_PLUGIN2中 的pluginName一致; 5.ap除了写代码load plugin之外不需要特殊的的宏; 这样我们就可以把我们的代码写成plugin了,如果你觉得子目录也要做成可以定义的话当然 也可以,做成QSetting就好了. 下面是我们的试验程序,注意这个程序中用了下面语句来列举plugins目录下的所有 plugin.so: plugin

22、sDir = QDir(qApp->applicationDirPath()); pluginsDir.cd("plugins"); foreach (QString fileName,pluginsDir.entryList(QDir::Files)) { QPluginLoader loader(pluginsDir.absoluteFilePath(fileName)); ... } // 注意这段程序中用到了applicationDirPath来得到app的地址. 要用到这种功能的话 // 要#include 才行,qApp

23、不需要自己定义,系统会自动定义的. // 还有就是用到了foreach宏来列举dir下面的所有文件名. 显然比较可爱 我们的试验程序plugin叫做kitty(猫咪),而ap叫做hunny,显然,我是想不到合适的名字罢了. kitty: .pro: ###################################################################### # Automatically generated by qmake (2.00a) 四 11月 9 10:37:28 2006 ##################

24、 TEMPLATE = lib CONFIG += plugin INCLUDEPATH += .. # "指定特殊的include path" TARGET += kitty # "特别注意这里" DEPENDPATH += . INCLUDEPATH += . # Input HEADERS += kitty.h SOURCES += kitty.cpp .h: #ifndef KITTY_H #defi

25、ne KITTY_H #include #include class Kitty : public QObject, public KittyInterface { Q_OBJECT Q_INTERFACES(KittyInterface) public: // for KittyInterface void go(); }; #endif .cpp: #include #include "kitty

26、h" void Kitty :: go() { printf("Kitty :: go() called\n"); printf("Kitty :: goto() \n"); } Q_EXPORT_PLUGIN2(kitty,Kitty) hunny: // 我们把kitty作为plugin放在plugins目录下 .pro: // 其实不需要做什么特殊的修改 ###################################################################### # Au

27、tomatically generated by qmake (2.00a) 四 11月 9 10:58:12 2006 ###################################################################### TEMPLATE = app TARGET += DEPENDPATH += . INCLUDEPATH += . # Input HEADERS += hunny.h interfaces.h SOURCES += hunny.cpp main.cpp CONFIG

28、 += debug .h: // 也不需要特殊的动作 #ifndef HUNNY_H #define HUNNY_H #include #include #include #include #include "interfaces.h" class Hunny : public QObject { Q_OBJECT public: void loadPlugins(); private: Q

29、Dir pluginsDir; }; #endif .cpp: // load kitty而已 #include "hunny.h" void Hunny :: loadPlugins() { printf("Hunny :: loadPlugins\n"); pluginsDir = QDir(qApp->applicationDirPath()); pluginsDir.cd("plugins"); foreach (QString fileName,pluginsDir.entryList(QDi

30、r::Files)) { QPluginLoader loader(pluginsDir.absoluteFilePath(fileName)); printf("loadPlugins : \ fileName(%s)\n",fileName.toAscii().data()); QObject *plugin = loader.instance(); printf("loadPlugins : plugin = %#x\n",plugin); if (plugin) { KittyInter

31、face *iKitty = qobject_cast(plugin); printf("loadPlugins : load KittyInterface,\ iKitty = %#x\n",iKitty); if (iKitty) { iKitty->go(); } } } } main.cpp: #include #include "hunny.h" int main(i

32、nt argc,char *argv[]) { QApplication app(argc,argv); Hunny h; h.loadPlugins(); return app.exec(); } interfaces.h: // 公用的interfaces #ifndef INTERFACES_H #define INTERFACES_H class KittyInterface { public: virtual void go() = 0; }; Q_DECLARE_

33、INTERFACE(KittyInterface, "com.S1.Linxb.hunny.KittyInterface/1.0") // 这里的标识字符其实没有什么关系的 #endif 写Qt Plugin时要注意的几个细节 yanboo 发表于 2007-11-14 11:00:47 - 1. 接口文件中要包含QtPlugin头文件 2. 对于小程序,尤其是一个人边想边做的这种,主程序和插件同步开发时,最好只用一份接口文件,其他插件工程中直接加入该文件,不要再拷贝到其工程目录下,这样修改接口的话较容易。 记得把接口文件

34、所在目录包含进其他工程中。 3. 有自己的界面的插件,它所实现的接口中至少要有启动和退出函数。 4. 退出插件时, 调用插件提供的退出函数,然后在主程序插件列表中删除该对象。这样就等到主程序退出时才能释放dll,理论上用QPluginLoader的unload可以彻底卸载,但我发现这个函数有些问题,会导致系统崩溃(Qt4.3.0)。 5. 一般的工具插件可以用exec函数启动,这样把当前程序控制权彻底交到插件界面。若用show启动插件界面,需要指定窗口为WindowModal,即使这样,Windows任务栏也会显示的像两个程序一样。(这是错误的,初始化插件中的窗体时没有指定正确的父窗口是

35、导致该问题的原因。) 6. 编写qt的Plugin及注意事项 2010-01-28 15:34 1)主程序,测试加载插件 #include "interfaces.h" #include #include #include int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); qDebug() << "start"; QPluginLoader pluginLoader("t

36、estd.dll"); QObject *plugin = pluginLoader.instance(); qDebug() << QObject::tr("Load statue:%1").arg(pluginLoader.isLoaded()?QObject::tr("Load OK"):pluginLoader.errorString()); if (plugin) {                 VectorLayer * layer = qobject_cast(plugin); qDebug()<< "start to access

37、 layer"; if (layer) {     qDebug()<< "access layer";        qDebug() <GetHello(); layer->SetHello("my layer is very good"); qDebug() <GetHello(); } } pluginLoader.unload(); return a.exec(); } 为使qDebug信息能够正常输出,需要在主程序工程pro文件中加入 CONFIG += qt console 2)共享的接口的头文件 /*

38、 *  接口,包括矢量图层、栅格数据 */ #ifndef INTERFACES_H #define INTERFACES_H #include #include QT_BEGIN_NAMESPACE class QString; class QStringList; QT_END_NAMESPACE class DataInterface: public QObject { public: virtual ~DataInterface(){}; }; class VectorLayer: publi

39、c DataInterface { public: virtual ~VectorLayer() {} virtual QString GetHello()=0; virtual void SetHello(QString Msg)=0; }; QT_BEGIN_NAMESPACE Q_DECLARE_INTERFACE(VectorLayer,"com.microinfospace.Goldmap.VectorLayer/1.0") QT_END_NAMESPACE #endif 这里的Q_DECLARE_INTERFACE需要特别留意,这段字符串分

40、成三部分 VectorLayer                                                       接口名称 com.microinfospace.Goldmap.VectorLayer         描述,一版是公司网址啥的 0.1                                                                     版本号 3)一个test插件的实现,主要功能,输出字符串,更改字符串内容 // test.h #ifndef TEST_H #define TEST_H #

41、include #include #include "interfaces.h" class TestHello: public VectorLayer { Q_OBJECT Q_INTERFACES(VectorLayer) private: QString CurMsg; public: QString GetHello(); void SetHello(QString Msg); }; #endif //test.cpp #include //-----------------

42、 #include #include "test.h" QString TestHello::GetHello() { return CurMsg; } void TestHello::SetHello(QString Msg) { CurMsg=Msg; } QT_BEGIN_NAMESPACE Q_EXPORT_PLUGIN2(test, TestHello) QT_END_NAMESPACE 这里的Q_EXPORT_PLUGIN2需要注意 test             是插件名 TestHello   是这个插件的类名 下图为运行结果

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        抽奖活动

©2010-2026 宁波自信网络信息技术有限公司  版权所有

客服电话:0574-28810668  投诉电话:18658249818

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :微信公众号    抖音    微博    LOFTER 

客服