×
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.
221 page views in the last 30 days.

Was this page helpful?

Your feedback about this content is important. Let us know what you think.

 

Thank you!

We appreciate your feedback.

×