为QT的Webkit 编写插件
為了允許的QWebView加載插件,必須使能QWebView的Javascript和Plugins屬性,使能方法為:
QWebSettings::globalSettings()->setAttribute(QWebSettings::JavascriptEnabled,true);QWebSettings::globalSettings()->setAttribute(QWebSettings::PluginsEnabled,true);
或者
//這里假設(shè)webView是QWebView的對(duì)象:QWebView *webView;webView->settings()->setAttribute(QWebSettings::JavascriptEnabled,true);
webView->settings()->setAttribute(QWebSettings::PluginsEnabled,true);
然后為QWebView添加插件工廠,這個(gè)插件工廠中包含了QWebView中所有可用的插件庫,當(dāng)然這個(gè)插件工廠中包含哪些插件得由我們程序員來定。添加插件工廠的方法為: //為QWebView添加插件工廠,即告訴QWebView有哪些插件可用。 //這里的 WebkitPluginFactory 是Qt的虛類 QWebPluginFactory 的實(shí)現(xiàn)類,后面會(huì)講到這個(gè)類。 webView->page()->setPluginFactory(new WebkitPluginFactory(this));
下面我們就來實(shí)現(xiàn)這個(gè)插件工廠類WebkitPluginFactory, 主要需要實(shí)現(xiàn)的就是 QWebPluginFactory? 中的兩個(gè)虛函數(shù):
virtual QObject *create(const QString &mimeType, const QUrl &url, const QStringList &argumentNames,const QStringList & argumentValues )const = 0; virtual QList<Plugin> plugins () const = 0; plugins() 方法為獲取所有可用的插件列表, create() 方法則根據(jù)mimeType等參數(shù)來決定創(chuàng)建相應(yīng)的插件。下面給出這個(gè)類的實(shí)現(xiàn)代碼:webkitpluginfactory.h :
#ifndef WEBKITPLUGINFACTORY_H #define WEBKITPLUGINFACTORY_H ? #include <QWebPluginFactory> #include <QUrl> #include "webkitplugininterface.h" ? class WebkitPluginFactory : public QWebPluginFactory { Q_OBJECT public: WebkitPluginFactory(QObject *parent = 0); QObject *create ( const QString & mimeType, const QUrl & url, const QStringList & argumentNames, const QStringList & argumentValues ) const; QList<QWebPluginFactory::Plugin> plugins () const; ? private: // 插件列表 mutable QList<QList<QWebPluginFactory::Plugin> > pluginslist; //插件接口,這個(gè)接口是我們自定義的插件的同意接口。 //這個(gè)接口在后面會(huì)講到。 mutable QList<WebKitPluginInterface *> interfaces; }; ? ? #endif // WEBKITPLUGINFACTORY_Hwebkitpluginfactory.cpp :
#include "webkitpluginfactory.h" #include <QPluginLoader> ? #include <QDebug> #include <QDir> ? ? WebkitPluginFactory::WebkitPluginFactory(QObject *parent) : QWebPluginFactory() { qDebug()<<"debug : WebkitPluginFactory"; } ? QList<QWebPluginFactory::Plugin> WebkitPluginFactory::plugins () const { ? //const char * s=getenv("BROWSER_PLUGIN_DIR"); const char *s = "/home/nxx/FlashPlugin-build-desktop"; static bool isFirst=true; static QList<QWebPluginFactory::Plugin> plugins; if(!isFirst) { return plugins; } isFirst=false; plugins.clear(); ? QString spath; if(s) spath=s; else spath="."; ? QDir dir(spath); QStringList filters; QString abspath=dir.absolutePath(); qDebug()<<abspath; ? //獲取指定目錄下的所有插件,linux下是插件庫的后綴為so,windows下則是dll, filters<<"lib*.so"; QStringList files=dir.entryList(filters); qDebug()<<"files: "<<files; foreach(QString file,files) { qDebug()<<QLibrary::isLibrary(file); file=dir.filePath(file); qDebug()<<"path: "<<file; QPluginLoader loader(file); QObject * obj= loader.instance(); if(obj==0) qDebug()<<"error: "<<loader.errorString(); //下面是載入自定義的接口,只有這樣才能支持動(dòng)態(tài)插件創(chuàng)建,如果固定死了,將不利于擴(kuò)展 WebKitPluginInterface * interface= qobject_cast<WebKitPluginInterface*> (obj); if(interface==0) { qDebug()<<"ignore error when loading so" ; continue; } qDebug()<<"load plugins: "<<interface->plugins().at(0).name; plugins.append(interface->plugins()); pluginslist.append(interface->plugins()); interfaces.append(interface); } if(plugins.isEmpty()){ qDebug()<<"no plugins is loaded!"; } return plugins; } ? ? QObject * WebkitPluginFactory::create ( const QString & mimeType, const QUrl & url, const QStringList & argumentNames, const QStringList & argumentValues ) const { for(int i=0;i<pluginslist.size();i++) { for( int j=0;j< pluginslist[i].size();j++) { foreach(QWebPluginFactory::MimeType mt, pluginslist[i][j].mimeTypes) { if(mt.name == mimeType) //更具M(jìn)IME類型,創(chuàng)建相應(yīng)的插件實(shí)例 return interfaces[i]-> create( mimeType, url, argumentNames, argumentValues); } } } return NULL; //如果沒有,直接返回NULL,webkit會(huì)進(jìn)行處理的 }下面就可以開始編寫插件庫。首先我們定義插件的統(tǒng)一接口,然后每個(gè)插件類只需實(shí)現(xiàn)該接口就行了,這樣有利于擴(kuò)展插件庫。
自定義的插件接口:
webkitplugininterface.h :
#ifndef WEBKITPLUGININTERFACE_H #define WEBKITPLUGININTERFACE_H #include <QWebPluginFactory> ? class WebKitPluginInterface { public: virtual ~WebKitPluginInterface(){}; virtual QList<QWebPluginFactory::Plugin> plugins()const =0; virtual QObject *create(const QString &mimeType, const QUrl &url, const QStringList &argumentNames, const QStringList &argumentValues) const =0; }; ? //聲明WebKitPluginInterface為一個(gè)接口 Q_DECLARE_INTERFACE(WebKitPluginInterface, "com.plugin.uvchip.www/1.0") #endif // WEBKITPLUGININTERFACE_H上面的那段代碼中的Q_DECLARE_INTERFACE() 是在定義接口是必須添加聲明。下面是Qt對(duì)這個(gè)宏的說明:
下面我們開始實(shí)現(xiàn)這個(gè)接口: 我們將flashplugin編譯成庫,這樣就可以供插件工廠WebkitPluginFactory加載訪問了。flashplugin.h :
#ifndef FLASHPLUGIN_H #define FLASHPLUGIN_H ? #if defined(FLASHPLUGIN_LIBRARY) # define FLASHPLUGINSHARED_EXPORT Q_DECL_EXPORT #else # define FLASHPLUGINSHARED_EXPORT Q_DECL_IMPORT #endif ? #include "webkitplugininterface.h" #include <QtPlugin> ? class FLASHPLUGINSHARED_EXPORT FlashPlugin : public QObject, public WebKitPluginInterface { Q_OBJECT Q_INTERFACES(WebKitPluginInterface) //聲明WebKitPluginInterface是一個(gè)接口 public: FlashPlugin(): WebKitPluginInterface(){}; ~FlashPlugin(){}; QList<QWebPluginFactory::Plugin> plugins()const ; QObject *create(const QString &mimeType, const QUrl &url, const QStringList &argumentNames, const QStringList &argumentValues) const ; ? }; #endif // FLASHPLUGIN_Hflashplugin.cpp :
#include "flashplugin.h" ? #include <QTextEdit> #include <QUrl> #include <QDebug> ? QList<QWebPluginFactory::Plugin> FlashPlugin::plugins()const { QWebPluginFactory::MimeType mimeType; mimeType.name="application/x-shockwave-flash"; mimeType.description=QObject::tr("flash"); mimeType.fileExtensions.append(".flv"); mimeType.fileExtensions.append(".f4v"); mimeType.fileExtensions.append(".swf"); ? QList<QWebPluginFactory::MimeType> mimeTypes; mimeTypes.append(mimeType); ? QWebPluginFactory::Plugin plugin; plugin.name=QObject::tr("External Video viewer plugin"); plugin.description=QObject::tr("Use vlc to open video files !!!"); plugin.mimeTypes=mimeTypes; ? QList<QWebPluginFactory::Plugin> plugins ; plugins.append(plugin); return plugins; } QObject *FlashPlugin::create(const QString &mimeType, const QUrl &url, const QStringList &argumentNames, const QStringList &argumentValues) const { QTextEdit * edit= new QTextEdit(); edit->setObjectName("我是插件"); edit->setPlainText(mimeType + " : " + url.toString() +"\n\n" +QString::fromUtf8("這里本來是需要adobeFlash插件的,")+"\n" +QString::fromUtf8("但現(xiàn)在替換成了我們自定義的插件(QTextEdit插件了)。") ); ? Q_UNUSED(argumentNames); Q_UNUSED(argumentValues); qDebug()<<"create flash plugin"; return edit; } ? //Q_EXPORT_PLUGIN2()必不可少, //只有這樣FlashPlugin插件類才為外部可見,插件名為WebkitPluginFlash Q_EXPORT_PLUGIN2(WebkitPluginFlash, FlashPlugin)Q_EXPORT_PLUGIN2 在Qt幫助文檔中的說明如下:
Q_EXPORT_PLUGIN2 ( PluginName, ClassName )
This macro exports the plugin class ClassName for the plugin specified by PluginName. The value of PluginName should correspond to the TARGET specified in the plugin's project file.
There should be exactly one occurrence of this macro in the source code for a Qt plugin, 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 是插件類名。
現(xiàn)在只要把生成的libWebkitFlashPlugin.so插件庫拷貝到webkitpluginfactory插件工廠能搜到的目錄下就行了(本例中我在webkitpluginfactory.cpp中指定的位置為 const char *s = "/home/nxx/FlashPlugin-build-desktop";)。
上面的插件庫和前面的工廠類,QWebView對(duì)象組合在一起就可以實(shí)現(xiàn):
當(dāng)用QWebView打開包含了需要 mimeType.name="application/x-shockwave-flash" 類型的插件的網(wǎng)頁的時(shí)候,就會(huì)調(diào)用到我們自定義的flashplugin插件了。
效果如下:
轉(zhuǎn)載于:https://www.cnblogs.com/hibraincol/archive/2011/04/15/2017558.html
總結(jié)
以上是生活随笔為你收集整理的为QT的Webkit 编写插件的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: sliverlight3 学习 2, 布
- 下一篇: initramfs 工作原理