QT Webkit的插件Plugin设计实现

转自:http://blog.csdn.net/myaccella/article/details/7009086


 Qt Webkit中浏览器插件Plugin设计实现是我们要介绍的内容,我们都知道浏览器中有一套由Netscape浏览器传承下来的插件接口,

包括webkit,firefox都是支持的,但是那个开发起来比较困难,并且是平台相关的,借助于Qt的跨平台的特性,可以方便地为Qt开

发出一套跨平台的插件。

 

    QtWebkit中插件可以有两种,一种Mime必须是application/x-qt-plugin或者application/x-qt-styled-widget,而另外一种则无需固定,

可以是除了前面的两种以外任意其它Mime类型。

 

前一种相对来说开发起来比较容易,只需重新实现

  1. QObject * QWebPage::createPlugin (const QString& classid,   
  2.     const QUrl& url,   
  3.     const QStringList& paramNames,   
  4.     const QStringList &paramValues)   

这个函数即可,这个函数会把HTML文件中的参数都传递进来

下面是一个例子:

  1. class PluginPage : public QWebPage    
  2. {   
  3. public:  
  4.     PluginPage(QObject *parent = 0)  : QWebPage(parent) {}    
  5. protected:    
  6.     virtual QObject *createPlugin(const QString &classid, const QUrl &url,  const QStringList &paramNames,    
  7.     const QStringList &paramValues)    
  8.     {    
  9.         QObject *result = 0;    
  10.         if (classid == "pushbutton")    
  11.             result = new QPushButton();    
  12.         else if (classid == "lineedit")    
  13.             result = new QLineEdit();    
  14.   
  15.         if (result)    
  16.             result->setObjectName(classid);    
  17.         //可以进行一些处理    
  18.          return result;    
  19.     }    
  20. }  

这样下面的网页就可以一个pushbutton了:


  1. <html>   
  2. <body> <object type='application/x-qt-plugin' classid='pushbutton' id='mybutton'/> </body>   
  3. </html>

并且还可以在JavaScript访问到QPushbutton,例如:

document.getElementById('mybutton').text将会返回按钮上的字符串。

 

上面介绍的插件设计方式中虽然方便,但是其Mime类型只能是application/x-qt-plugin或者application/x-qt-styled-widget,

这个有时候可能满足不了实际应用需求,那么另一种就没有这种限制,那可以是任意Mime类型的。这种设计需要重新实现

QWebPluginFactory这个纯虚基类。先看看他的声明:

 

  1. class QWEBKIT_EXPORT QWebPluginFactory : public QObject   
  2. {    
  3.     ……    
  4. public:    
  5.     struct Plugin {    
  6.         QString name;   
  7.         QString description;    
  8.         QList<MimeType> mimeTypes;    
  9.     };    
  10.     explicit QWebPluginFactory(QObject* parent = 0);    
  11.     virtual ~QWebPluginFactory();  
  12.     virtual QList<Plugin> plugins() const = 0;   
  13.     virtual void refreshPlugins();   
  14.     virtual QObject *create(const QString& mimeType, const QUrl&,   
  15.          const QStringList& argumentNames, const QStringList& argumentValues) const = 0;   
  16.     virtual bool extension(Extension extension, const ExtensionOption* option = 0, ExtensionReturn* output = 0);   
  17.     virtual bool supportsExtension(Extension extension) const;   
  18.     ……   
  19. }; 


重点要实现的接口是plugins,用于获取plugin的列表,用于webkit内部判断该mime类型是否被支持,如果可以支持,

那么就会调用create来创建这个插件,而具体打开哪个文件以及参数都会传递进来。

 

后两个extension和supportsExtension接口暂时没有发现有什么用处,暂不考虑。

因此重新实现的WebPluginFactory如下:

  1. class WebPluginFactory: public QWebPluginFactory    
  2. {        
  3. public:            
  4.     WebPluginFactory(QObject *parent = 0);    
  5.     ~WebPluginFactory(){};            
  6.     QList<QWebPluginFactory::Plugin> plugins() const;  
  7.     void refreshPlugins();  
  8.     QObject *create(const QString &mimeType, const QUrl &url, const QStringList &argumentNames,   
  9.          const QStringList &argumentValues) const ;  
  10.     bool extension(QWebPluginFactory::Extension extension, const QWebPluginFactory::ExtensionOption *option = 0,  
  11.          QWebPluginFactory::ExtensionReturn *output = 0);  
  12.     bool supportsExtension(QWebPluginFactory::Extension extension) const;        
  13. private:            
  14.     // 用于将载入的插件记录下来            
  15.     mutable QList<QList<QWebPluginFactory::Plugin> > pluginslist;  
  16.     mutable QList<WebKitPluginInteface *> interfaces;    
  17. };


