详解为QT Webkit编写插件案例实现

移动开发
为QT Webkit编写插件案例实现是本文要介绍的内容,主要是来了解QT Webki中的插件问题,为了允许的QWebView加载插件,必须使能QWebView的Javascript和Plugins属性。

QT Webkit编写插件案例实现是本文要介绍的内容,主要是来了解QT Webkit中的插件问题,为了允许的QWebView加载插件,必须使能QWebView的Javascript和Plugins属性,使能方法为:

  1. QWebSettings::globalSettings()->setAttribute(QWebSettings::JavascriptEnabled,true);  
  2. QWebSettings::globalSettings()->setAttribute(QWebSettings::PluginsEnabled,true); 

或者

//这里假设webView是QWebView的对象:

  1. QWebView *webView;webView->settings()->setAttribute(QWebSettings::JavascriptEnabled,true);  
  2. webView->settings()->setAttribute(QWebSettings::PluginsEnabled,true); 

然后为QWebView添加插件工厂,这个插件工厂中包含了QWebView中所有可用的插件库,当然这个插件工厂中包含哪些插件得由我们程序员来定。添加插件工厂的方法为:
//为QWebView添加插件工厂,即告诉QWebView有哪些插件可用。//这里的 WebkitPluginFactory 是Qt的虚类 QWebPluginFactory 的实现类,后面会讲到这个类。

  1. webView->page()->setPluginFactory(new WebkitPluginFactory(this)); 

