Qt Webkit中浏览器插件设计是本文要介绍对内容,我们都知道浏览器中有一套由Netscape浏览器传承下来的插件接口,包括webkit,firefox都是支持的,但是那个开发起来比较困难,并且是平台相关的,借助于Qt的跨平台的特性,可以方便地为Qt开发出一套跨平台的插件。
Qt Webkit中插件可以有两种,一种Mime必须是application/x-qt-plugin或者application/x-qt-styled-widget,而另外一种则无需固定,可以是除了前面的两种以外任意其它Mime类型。
前一种相对来说开发起来比较容易,只需重新实现
- QObject * QWebPage::createPlugin ( const QString & classid, const QUrl & url, const QStringList & paramNames, const QStringList ¶mValues )
这个函数即可,这个函数会把HTML文件中的参数都传递进来
下面是一个例子:
- class PluginPage : public QWContainer(wid2, wid3)ebPage
- {
- public:
- PluginPage(QObject *parent = 0)
- : QWebPage(parent) {}
- protected:
- virtual QObject *createPlugin(const QString &classid, const QUrl &url,
- const QStringList ¶mNames,
- const QStringList ¶mValues)
- {
- QObject *result = 0;
- if (classid == "pushbutton")
- result = new QPushButton();
- else if (classid == "lineedit")
- result = new QLineEdit();
- if (result)
- result->setObjectName(classid);
- //可以进行一些处理
- return result;
- }
- };
这样下面的网页就可以一个pushbutton了:
- <html><body><object type='application/x-qt-plugin' classid='pushbutton' id='mybutton'/></body></html>
并且还可以在JavaScript访问到QPushbutton,例如:
document.getElementById('mybutton').text将会返回按钮上的字符串。
上面介绍的插件设计方式中虽然方便,但是其Mime类型只能是application/x-qt-plugin或者application/x-qt-styled-widget,这个有时候可能满足不了实际应用需求,那么另一种就没有这种限制,那可以是任意Mime类型的。这种设计需要重新实现QWebPluginFactory这个纯虚基类。先看看他的声明:
前一节介绍的插件设计方式中虽然方便,但是其Mime类型只能是application/x-qt-plugin或者application/x-qt-styled-widget,这个有时候可能满足不了实际应用需求,那么另一种就没有这种限制,那可以是任意Mime类型的。这种设计需要重新实现QWebPluginFactory这个纯虚基类。先看看他的声明:
- class QWEBKIT_EXPORT QWebPluginFactory : public QObject {
- ……
- public:
- struct Plugin {
- QString name;
- QString description;
- QList<MimeType> mimeTypes;
- };
- explicit QWebPluginFactory(QObject* parent = 0);
- virtual ~QWebPluginFactory();
- virtual QList<Plugin> plugins() const = 0;
- virtual void refreshPlugins();
- virtual QObject *create(const QString& mimeType,
- const QUrl&,
- const QStringList& argumentNames,
- const QStringList& argumentValues) const = 0;
- virtual bool extension(Extension extension, const ExtensionOption* option = 0, ExtensionReturn* output = 0);
- virtual bool supportsExtension(Extension extension) const;
- ……
- };
重点要实现的接口是plugins,用于获取plugin的列表,用于webkit内部判断该mime类型是否被支持,如果可以支持,那么就会调用create来创建这个插件,而具体打开哪个文件以及参数都会传递进来。
后两个extension和supportsExtension接口暂时没有发现有什么用处,暂不考虑。
因此重新实现的WebPluginFactory如下:
- class WebPluginFactory: public QWebPluginFactory
- {
- public:
- WebPluginFactory(QObject *parent = 0);
- ~WebPluginFactory(){};
- QList<QWebPluginFactory::Plugin> plugins()const ;
- void refreshPlugins();
- QObject *create(const QString &mimeType,
- const QUrl &url,
- const QStringList &argumentNames,
- const QStringList &argumentValues) const ;
- bool extension(QWebPluginFactory::Extension extension, const QWebPluginFactory::ExtensionOption
- *option = 0, QWebPluginFactory::ExtensionReturn *output = 0);
- bool supportsExtension(QWebPluginFactory::Extension extension) const;
- private:
- // 用于将载入的插件记录下来
- mutable QList<QList<QWebPluginFactory::Plugin> > pluginslist;
- mutable QList<WebKitPluginInteface *> interfaces;
- };
具体实现主要是create和plugins两个函数:
- QList<QWebPluginFactory::Plugin> WebPluginFactory::plugins() const
- {
- const char * s=getenv("BROWSER_PLUGIN_DIR");
- static bool isFirst=true;
- if(!isFirst)
- {
- return pluginslist;
- }
- isFirst=false;
- QString spath;
- if(s)
- sspath=s;
- else
- {
- spath=".";
- }
- QDir dir(spath);
- QStringList filters;
- QString abspath=dir.absolutePath();
- filters<<"libqtweb*.so"; //查找下面的扩张,linux下是so,windows下则应该是dll,
- QStringList files=dir.entryList(filters);
- foreach(QString file,files)
- {
- file=dir.filePath(file);
- QPluginLoader loader(file,0);
- QObject * obj= loader.instance();
- //下面是载入自定义的接口,只有这样才能支持动态插件创建,如果固定死了,将不利于扩展,后一节会介绍这部分内容
- WebKitPluginInteface * interface= qobject_cast<WebKitPluginInteface*> (obj);
- if(interface==0)
- {
- //ignore error when loading so ;
- continue;
- }
- interface->plugins();
- plugins.append(interface->plugins());
- pluginslist.append(interface->plugins());
- interfaces.append(interface);
- }
- return plugins;
- }
- void WebPluginFactory::refreshPlugins()
- {
- Reload();
- }
- QObject * WebPluginFactory::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(WebPluginFactory::MimeType mt, pluginslist[i][j].mimeTypes)
- {
- if(mt.name == mimeType) //查找到,创建实例
- return interfaces[i]->create( mimeType, url, argumentNames, argumentValues);
- }
- }
- }
- return NULL; //如果没有,直接返回NULL,webkit会进行处理的
- }
这两个最主要的接口都是围绕着mimetype进行的,通过返回的列表告诉webkit插件支持什么类型的文件,而create则根据mimetype来识别文件类型,然后创建相应的插件。
小结:Qt Webkit中浏览器插件设计的内容介绍完了,希望通过Qt Webkit应用内容的学习能对你有所帮助!