具体实现主要是create和plugins两个函数:

  1. QList<QWebPluginFactory::Plugin> WebPluginFactory::plugins() const  {        
  2.     const char * s=getenv("BROWSER_PLUGIN_DIR");        
  3.     static bool isFirst=true;        
  4.     if(!isFirst)      {  
  5.           return pluginslist;  
  6.     }        
  7.     isFirst=false;        
  8.     QString spath;        
  9.     if(s)        
  10.         spath=s;  
  11.     else  {    
  12.         spath=".";    
  13.     }        
  14.     QDir dir(spath);        
  15.     QStringList filters;        
  16.     QString abspath=dir.absolutePath();    
  17.     filters<<"libqtweb*.so";   
  18.     //查找下面的动态库,linux下是so,windows下则应该是dll,        
  19.      QStringList files=dir.entryList(filters);        
  20.     foreach(QString file,files)      {  
  21.         file=dir.filePath(file);            
  22.         QPluginLoader loader(file,0);  
  23.         QObject * objloader.instance();    
  24.         //下面是载入自定义的接口,只有这样才能支持动态插件创建,如果固定死了,将不利于扩展,后一节会介绍这部分内容   
  25.          WebKitPluginInteface * interfaceqobject_cast<WebKitPluginInteface*> (obj);  
  26.         if (interface == 0)  {  
  27.             //ignore error when loading so ;   
  28.             continue;            
  29.         }            
  30.         interface->plugins();            
  31.         plugins.append(interface->plugins());   
  32.         pluginslist.append(interface->plugins());    
  33.         interfaces.append(interface);        
  34.     }        
  35.     return plugins;    
  36. }    
  37.   
  38. void WebPluginFactory::refreshPlugins()  {        
  39.     Reload();    
  40. }    
  41.   
  42. QObject * WebPluginFactory::create(const QString &mimeType, const QUrl &url, const QStringList &argumentNames,            
  43.     const QStringList &argumentValues) const    
  44. {        
  45.     for(int i=0;i<pluginslist.size();i++){  
  46.         for( int j=0;j< pluginslist[i].size();j++){  
  47.               foreach(WebPluginFactory::MimeType mt, pluginslist[i][j].mimeTypes){  
  48.                   if(mt.name == mimeType) //查找到,创建实例  
  49.                          return interfaces[i]->create( mimeType, url, argumentNames, argumentValues);  
  50.               }            
  51.         }        
  52.     }        
  53.     return NULL; //如果没有,直接返回NULL,webkit会进行处理的    


这两个最主要的接口都是围绕着mimetype进行的,通过返回的列表告诉webkit插件支持什么类型的文件,而create则根据mimetype来识别文件类型,


然后创建相应的插件。

下面会简单的创建一个插件来演示如何创建一个插件。

上面讲到可以通过扩展QWebPage接口进行动态载入插件,但是插件的接口并没有明确,这里通过介绍自定义的接口来实现插件的动态载入。

首先是接口的定义:

  1. class WebKitPluginInteface  {        
  2. public:            
  3.     virtual ~WebKitPluginInteface(){};  
  4.     virtual QList<QWebPluginFactory::Plugin> plugins()const =0;  
  5.     virtual QObject *create(const QString &mimeType, const QUrl &url, const QStringList &argumentNames,                    
  6.         const QStringList &argumentValues) const =0;    
  7. };     
  8. Q_DECLARE_INTERFACE(WebKitPluginInteface, "baizx.cnblogs.com/1.0")


这样自定义的插件就可以通过实现这个接口来实现定制的插件。下面是一个例子:

  1. class TestPlugin :public QObject,public WebKitPluginInteface {   
  2.     Q_OBJECT   
  3.     Q_INTERFACES(WebKitPluginInteface)   
  4. public:   
  5.     TestPlugin(QObject * parent=0): WebkitPlugin(parent){};   
  6.     virtual ~TestPlugin(){};   
  7.     virtual QList<QWebPluginFactory::Plugin> plugins()const ;   
  8.     virtual QObject *create(const QString &mimeType, const QUrl &url,   
  9.         const QStringList &argumentNames, const QStringList &argumentValues) const ;   
  10. };   
  11.   
  12. QList<QWebPluginFactory::Plugin> TestPlugin::plugins()const   
  13. {   
  14.     QList<QWebPluginFactory::Plugin> plugins ;   
  15.     QWebPluginFactory::Plugin plugin;   
  16.     QWebPluginFactory::MimeType mimeType;   
  17.     QStringList strings;   
  18.     plugin.name="testplugin";   
  19.     plugin.description="testplugin !!!";   
  20.     mimeType.name="application/x-textedit";   
  21.     mimeType.description="test textedit";   
  22.     strings.append(".etxt");   
  23.     mimeType.fileExtensions=strings;   
  24.     QList<QWebPluginFactory::MimeType> mimeTypes;   
  25.     mimeTypes.append(mimeType);   
  26.     plugin.mimeTypes=mimeTypes;   
  27.     plugins.append(plugin);   
  28.     return plugins;   
  29. }   
  30.   
  31. QObject *TestPlugin::create(const QString &mimeType, const QUrl &url,   
  32.         const QStringList &argumentNames, const QStringList &argumentValues) const   
  33. {   
  34.     QTextEdit * editnew QTextEdit();   
  35.     edit->setObjectName("我是插件");   
  36.     edit->setPlainText(mimeType + url.toString() );   
  37.     Q_UNUSED(argumentNames);   
  38.     Q_UNUSED(argumentValues);   
  39.     return edit;   
  40. }   


这样一个简单的插件就创建完毕了,具体实际应用中可能会用到很到参数,并且会载入实际的内容,这里只是一个演示。

小结:Qt Webkit浏览器插件设计实现的内容介绍完了,希望通过本文的学习能对你有所帮助!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值