下面我们就来实现这个插件工厂类WebkitPluginFactory, 主要需要实现的就是 QWebPluginFactory  中的两个虚函数:

  1. virtual QObject *create(  
  2.   const QString &mimeType,   
  3.   const QUrl &url,         
  4.   const QStringList &argumentNames,  
  5.   const QStringList & argumentValues )  
  6.   const = 0;virtual QList<Plugin>      
  7.   plugins () const = 0;  
  8.     
  9. plugins() 方法为获取所有可用的插件列表, create() 方法则根据mimeType等参数来决定创建相应的插件。下面给出这个类的实现代码:  
  10.  
  11. webkitpluginfactory.h :  
  12.  
  13. #ifndef WEBKITPLUGINFACTORY_H  
  14. #define WEBKITPLUGINFACTORY_H   
  15. #include <QWebPluginFactory> 
  16. #include <QUrl> 
  17. #include "webkitplugininterface.h" class WebkitPluginFactory : public QWebPluginFactory{    
  18.   Q_OBJECTpublic:    WebkitPluginFactory(QObject *parent = 0);      
  19.   QObject *create (   
  20.     const QString & mimeType, const QUrl & url,   
  21.     const QStringList & argumentNames, const QStringList & argumentValues )   
  22.     const;    QList<QWebPluginFactory::Plugin> plugins () const;   
  23.   private:    // 插件列表    mutable QList<QList<QWebPluginFactory::Plugin> > pluginslist;    
  24. //插件接口,这个接口是我们自定义的插件的同意接口。    //这个接口在后面会讲到。    
  25. mutable QList<WebKitPluginInterface *> interfaces;  
  26.  };   
  27.  #endif // WEBKITPLUGINFACTORY_H  
  28.    
  29. webkitpluginfactory.cpp :  
  30.  
  31. #include "webkitpluginfactory.h"  
  32. #include <QPluginLoader>   
  33. #include <QDebug> 
  34. #include <QDir>    
  35. WebkitPluginFactory::WebkitPluginFactory(QObject *parent) :          
  36.     QWebPluginFactory(){      
  37.         qDebug()<<"debug : WebkitPluginFactory";  
  38.      }   
  39.    QList<QWebPluginFactory::Plugin>   
  40.    WebkitPluginFactory::plugins () const{       
  41.    //const char * s=getenv("BROWSER_PLUGIN_DIR");      
  42.      const char *s = "/home/nxx/FlashPlugin-build-desktop";      
  43.      static bool isFirst=true;      
  44.      static QList<QWebPluginFactory::Plugin> plugins;      
  45.        if(!isFirst)    {     
  46.             return plugins;      
  47.    }      
  48.    isFirst=false;      
  49.    plugins.clear();       
  50.    QString spath;      
  51.    if(s)        sspath=s;      
  52.    else        spath=".";       
  53.    QDir dir(spath);      
  54.    QStringList filters;      
  55.    QString abspath=dir.absolutePath();      
  56.    qDebug()<<abspath;     //获取指定目录下的所有插件,linux下是插件库的后缀为so,windows下则是dll  
  57.    filters<<"lib*.so";      
  58.    QStringList files=dir.entryList(filters);      
  59.    qDebug()<<"files: "<<files;    foreach(QString file,files)    {     
  60.         qDebug()<<QLibrary::isLibrary(file);          
  61.         file=dir.filePath(file);          
  62.         qDebug()<<"path: "<<file;          
  63.         QPluginLoader loader(file);          
  64.         QObject * objloader.instance();          
  65.         if(obj==0)              
  66.         qDebug()<<"error: "<<loader.errorString();          
  67.         //下面是载入自定义的接口,只有这样才能支持动态插件创建,如果固定死了,将不利于扩展          
  68.     WebKitPluginInterface * interfaceqobject_cast<WebKitPluginInterface*> (obj);          
  69.     if(interface==0)        {     
  70.              qDebug()<<"ignore error when loading so" ;             
  71.               continue;          
  72.          }          
  73.    qDebug()<<"load plugins: "<<interface->plugins().at(0).name;          
  74.    plugins.append(interface->plugins());         
  75.     pluginslist.append(interface->plugins());          
  76.     interfaces.append(interface);     
  77.  }    if(plugins.isEmpty()){         
  78.   qDebug()<<"no plugins is loaded!";     
  79.    }      
  80.  return plugins;  
  81. }  QObject * WebkitPluginFactory::create (   
  82. const QString & mimeType,   
  83. const QUrl & url, const QStringList & argumentNames, const QStringList & argumentValues )   
  84. const{      
  85. for(int i=0;i<pluginslist.size();i++)    {     
  86.      for( int j=0;j< pluginslist[i].size();j++)        {         
  87.           foreach(QWebPluginFactory::MimeType mt, pluginslist[i][j].mimeTypes)   {       
  88.     if(mt.name == mimeType) //更具MIME类型,创建相应的插件实例                   
  89.        return interfaces[i]->    
  90.     create( mimeType, url, argumentNames, argumentValues);            
  91.  }        
  92. }     
  93.  }      
  94.  return NULL; //如果没有,直接返回NULL,webkit会进行处理的  

下面就可以开始编写插件库。首先我们定义插件的统一接口,然后每个插件类只需实现该接口就行了,这样有利于扩展插件库。

自定义的插件接口:

  1. webkitplugininterface.h :  
  2.  
  3. #ifndef WEBKITPLUGININTERFACE_H  
  4. #define WEBKITPLUGININTERFACE_H  
  5. #include <QWebPluginFactory>   
  6. class WebKitPluginInterface{public:    virtual   
  7. WebKitPluginInterface(){};      
  8. virtual QList<QWebPluginFactory::Plugin> plugins()const =0;      
  9. virtual QObject *create(  
  10.            const QString &mimeType,     
  11.            const QUrl &url,    
  12.            const QStringList &argumentNames,   
  13.            const QStringList &argumentValues)   
  14.            const =0;}; //声明WebKitPluginInterface为一个接口  
  15.    Q_DECLARE_INTERFACE(WebKitPluginInterface, "com.plugin.uvchip.www/1.0")  
  16.    #endif // WEBKITPLUGININTERFACE_H  

上面的那段代码中的Q_DECLARE_INTERFACE() 是在定义接口是必须添加声明。下面是Qt对这个宏的说明:

  1. Q_DECLARE_INTERFACE (   
  2. ClassName, Identifier )This macro associates the given Identifier (a string literal)   
  3. to the interface class called ClassName. The Identifier must be unique. 

下面我们开始实现这个接口:

我们将flashplugin编译成库,这样就可以供插件工厂WebkitPluginFactory加载访问了。

  1. flashplugin.h :  
  2.  
  3. #ifndef FLASHPLUGIN_H  
  4. #define FLASHPLUGIN_H   
  5. #if defined(FLASHPLUGIN_LIBRARY)  
  6. #  define FLASHPLUGINSHARED_EXPORT Q_DECL_EXPORT#else  
  7. #  define FLASHPLUGINSHARED_EXPORT Q_DECL_IMPORT#endif   
  8. #include "webkitplugininterface.h"  
  9. #include <QtPlugin>   
  10.     class FLASHPLUGINSHARED_EXPORT FlashPlugin : public QObject, public WebKitPluginInterface  {          
  11.     Q_OBJECT          
  12.     Q_INTERFACES(WebKitPluginInterface) //声明WebKitPluginInterface是一个接口      
  13.     public:          
  14.     FlashPlugin(): WebKitPluginInterface(){};          
  15.     ~FlashPlugin(){};          
  16.     QList<QWebPluginFactory::Plugin> plugins()const ;         
  17.      QObject *create(const QString &mimeType,    
  18.      const QUrl &url,     
  19.      const QStringList &argumentNames,      
  20.      const QStringList &argumentValues) const ;   
  21.      };  
  22.  #endif // FLASHPLUGIN_H  
  23.    
  24. flashplugin.cpp :  
  25.  
  26. #include "flashplugin.h"   
  27. #include <QTextEdit> 
  28. #include <QUrl> 
  29. #include <QDebug>   
  30. QList<QWebPluginFactory::Plugin> FlashPlugin::plugins()const{      
  31. QWebPluginFactory::MimeType mimeType;      
  32. mimeType.name="application/x-shockwave-flash";      
  33. mimeType.description=QObject::tr("flash");      
  34. mimeType.fileExtensions.append(".flv");      
  35. mimeType.fileExtensions.append(".f4v");     
  36.  mimeType.fileExtensions.append(".swf");      
  37.   QList<QWebPluginFactory::MimeType> mimeTypes;      
  38.   mimeTypes.append(mimeType);       
  39.   QWebPluginFactory::Plugin plugin;      
  40.   plugin.name=QObject::tr("External Video viewer plugin");      
  41.   plugin.description=QObject::tr("Use vlc to open video files !!!");     
  42.    plugin.mimeTypes=mimeTypes;       
  43.    QList<QWebPluginFactory::Plugin> plugins ;      
  44.    plugins.append(plugin);      
  45.    return plugins;  
  46.  }  
  47.      QObject *FlashPlugin::create(  
  48.    const QString &mimeType,     
  49.    const QUrl &url,   
  50.    const QStringList &argumentNames,                  
  51.    const QStringList &argumentValues)   
  52.    const{      
  53.    QTextEdit * editnew QTextEdit();      
  54.    edit->setObjectName("我是插件");      
  55.    edit->setPlainText(mimeType + " :  " + url.toString() +"\n\n"           
  56.           +QString::fromUtf8("这里本来是需要adobeFlash插件的,")+"\n"          
  57.            +QString::fromUtf8("但现在替换成了我们自定义的插件(QTextEdit插件了)。")   
  58.        );      
  59.      Q_UNUSED(argumentNames);      
  60.      Q_UNUSED(argumentValues);      
  61.      qDebug()<<"create flash plugin";     
  62.   return edit;  
  63. }  

//Q_EXPORT_PLUGIN2()必不可少,//只有这样FlashPlugin插件类才为外部可见,插件名为WebkitPluginFlashQ_EXPORT_PLUGIN2(WebkitPluginFlash,FlashPlugin)

Q_EXPORT_PLUGIN2 在Qt帮助文档中的说明如下:

  1. Q_EXPORT_PLUGIN2 ( PluginName, ClassName )  
  2. This macro exports the plugin class ClassName for the plugin specified by PluginName. 
  3. The value of PluginName should correspond to the TARGET specified in the plugin's project file.   
  4.  
  5. There should be exactly one occurrence of this macro in the source code for a Qt plugin, 
  6. and it should be used where the implementation is written rather than in a header file. 

Q_EXPORT_PLUGIN2(WebkitPluginFlash, FlashPlugin) 中的WebkitPluginFlash为编译之后生成的库的名字,这里的生成的库的完整名字为:libWebkitFlashPlugin.so, FlashPlugin 是插件类名。

现在只要把生成的libWebkitFlashPlugin.so插件库拷贝到webkitpluginfactory插件工厂能搜到的目录下就行了(本例中我在webkitpluginfactory.cpp中指定的位置为 const char *s = "/home/nxx/FlashPlugin-build-desktop";)。

上面的插件库和前面的工厂类,QWebView对象组合在一起就可以实现:

当用QWebView打开包含了需要 mimeType.name="application/x-shockwave-flash" 类型的插件的网页的时候,就会调用到我们自定义的flashplugin插件了。

效果如下:

详解为QT Webkit编写插件案例实现

小结:详解为QT Webkit编写插件案例实现的内容介绍完了,希望通过本文的学习能对你有所帮助!

责任编辑:zhaolei 来源: 互联网
相关推荐

2011-06-27 16:59:19

Qt 动态 插件

2011-06-14 11:48:38

Webkit QT

2011-08-29 14:19:48

QtWebkit浏览器

2011-09-09 17:24:39

Qt Webkit模块

2011-09-09 18:43:13

Qt Webkit浏览器

2011-06-27 17:24:37

Qt 插件

2011-09-01 15:22:16

Qt WebKitWebKit

2011-08-29 14:40:58

QTWebkit

2011-10-13 14:26:12

Qt WebKitWebKit

2011-09-06 10:46:19

QT播放器

2011-09-07 16:43:38

Qt Widget

2011-08-29 10:59:47

QtWebkit嵌入式

2011-08-29 10:22:48

QtWebkit 模块HTML文档

2011-06-24 15:16:33

Qt 插件

2011-09-01 16:01:25

Qt插件

2011-07-05 17:54:43

QT Sqlite ARM

2011-09-09 15:31:04

Android Web插件

2011-09-09 16:23:16

Android Web测试

2011-08-29 11:25:29

QTWebKit鼠标

2011-08-29 10:01:27

QTWebkit插件
点赞
收藏

51CTO技术栈公众号