×
Namespaces

Variants
Actions
(Difference between revisions)

Porting WRT widgets to Qt applications

From Nokia Developer Wiki
Jump to: navigation, search
seppo_fn (Talk | contribs)
hamishwillee (Talk | contribs)
m (Text replace - "<code cpp>" to "<code cpp-qt>")
 
(11 intermediate revisions by 4 users not shown)
Line 1: Line 1:
[[Category:Qt]][[Category:Web Technology]][[Category:Porting]]
+
{{ArticleMetaData <!-- v1.2 -->
 +
|sourcecode= [[Media:BetaLabsClientQtWebKit.zip]] [[Media:WRTStub v 1 2.zip]]
 +
|installfile= <!-- Link to installation file (e.g. [[Media:The Installation File.sis]]) -->
 +
|devices= <!-- Devices tested against - e.g. ''devices=Nokia 6131 NFC, Nokia C7-00'') -->
 +
|sdk= <!-- SDK(s) built and tested against (e.g. [http://linktosdkdownload/ Qt SDK 1.1.4]) -->
 +
|platform= <!-- Compatible platforms - e.g. Symbian^1 and later, Qt 4.6 and later -->
 +
|devicecompatability= <!-- Compatible devices e.g.: All* (must have internal GPS) -->
 +
|dependencies= <!-- Any other/external dependencies e.g.: Google Maps Api v1.0 -->
 +
|signing= <!-- Signing requirements - empty or one of: Self-Signed, DevCert, Manufacturer -->
 +
|capabilities= <!-- Capabilities required by the article/code example (e.g. Location, NetworkServices. -->
 +
|keywords= <!-- APIs, classes and methods (e.g. QSystemScreenSaver, QList, CBase -->
 +
|language= <!-- Language category code for non-English topics - e.g. Lang-Chinese -->
 +
|translated-by= <!-- [[User:XXXX]] -->
 +
|translated-from-title= <!-- Title only -->
 +
|translated-from-id= <!-- Id of translated revision -->
 +
|review-by= <!-- After re-review: [[User:username]] -->
 +
|review-timestamp= <!-- After re-review: YYYYMMDD -->
 +
|update-by= <!-- After significant update: [[User:username]]-->
 +
|update-timestamp= <!-- After significant update: YYYYMMDD -->
 +
|creationdate= 20091222
 +
|author= [[User:Seppo fn]]
 +
}}
 +
[[Category:Porting]][[Category:Qt]][[Category:MeeGo Harmattan]][[Category:Symbian]][[Category:Symbian Web Runtime]]
 +
{{FeaturedArticle|timestamp=20100328}}
 
=Introduction=
 
=Introduction=
  
Line 12: Line 35:
 
# Click Next.
 
# Click Next.
 
# In the following dialog, you can select the modules that you want to include in your project. Check the QtWebKit module and click Next.
 
# In the following dialog, you can select the modules that you want to include in your project. Check the QtWebKit module and click Next.
# In the following dialog, name your main window class as <tt>WRTWidgetWindow</tt> (the <tt>Class name</tt> field) and uncheck the <tt>Generate form</tt> box (in this project, the UI components are added by hand).
+
# In the following dialog, name your main window class as {{Icode|WRTWidgetWindow}} (the {{Icode|Class name}} field) and uncheck the {{Icode|Generate form}} box (in this project, the UI components are added by hand).
 
# Click Next.
 
# Click Next.
# Review that the proposed changes are correct and click Finish. The project is opened and there are two source files, <tt>main.cpp</tt> and <tt>wrtwidgetwindow.cpp</tt>, which can be found in the '''Sources''' folder in the '''Projects''' view.
+
# Review that the proposed changes are correct and click Finish. The project is opened and there are two source files, {{Icode|main.cpp}} and {{Icode|wrtwidgetwindow.cpp}}, which can be found in the '''Sources''' folder in the '''Projects''' view.
  
  
Now you are ready to write some code! Start by opening the <tt>main.cpp</tt> file and modify it to look like this:
+
Now you are ready to write some code! Start by opening the {{Icode|main.cpp}} file and modify it to look like this:
  
<code cpp>
+
<code cpp-qt>
 
#include <QtGui/QApplication>
 
#include <QtGui/QApplication>
  
Line 35: Line 58:
 
</code>
 
</code>
  
Next, open the header file of the main window, <tt>wrtwidgetwindow.h</tt> (in the '''Headers''' folder in the '''Projects''' view), and modify it to look like this:
+
Next, open the header file of the main window, {{Icode|wrtwidgetwindow.h}} (in the '''Headers''' folder in the '''Projects''' view), and modify it to look like this:
  
<code cpp>
+
<code cpp-qt>
 
#ifndef WRTWIDGETWINDOW_H
 
#ifndef WRTWIDGETWINDOW_H
 
#define WRTWIDGETWINDOW_H
 
#define WRTWIDGETWINDOW_H
Line 65: Line 88:
 
</code>
 
</code>
  
The class, which was declared above, represents the main window of the application. It contains one Qt widget, QWebView (<tt>webView</tt>), which is used for showing the web content (HTML, CSS, JavaScript) on Qt. Next, open the implementation for the class (<tt>wrtwidgetwindow.cpp</tt>) and modify it so that it looks like this:
+
The class, which was declared above, represents the main window of the application. It contains one Qt widget, QWebView ({{Icode|webView}}), which is used for showing the web content (HTML, CSS, JavaScript) on Qt. Next, open the implementation for the class ({{Icode|wrtwidgetwindow.cpp}}) and modify it so that it looks like this:
  
<code cpp>
+
<code cpp-qt>
 
#include "wrtwidgetwindow.h"
 
#include "wrtwidgetwindow.h"
  
Line 108: Line 131:
 
=Showing the web content from Qt=
 
=Showing the web content from Qt=
  
Let's add your existing WRT widget to the project (if you don't have one, grab one from here, for example: [http://www.forum.nokia.com/piazza/wiki/images/c/cf/WRTStub_v_1_2.zip Web Runtime Stub]). Copy the HTML, CSS, JavaScript, and resource files (such as graphic files) into your Qt project. It is most easily done by using the file manager and copying the respective folders into your project's root directory as a whole (you have the web content in separate folders, don't you?). The directory structure of your widget could look like this, for example:
+
Let's add your existing WRT widget to the project (if you don't have one, grab one from here, for example: [[Media:WRTStub v 1 2.zip|Web Runtime Stub]]). Copy the HTML, CSS, JavaScript, and resource files (such as graphic files) into your Qt project. It is most easily done by using the file manager and copying the respective folders into your project's root directory as a whole (you have the web content in separate folders, don't you?). The directory structure of your widget could look like this, for example:
  
 
<code>
 
<code>
Line 117: Line 140:
 
</code>
 
</code>
  
In order to use the web content from the Qt application, you must create a resource file in your project and add the content into it. To create the resource file, select '''File''' > '''New File or Project...''' > '''Qt''' > '''Qt Resource file''' and click OK. Give the resource file a name and set its location. Click Next and make sure that the resource file is added to your project (the '''Add to Project''' checkbox and the '''Project''' drop-down list). Click Finish. The resource file is created and will be automatically added as a resource into the <tt>.pro</tt> file of the project. Open the resource file in Qt Creator's plain text editor by right-clicking on it in the '''Projects''' view and selecting '''Open With''' > '''Plain Text Editor'''. Add the web content to the resource file as follows:
+
In order to use the web content from the Qt application, you must create a resource file in your project and add the content into it. To create the resource file, select '''File''' > '''New File or Project...''' > '''Qt''' > '''Qt Resource file''' and click OK. Give the resource file a name and set its location. Click Next and make sure that the resource file is added to your project (the '''Add to Project''' checkbox and the '''Project''' drop-down list). Click Finish. The resource file is created and will be automatically added as a resource into the {{Icode|.pro}} file of the project. Open the resource file in Qt Creator's plain text editor by right-clicking on it in the '''Projects''' view and selecting '''Open With''' > '''Plain Text Editor'''. Add the web content to the resource file as follows:
  
 
<code xml>
 
<code xml>
Line 139: Line 162:
 
</code>
 
</code>
  
The resources are now compiled into the Qt application, but they are not used for anything yet. To access the resources from within the HTML file, you must prepend the relative paths to them with "<tt>qrc:/</tt>". For example, if the main HTML file of the WRT widget contained these lines:
+
The resources are now compiled into the Qt application, but they are not used for anything yet. To access the resources from within the HTML file, you must prepend the relative paths to them with "{{Icode|qrc:/}}". For example, if the main HTML file of the WRT widget contained these lines:
  
 
<code xml>
 
<code xml>
Line 155: Line 178:
 
</code>
 
</code>
  
Change all the paths in the HTML files (this doesn't concern the CSS files, they work like before) as instructed above, and make this final change before you can try out your widget: Open the <tt>wrtwidgetwindow.cpp</tt> file again and load the main HTML file into the QWebView component with the following code:
+
Change all the paths in the HTML files (this doesn't concern the CSS files, they work like before) as instructed above, and make this final change before you can try out your widget: Open the {{Icode|wrtwidgetwindow.cpp}} file again and load the main HTML file into the QWebView component with the following code:
  
<code cpp>
+
<code cpp-qt>
 
QWebView* WRTWidgetWindow::createWebView()
 
QWebView* WRTWidgetWindow::createWebView()
 
{
 
{
Line 166: Line 189:
 
</code>
 
</code>
  
Voilà! Go ahead and clean and build your Qt application now ('''Build''' > '''Rebuild Project'''). Along with other files, the resources are compiled into the application. Then, run the application ('''Build''' > '''Run''' or <tt>Ctrl+R</tt>). The HTML file that you loaded above appears in the QWebKit component.
+
Voilà! Go ahead and clean and build your Qt application now ('''Build''' > '''Rebuild Project'''). Along with other files, the resources are compiled into the application. Then, run the application ('''Build''' > '''Run''' or {{Icode|Ctrl+R}}). The HTML file that you loaded above appears in the QWebKit component.
  
 
=Porting Considerations=
 
=Porting Considerations=
  
It was assumed above that the HTML file of the widget is relatively simple (such as the one in the [http://www.forum.nokia.com/piazza/wiki/images/c/cf/WRTStub_v_1_2.zip WRT Stub application]). More often than not, this is not the case. This chapter presents several issues to consider when porting WRT widgets to Qt applications.
+
It was assumed above that the HTML file of the widget is relatively simple (such as the one in the [[Media:WRTStub v 1 2.zip|WRT Stub application]]). More often than not, this is not the case. This chapter presents several issues to consider when porting WRT widgets to Qt applications.
  
 
==Web Runtime API==
 
==Web Runtime API==
  
In addition to the standard JavaScript objects, there are extension APIs in WRT that allow widgets to access system properties, for example. For a list of these objects, see [http://library.forum.nokia.com/topic/Web_Developers_Library/GUID-7C69DDA4-16F1-4A8F-BDB2-4CB0015B4E81.html Web Runtime API reference in Web Developer's Library]. Because these objects are WRT-specific, they won't be understood by Qt. For example, the code that hides the softkeys looks like this:
+
In addition to the standard JavaScript objects, there are extension APIs in WRT that allow widgets to access system properties, for example. For a list of these objects, see [http://www.developer.nokia.com/Resources/Library/Web/ Web Runtime API reference in Web Developer's Library]. Because these objects are WRT-specific, they won't be understood by Qt. For example, the code that hides the softkeys looks like this:
  
 
<code javascript>
 
<code javascript>
Line 182: Line 205:
 
It must be removed from the Qt application in order to execute the JavaScript, and another way to accomplish the same result must be implemented, if needed. For example, to hide the softkeys you can show the application in fullscreen:
 
It must be removed from the Qt application in order to execute the JavaScript, and another way to accomplish the same result must be implemented, if needed. For example, to hide the softkeys you can show the application in fullscreen:
  
<code cpp>
+
<code cpp-qt>
 
WRTWidgetWindow widget;
 
WRTWidgetWindow widget;
 
widget.showFullScreen();
 
widget.showFullScreen();
Line 189: Line 212:
 
==S60 Platform Services==
 
==S60 Platform Services==
  
WRT provides several JavaScript service APIs for accessing [http://library.forum.nokia.com/topic/Web_Developers_Library/GUID-46EABDC1-37CB-412A-ACAD-1A1A9466BB68.html#GUID-46EABDC1-37CB-412A-ACAD-1A1A9466BB68 S60 Platform Services]. As the name suggests, these APIs are S60-specific (and WRT-specific), so they won't be understood by Qt. In a QtWebKit application, there will be two alternatives for Platform services. For C++ developers, [http://qt.gitorious.org/qt-mobility Qt Mobility APIs] are a good choice. They are being developed and will eventually offer the same kind of functionality. Also, the [[Qt hybrid applications|Qt hybrid application framework]] that Nokia is developing will provide that kind of functionality. The benefit of the latter one is that the underlying services can be accessed using pure web technologies.
+
WRT provides several JavaScript service APIs for accessing [http://www.developer.nokia.com/Resources/Library/Web/#GUID-46EABDC1-37CB-412A-ACAD-1A1A9466BB68 S60 Platform Services]. As the name suggests, these APIs are S60-specific (and WRT-specific), so they won't be understood by Qt. In a QtWebKit application, there will be two alternatives for Platform services. For C++ developers, [http://qt.gitorious.org/qt-mobility Qt Mobility APIs] are a good choice. They are being developed and will eventually offer the same kind of functionality. Also, the [[Qt hybrid applications|Qt hybrid application framework]] that Nokia is developing will provide that kind of functionality. The benefit of the latter one is that the underlying services can be accessed using pure web technologies.
  
 
==Dynamic Scalability==
 
==Dynamic Scalability==
  
Handling orientation changes dynamically is important when designing usable mobile applications. The technique presented in the snippets "[[CS001498 - Detecting orientation changes in WRT]]" and "[[CS001499 - Reacting to the changes in screen size in WRT]]" works fine in Qt, because the JavaScript event <tt>onresize</tt> can be used also from within the QWebKit component to take care of the scalability. The only thing that you may want to take into account is to set the resolution to a fixed value on platforms that don't support orientation changes (for example, desktop Windows and Linux). Here is the code that accomplishes this:
+
Handling orientation changes dynamically is important when designing usable mobile applications. The technique presented in the snippets "[[Detecting orientation changes in Symbian Web Runtime]]" and "[[Reacting to the changes in screen size in Symbian Web Runtime]]" works fine in Qt, because the JavaScript event {{Icode|onresize}} can be used also from within the QWebKit component to take care of the scalability. The only thing that you may want to take into account is to set the resolution to a fixed value on platforms that don't support orientation changes (for example, desktop Windows and Linux). Here is the code that accomplishes this:
  
<code cpp>
+
<code cpp-qt>
 
WRTWidgetWindow widget;
 
WRTWidgetWindow widget;
 
#if defined Q_OS_SYMBIAN || defined Q_WS_HILDON
 
#if defined Q_OS_SYMBIAN || defined Q_WS_HILDON
Line 209: Line 232:
 
==Calling Qt Code from JavaScript==
 
==Calling Qt Code from JavaScript==
  
At some point, there may be a need to call Qt code from JavaScript. One such case is closing the application. The JavaScript code "<tt>window.close()</tt>", which would normally close the window, cannot be used to close a window in Qt. For that, you will need to write some Qt code and call it from JavaScript. Here's the Qt function that exits the application:
+
At some point, there may be a need to call Qt code from JavaScript. One such case is closing the application. The JavaScript code "{{Icode|window.close()}}", which would normally close the window, cannot be used to close a window in Qt. For that, you will need to write some Qt code and call it from JavaScript. Here's the Qt function that exits the application:
  
<code cpp>
+
<code cpp-qt>
 
#include <QtGui/QApplication>
 
#include <QtGui/QApplication>
  
Line 222: Line 245:
 
In order to call this function from JavaScript, you will need to make the Qt class available to 'the JavaScript side' (or in more technical terms, from within QWebFrame's JavaScript context). Add the following function to the class:
 
In order to call this function from JavaScript, you will need to make the Qt class available to 'the JavaScript side' (or in more technical terms, from within QWebFrame's JavaScript context). Add the following function to the class:
  
<code cpp>
+
<code cpp-qt>
 
#include <QtWebKit/QWebFrame>
 
#include <QtWebKit/QWebFrame>
  
Line 236: Line 259:
 
The above function should be called when the QWebView component is created:
 
The above function should be called when the QWebView component is created:
  
<code cpp>
+
<code cpp-qt>
 
QWebView* WRTWidgetWindow::createWebView()
 
QWebView* WRTWidgetWindow::createWebView()
 
{
 
{
Line 252: Line 275:
 
Also add the necessary function declarations into the header file:
 
Also add the necessary function declarations into the header file:
  
<code cpp>
+
<code cpp-qt>
 
public:
 
public:
 
     void close();
 
     void close();
Line 260: Line 283:
 
</code>
 
</code>
  
After these steps, you can write a JavaScript function which calls WRTWidgetWindow's <tt>close()</tt> function .
+
After these steps, you can write a JavaScript function which calls WRTWidgetWindow's {{Icode|close()}} function .
  
 
<code javascript>
 
<code javascript>
Line 277: Line 300:
 
=Example project=
 
=Example project=
  
The original BetaLabs widget can be downloaded at [http://www.forum.nokia.com/info/sw.nokia.com/id/60bbf194-224a-44eb-b352-da5ad53069fe/Web_Run-Time_BetaLabsWidget_Example.html http://www.forum.nokia.com/info/sw.nokia.com/id/60bbf194-224a-44eb-b352-da5ad53069fe/Web_Run-Time_BetaLabsWidget_Example.html]
+
The original BetaLabs widget can be downloaded at [http://www.developer.nokia.com/info/sw.nokia.com/id/60bbf194-224a-44eb-b352-da5ad53069fe/Web_Run-Time_BetaLabsWidget_Example.html http://www.developer.nokia.com/info/sw.nokia.com/id/60bbf194-224a-44eb-b352-da5ad53069fe/Web_Run-Time_BetaLabsWidget_Example.html]
  
The first version of the ported application is available at [[File:BetaLabsClientQtWebKit.zip]]
+
The first version of the ported application is available at [[File:BetaLabsClientQtWebKit.zip]].
  
 
=Related documentation=
 
=Related documentation=
Line 287: Line 310:
 
* [[Calling an exposed QObject slot from Qt WebKit with JavaScript]]
 
* [[Calling an exposed QObject slot from Qt WebKit with JavaScript]]
 
* [[Connecting to a QObjects signal with JavaScript slot in Qt WebKit]]
 
* [[Connecting to a QObjects signal with JavaScript slot in Qt WebKit]]
 +
 +
=QtWebKitStub=
 +
 +
There is also a template application available to make it simpler to start developing your own QtWebKit applications. To download it, go to [[QtWebKitStub]].
 +
[[Category:Code Examples]]

Latest revision as of 04:18, 11 October 2012

Article Metadata
Code ExampleCompatibility
Platform(s):
Symbian
Article
Created: seppo_fn (22 Dec 2009)
Last edited: hamishwillee (11 Oct 2012)
Featured Article
28 Mar
2010

Contents

[edit] Introduction

This article provides Web developers with information about porting Web Runtime (WRT) widgets to Qt applications. The IDE used here is Qt Creator, but basic principles should apply to other IDEs, such as NetBeans or Eclipse, as well.

[edit] Creating a Qt Application with a QWebView Component

  1. Start the Qt Creator IDE.
  2. Select File > New File or Project... > Projects > Qt4 Gui Application.
  3. Click OK.
  4. Give the project a name and set its location.
  5. Click Next.
  6. In the following dialog, you can select the modules that you want to include in your project. Check the QtWebKit module and click Next.
  7. In the following dialog, name your main window class as WRTWidgetWindow (the Class name field) and uncheck the Generate form box (in this project, the UI components are added by hand).
  8. Click Next.
  9. Review that the proposed changes are correct and click Finish. The project is opened and there are two source files, main.cpp and wrtwidgetwindow.cpp, which can be found in the Sources folder in the Projects view.


Now you are ready to write some code! Start by opening the main.cpp file and modify it to look like this:

#include <QtGui/QApplication>
 
#include "wrtwidgetwindow.h"
 
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
 
WRTWidgetWindow window;
window.show();
 
return app.exec();
}

Next, open the header file of the main window, wrtwidgetwindow.h (in the Headers folder in the Projects view), and modify it to look like this:

#ifndef WRTWIDGETWINDOW_H
#define WRTWIDGETWINDOW_H
 
#include <QtCore/QPointer>
#include <QtGui/QMainWindow>
 
class QWebView;
 
class WRTWidgetWindow : public QMainWindow
{
Q_OBJECT
 
public:
WRTWidgetWindow(QWidget *parent = 0);
~WRTWidgetWindow();
 
private:
void setupUI();
QWebView* createWebView();
 
private:
QPointer<QWebView> webView;
};
 
#endif // WRTWIDGETWINDOW_H

The class, which was declared above, represents the main window of the application. It contains one Qt widget, QWebView (webView), which is used for showing the web content (HTML, CSS, JavaScript) on Qt. Next, open the implementation for the class (wrtwidgetwindow.cpp) and modify it so that it looks like this:

#include "wrtwidgetwindow.h"
 
#include <QtGui/QFrame>
#include <QtGui/QVBoxLayout>
#include <QtWebKit/QWebView>
 
WRTWidgetWindow::WRTWidgetWindow(QWidget *parent)
: QMainWindow(parent)
{
setupUI();
}
 
WRTWidgetWindow::~WRTWidgetWindow()
{
webView->deleteLater();
}
 
void WRTWidgetWindow::setupUI()
{
QFrame* cw = new QFrame(this);
setCentralWidget(cw);
 
QVBoxLayout* layout = new QVBoxLayout(cw);
cw->setLayout(layout);
 
webView = createWebView();
layout->addWidget(webView);
}
 
QWebView* WRTWidgetWindow::createWebView()
{
QWebView* view = new QWebView(this);
return view;
}

After this, the application can be compiled and run. You can try this, even though the application doesn't do much yet; there's only an empty QWebView component on the screen.

[edit] Showing the web content from Qt

Let's add your existing WRT widget to the project (if you don't have one, grab one from here, for example: Web Runtime Stub). Copy the HTML, CSS, JavaScript, and resource files (such as graphic files) into your Qt project. It is most easily done by using the file manager and copying the respective folders into your project's root directory as a whole (you have the web content in separate folders, don't you?). The directory structure of your widget could look like this, for example:

html/   (HTML files)
style/ (CSS files)
script/ (JavaScript files)
gfx/ (graphics)

In order to use the web content from the Qt application, you must create a resource file in your project and add the content into it. To create the resource file, select File > New File or Project... > Qt > Qt Resource file and click OK. Give the resource file a name and set its location. Click Next and make sure that the resource file is added to your project (the Add to Project checkbox and the Project drop-down list). Click Finish. The resource file is created and will be automatically added as a resource into the .pro file of the project. Open the resource file in Qt Creator's plain text editor by right-clicking on it in the Projects view and selecting Open With > Plain Text Editor. Add the web content to the resource file as follows:

<?xml version="1.0" encoding="utf-8"?>
<RCC version="1.0">
<qresource>
<!-- HTML files -->
<file>html/index.html</file>
 
<!-- CSS files -->
<file>style/general.css</file>
 
<!-- JavaScript files -->
<file>script/common.js</file>
<file>script/main.js</file>
 
<!-- Graphics -->
<file>gfx/icon.png</file>
</qresource>
</RCC>

The resources are now compiled into the Qt application, but they are not used for anything yet. To access the resources from within the HTML file, you must prepend the relative paths to them with "qrc:/". For example, if the main HTML file of the WRT widget contained these lines:

<link rel="stylesheet" href="style/general.css" type="text/css" />
<script type="text/javascript" src="script/common.js" charset="utf-8"></script>
<script type="text/javascript" src="script/main.js" charset="utf-8"></script>

then the main HTML file in the Qt application would contain these lines:

<link rel="stylesheet" href="qrc:/style/general.css" type="text/css" />
<script type="text/javascript" src="qrc:/script/common.js" charset="utf-8"></script>
<script type="text/javascript" src="qrc:/script/main.js" charset="utf-8"></script>

Change all the paths in the HTML files (this doesn't concern the CSS files, they work like before) as instructed above, and make this final change before you can try out your widget: Open the wrtwidgetwindow.cpp file again and load the main HTML file into the QWebView component with the following code:

QWebView* WRTWidgetWindow::createWebView()
{
QWebView* view = new QWebView(this);
view->load(QUrl("qrc:/html/index.html"));
return view;
}

Voilà! Go ahead and clean and build your Qt application now (Build > Rebuild Project). Along with other files, the resources are compiled into the application. Then, run the application (Build > Run or Ctrl+R). The HTML file that you loaded above appears in the QWebKit component.

[edit] Porting Considerations

It was assumed above that the HTML file of the widget is relatively simple (such as the one in the WRT Stub application). More often than not, this is not the case. This chapter presents several issues to consider when porting WRT widgets to Qt applications.

[edit] Web Runtime API

In addition to the standard JavaScript objects, there are extension APIs in WRT that allow widgets to access system properties, for example. For a list of these objects, see Web Runtime API reference in Web Developer's Library. Because these objects are WRT-specific, they won't be understood by Qt. For example, the code that hides the softkeys looks like this:

window.menu.hideSoftkeys();

It must be removed from the Qt application in order to execute the JavaScript, and another way to accomplish the same result must be implemented, if needed. For example, to hide the softkeys you can show the application in fullscreen:

WRTWidgetWindow widget;
widget.showFullScreen();

[edit] S60 Platform Services

WRT provides several JavaScript service APIs for accessing S60 Platform Services. As the name suggests, these APIs are S60-specific (and WRT-specific), so they won't be understood by Qt. In a QtWebKit application, there will be two alternatives for Platform services. For C++ developers, Qt Mobility APIs are a good choice. They are being developed and will eventually offer the same kind of functionality. Also, the Qt hybrid application framework that Nokia is developing will provide that kind of functionality. The benefit of the latter one is that the underlying services can be accessed using pure web technologies.

[edit] Dynamic Scalability

Handling orientation changes dynamically is important when designing usable mobile applications. The technique presented in the snippets "Detecting orientation changes in Symbian Web Runtime" and "Reacting to the changes in screen size in Symbian Web Runtime" works fine in Qt, because the JavaScript event onresize can be used also from within the QWebKit component to take care of the scalability. The only thing that you may want to take into account is to set the resolution to a fixed value on platforms that don't support orientation changes (for example, desktop Windows and Linux). Here is the code that accomplishes this:

WRTWidgetWindow widget;
#if defined Q_OS_SYMBIAN || defined Q_WS_HILDON
// On Symbian and Maemo, show the widget in full screen
widget.showFullScreen();
#elif defined Q_OS_WIN32 || defined Q_OS_LINUX
// On desktop Windows and Linux, show the widget in WVGA resolution
widget.setFixedSize(800, 480);
widget.show();
#endif

[edit] Calling Qt Code from JavaScript

At some point, there may be a need to call Qt code from JavaScript. One such case is closing the application. The JavaScript code "window.close()", which would normally close the window, cannot be used to close a window in Qt. For that, you will need to write some Qt code and call it from JavaScript. Here's the Qt function that exits the application:

#include <QtGui/QApplication>
 
void WRTWidgetWindow::close()
{
QApplication::exit();
}

In order to call this function from JavaScript, you will need to make the Qt class available to 'the JavaScript side' (or in more technical terms, from within QWebFrame's JavaScript context). Add the following function to the class:

#include <QtWebKit/QWebFrame>
 
void WRTWidgetWindow::addJavaScriptObject()
{
// Make the WRTWidgetWindow available from within the QWebFrame's
// JavaScript context (as variable "clientApp")
this->webView->page()->mainFrame()->addToJavaScriptWindowObject("clientApp",
this);
}

The above function should be called when the QWebView component is created:

QWebView* WRTWidgetWindow::createWebView()
{
QWebView* view = new QWebView(this);
// Call the addJavaScriptObject slot when the javaScriptWindowObjectCleared
// signal is emitted, i.e. before the loading of the new window object
// starts
connect(view->page()->mainFrame(), SIGNAL(javaScriptWindowObjectCleared()),
this, SLOT(addJavaScriptObject()));
view->load(QUrl("qrc:/html/index.html"));
return view;
}

Also add the necessary function declarations into the header file:

public:
void close();
 
private slots:
void addJavaScriptObject();

After these steps, you can write a JavaScript function which calls WRTWidgetWindow's close() function .

// Exits the application
function exit() {
clientApp.close();
}

Finally, call the JavaScript function. From HTML, for example:

<input id="btnExit" type="button" onclick="exit();" value="Exit" />

[edit] Example project

The original BetaLabs widget can be downloaded at http://www.developer.nokia.com/info/sw.nokia.com/id/60bbf194-224a-44eb-b352-da5ad53069fe/Web_Run-Time_BetaLabsWidget_Example.html

The first version of the ported application is available at File:BetaLabsClientQtWebKit.zip.

[edit] Related documentation

For more information, refer to the following code snippets:

[edit] QtWebKitStub

There is also a template application available to make it simpler to start developing your own QtWebKit applications. To download it, go to QtWebKitStub.

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