×
Namespaces

Variants
Actions

通过Qt Mobility扩展JavaScript功能

From Nokia Developer Wiki
Jump to: navigation, search
Article Metadata

代码示例
兼容于
平台:
Symbian

文章
max.chen 在 03 Jan 2011 创建
最后由 hamishwillee 在 11 Oct 2012 编辑

当我们将WRT widget移植到Qt时,常常会碰到JavaScript不具备某些功能,如访问联系人,操控摄像头等。这时我们会想到能否利用Qt Mobility扩展JavaScript的功能呢? 答案当然是肯定的。这里我们就以联系人为例,讲解如何实现这样的混合编程。

一个WRT widget通过JavaScript Contacts Service API 实现了将联系人姓名从设备中读出:

Port qt mobility.png

如果将这个widget移植到Qt平台,那么就无法在利用JavaScript Contacts Service API了。解决的方案就是用Qt Mobility取代JavaScript Service API。

如何将WRT widget移植到Qt 中讲解了如何创建一个基于QWebView控件的Qt应用。

由于项目中使用了Qt Mobility 的联系人功能所以要在项目文件中加入:

CONFIG += mobility
MOBILITY = contacts
 
QT += webkit \
network

并且还要根据需要添加相应的能力:

symbian: {
TARGET.CAPABILITY = ReadUserData \
WriteUserData
}

类ContactServer中实现了一些供JavaScript调用的方法,首先要在cpp文件中引入头文件并声明QTM_USE_NAMESPACE宏:

#include <QContactManager>
#include <QContact>
#include <QContactName>
 
QTM_USE_NAMESPACE

在getContacts()方法中,我们通过Qt Mobility 的联系人功能访问到了设备中的联系人,并以字符串的形式返回。

QString ContactServer::getContacts()
{
 
QContactManager cm; // instantiate the default manager
QList<QContact> allContacts = cm.contacts();
 
QString temp ="";
for (int i = 0; i < allContacts.size() && i<5 ; ++i) {
QContact aContact = allContacts.at(i) ;
 
temp += "Last name:" +aContact.detail<QContactName>().lastName ()+"<br>" +
"First name:" + aContact.detail<QContactName>().firstName () + "<br>";
}
 
return temp;
}

那么,我们是如何在Javascript中调用这个方法的呢。在文件contractview.cpp中,我们可以看到如下代码:

   QWebView* ContractView::createWebView()
{
QWebSettings* defaultSettings = QWebSettings::globalSettings();
defaultSettings->setAttribute(QWebSettings::JavascriptEnabled, true);
 
 
QWebView* webView = new QWebView(this);
 
connect(webView->page()->mainFrame(),
SIGNAL(javaScriptWindowObjectCleared()),
this,
SLOT(addJavascriptObject()));
 
 
webView->load(QUrl("qrc:/res/contact-sample.html"));
//webView->load(QUrl::fromUserInput("C:/Qt/qtprojects/wrtwrapper/res/contact-sample.html"));
return webView;
}
 
void ContractView::addJavascriptObject()
{
if(this->m_webView) {
this->m_webView->page()->mainFrame()
->addToJavaScriptWindowObject("contactServer",
this->m_contactServer);
 
}
}

在这段代码中,

        QWebSettings* defaultSettings = QWebSettings::globalSettings();
defaultSettings->setAttribute(QWebSettings::JavascriptEnabled, true);

QWebSettings 类提供了访问QWebPage 和QWebFrame中设置的途径。详细的QWebSettings说明可以在Qt联机帮助中找到。

在addJavascriptObject()方法中,

void ContractView::addJavascriptObject()
{
if(this->m_webView) {
this->m_webView->page()->mainFrame()
->addToJavaScriptWindowObject("contactServer",
this->m_contactServer);
 
}
}

我们通过addToJavaScriptWindowObject()方法将ContactServer的实例m_contactServer传递到JavaScript中,但是工作还没有结束。我们发现调用addJavascriptObject()是通过下面这段实现的:

 connect(webView->page()->mainFrame(),
SIGNAL(javaScriptWindowObjectCleared()),
this,
SLOT(addJavascriptObject()));

熟悉Qt消息机制的开发者一眼就可以看出javaScriptWindowObjectCleared()是一个消息(signal), 而addJavascriptObject()则是一个槽(slot),打开头文件contractview.h ,我们发现的确是这样:

 private slots:
void addJavascriptObject();

这样,一旦有消息javaScriptWindowObjectCleared()发出,那么addJavascriptObject()方法就会被调用。通过查阅Qt联机帮助,我们得知每次加载新页面时都会发出这个信号,这样就能保证即使在用户刷新,重新加载页面后,我们的Qt对象m_contactServer在JavaScript中还能访问到。


最后,让我们来看看在JavaScript中是如何调用Qt对象的:

// Get Contact List
function getContactList() {
 
try {
 
document.getElementById(DIV_ID).innerHTML = window.contactServer.getContacts();
 
}
catch (e) {
alert ("getContactList: " + e);
}
}

代码示例: File:ContactWidget.zip

File:Wrtwrapper.zip

This page was last modified on 11 October 2012, at 04:19.
215 page views in the last 30 days.
×