有时候可能需要在html网页中调用本地的对象方法。
比如说我点击了一个视频文件的链接,希望调用本地的多媒体模块来播放这个视频文件, 如何实现?
一、html中的JavaScript调用Qt本地对象方法
过程如下:
- 将本地的QObject对象暴露给webkit和JavaScript
- 通过JavaScript调用本地QObject的槽
下面对每个步骤进行详细的分析:
1、将本地的QObject对象暴露给webkit和JavaScript
QWebFrame里提供了实现这个功能的接口:
1
void
addToJavaScriptWindowObject(
const
QString &name, QObject *object, QScriptEngine::ValueOwnership ownership);
Qt的帮助文档中对这个方法的说明如下:
Make object available under name from within the frame's JavaScript context. The object will be inserted as a child of the frame's window object.
Qt properties will be exposed as JavaScript properties and slots as JavaScript methods.
If you want to ensure that your QObjects remain accessible after loading a new URL, you should add them in a slot connected to the javaScriptWindowObjectCleared() signal.
If Javascript is not enabled for this page, then this method does nothing.
The object will never be explicitly deleted by QtWebKit.
从这里可以看出,要想addToJavaScriptWindowObject方法有效,必须是能javascript;为了保证每次打开个新网页或刷新网页时都调用这个方法,那就应该将这个方法和javaScriptWindowObjectCleared信号相连。
相关代码如下:
webkit_vlc.h
#ifndef WEBKIT_VLC_H
#define WEBKIT_VLC_H
#include <QWidget>
#include <QWebView>
#include "obj_openvlc.h"
namespace Ui {
class Webkit_VLC;
}
class Webkit_VLC : public QWebView
{
Q_OBJECT
public:
explicit Webkit_VLC(QWidget *parent = 0);
~Webkit_VLC();
private slots:
void addJavaScriptObject();
private:
Ui::Webkit_VLC *ui;
Obj_OpenVlc *obj_openVlc; //将暴露给javascript的对象
};
#endif // WEBKIT_VLC_H
webkit_vlc.cpp
#include "webkit_vlc.h"
#include "ui_webkit_vlc.h"
#include <QWebPage>
#include <QWebFrame>
#include <QtDebug>
Webkit_VLC::Webkit_VLC(QWidget *parent) :
QWebView(parent),
ui(new Ui::Webkit_VLC)
{
setWindowFlags( Qt::FramelessWindowHint);
ui->setupUi(this);
resize(1280,720);
obj_openVlc = new Obj_OpenVlc(this);
settings()->setAttribute(QWebSettings::JavascriptEnabled,true);
settings()->setAttribute(QWebSettings::PluginsEnabled,true);
connect(page()->mainFrame(), SIGNAL(javaScriptWindowObjectCleared ()),
this, SLOT(addJavaScriptObject()));
load(QUrl("file:///home/nxx/Webkit_VLC/view.html"));
}
Webkit_VLC::~Webkit_VLC()
{
delete ui;
}
void Webkit_VLC::addJavaScriptObject(){
qDebug()<<"addJavaScriptObject";
//javascript可以通过对象名obj_open_vlc访问obj_openVlc对象。
page()->mainFrame()->addToJavaScriptWindowObject("obj_open_vlc",this->obj_openVlc);
}
现在已经将名为“obj_open_vlc”的对象暴露给了webkit的javascript, 这个对象名对应的是本地的一个类的对象
Obj_OpenVlc *obj_openVlc.
下面的代码为这个类的实现,并且类中定义了一个槽供webkit的javascript调用。
obj_openvlc.h
#ifndef OBJ_OPENVLC_H
#define OBJ_OPENVLC_H
#include <QObject>
class Obj_OpenVlc : public QObject
{
Q_OBJECT
public:
explicit Obj_OpenVlc(QObject *parent = 0);
signals:
public slots:
//供javascript调用的槽
QString openVLC(QString url);
};
#endif // OBJ_OPENVLC_H
#include "obj_openvlc.h"
#include <QtDebug>
Obj_OpenVlc::Obj_OpenVlc(QObject *parent) :
QObject(parent)
{
}
QString Obj_OpenVlc::openVLC(QString url)
{
qDebug()<<"open "<< url;
return url;
}
2、在html中通过JavaScript调用本地QObject的槽
html的代码如下:
view.html
<html>
<script LANGUAGE="JScript">
function open()
{
try{
var url = obj_open_vlc.openVLC("192.168.0.1/webroot/test.f4v");
alert(url);
}
catch(e) {
alert(e);
}
}
</script>
<body>
<h1>Open VLC</h1>
<input type=button value="open" onclick="open()">
</body>
</html>
这个html中通过javascript代码
obj_open_vlc.openVLC("192.168.0.1/webroot/test.f4v");
调用了本地类Obj_OpenVlc的对象obj_openVlc的槽(方法)openVLC()。
这样子就实现了在webkit的html网页中的,通过javascript调用本地对象的方法。
二、Qt本地对象调用html中的javascript方法
目前我知道的有两种方法:
1. 通过QWebFrame类的槽:
QVariant QWebFrame::evaluateJavaScript ( const QString & scriptSource )
来直接调用javascript中的方法, 比如我html网页中有个javascript 的 loadFinished()方法 , 那么就可按下面的方式直接调用:
webView->page()->mainFrame()->evaluateJavaScript("loadFinished();");
这里假设 webView 是 QWebView类的对象。
2.将本地OBject的信号和javascript的方法相连。
当本地发射出这个信号时,也会调用javascript的方法。不过这里需要在javascript中加入类似下面的代码。
//将Qt本地对象 obj_open_vlc的信号与 javascript的函数slotButtonClicked相连
obj_open_vlc.ObjSignal.connect(slotLinkClicked);
此处的 ObjSignal 是Qt本地对象obj_open_vlc的一个信号,slotButtonClicked 是javascipt 中的一个方法。之后,如果本地obj_open_vlc 对象执行 emit ObjSignal() 之后就会调用javascipt的方法slotLinkClicked()。
这里贴上相关的html的代码:
<html xmlns="http://www.w3.org/1999/xhtml">
<title>Media Server</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script language="javascript">
//将Qt本地对象 obj_open_vlc的信号与 javascript的函数slotButtonClicked相连
obj_open_vlc.ObjSignal.connect(slotLinkClicked);
function slotLinkClicked()
{
alert("link is clicked!");
}
function loadFinished()
{
alert("page load finished!");
}
function getRTMPHost()
{
if (location.protocol == "http:" || location.protocol == "https:")
return "/" + location.hostname + "/";
else
return "";
}
function open(file)
{
url = 'rtmp:/' + getRTMPHost() + 'vod/' + file
try {
var play = obj_open_vlc.openVLC(url);
//alert(play);
}
catch(e) {
alert(e);
}
}
</script>
<body>
<h1>Media Server</h1>
<p><a href="javascript:open('test1.f4v');">test1.f4v</a></p>
<p><a href="javascript:open('test2.f4v');">test2.f4v</a></p>
</body>
</html>