The Complete Magazine on Open Source

QT-Webkit: A Quick Way to Develop A Destop or Mobile App

SHARE
/ 271 0

Smartphone-develop

Qt-WebKit, a major engine that can render Web pages and execute JavaScript code, is the answer to the developer’s prayer. Let’s take a look at a few examples that will aid developers in making better use of this engine.

This article is for Qt developers. It is assumed that the intended audience is aware of the famous Signals and Slots mechanisms of Qt. Creating an HTML page is very quick compared to any other way of designing a GUI. An HTML page is nothing but a fancy page that doesn’t have any logic in its build. With the amalgamation of JavaScript, however, the HTML page builds in some intelligence. As everything cannot be collated in JavaScript, we need a back-end for it. Qt provides a way to mingle (HTML+Java) with C++. Thus, you can call the C++ methods through JavaScripts and vice-versa. This is possible by using the Qt-WebKit framework. The applications developed in Qt are not just limited to various desktop platforms. They are even ported over several mobile platforms. Thus, you can design your apps that can just fit into the Windows, iOS and Android worlds, seamlessly.

What is Qt-WebKit?
In simple words, Qt-WebKit is the Web-browsing module of Qt. It can be used to display live content from the Internet as well as local HTML files.

Programming paradigm
In Qt-WebKit, the base class is known as QWebView. The sub-class of QWebView is QWebViewPage, and a further sub-class is QWebFrame. This is useful while adding the desired class object to the JavaScript window object. In short, this class object will be visible to JavaScript once it is added to the JavaScript window object. However, JavaScript can invoke only the public Q_INVOKABLE methods. The Q_INVOKABLE restriction was introduced to make the applications being developed using Qt even more secure.

Q_INVOKABLE
This is a macro that is similar to Slot, except that it has a return type. Thus, we will prefix Q_INVOKABLE to the methods that can be called by the JavaScript. The advantage here is that we can have a return type with Q_INVOKABLE, as compared to Slot.

Developing a sample HTML page with JavaScript intelligence
Here is a sample form in HTML-JavaScript that will allow us to multiply any two given numbers. However, the logic of multiplication should reside in the C++ method only.

<html>
<head>
<script>
function Multiply()
{
/** MultOfNumbers a C++ Invokable method **/
var result = myoperations.MultOfNumbers(document.forms["DEMO_FORM"]["Multiplicant_A"].value, document.forms["DEMO_FORM"]["Multiplicant_B"].value);
document.getElementById("answer").value = result;
}
</script>
</head>
<body>
<form name="DEMO_FORM">
Multiplicant A: <input type="number" name="Multiplicant_A"><br>
Multiplicant B: <input type="number" name="Multiplicant_B"><br>
Result: <input type="number" id="answer" name="Multiplicant_C"><br>
<input type="button" value="Multiplication_compute_on_C++" onclick="Multiply()">
</form>
</body>
</html>

Please note that in the above HTML code, myoperations is a class object. And MultOfNumbers is its public Q_Invokable class method.

How to call the C++ methods from the Web page using the Qt-WebKit framework
Let’s say, I have the following class that has the
Q_Invokable method, MultOfNumbers.

class MyJavaScriptOperations : public QObject {
Q_OBJECT
public:
Q_INVOKABLE qint32 MultOfNumbers(int a, int b) {
qDebug() << a * b;
return (a*b);
}
};

This class object should be added to the JavaScript window object by the following API:

addToJavaScriptWindowObject("name of the object", new (class that can be accessed))

Here is the entire program:

#include <QtGui/QApplication>
#include <QApplication>
#include <QDebug>
#include <QWebFrame>
#include <QWebPage>
#include <QWebView>

class MyJavaScriptOperations : public QObject {
Q_OBJECT
public:
Q_INVOKABLE qint32 MultOfNumbers(int a, int b) {
qDebug() << a * b;
return (a*b);
}
};

int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QWebView *view = new QWebView();
view->resize(400, 500);
view->page()->mainFrame()->addToJavaScriptWindowObject("myoperations", new MyJavaScriptOperations);
view->load(QUrl("./index.html"));
view->show();
return a.exec();
}
#include "main.moc"
Figure 1

Figure 1 : QT DEMO output

The output is given in Figure 1.

How to install a callback from C++ code to the Web page using the Qt-WebKit framework
We have already seen the call to C++ methods by JavaScript. Now, how about a callback from C++ to JavaScript? Yes, it is possible with the Qt-WebKit. There are two ways to do so. However, for the sake of neatness in design, let’s discuss only the Signals and Slots mechanisms for the JavaScript callback.
Installing Signals and Slots for the JavaScript function
Here are the steps that need to be taken for the callback to be installed:
a) Add a JavaScript window object to the javaScriptWindowObjectCleared slot.
b) Declare a signal in the class.
c) Emit the signal.
d) In JavaScript, connect the signal to the JavaScript function slot.
Here is the syntax to help you connect:

<JavaScript_window_object>.<signal_name>.connect(<JavaScript function name>);

Note, you can make a callback to JavaScript only after the Web page is loaded. This can be ensured by connecting to the Slot emitted by the Signal loadFinished() in the C++ application.
Let’s look at a real example now. This will fire a callback once the Web page is loaded.
The callback should be addressed by the JavaScript function, which will show up an alert window.

<html>
<head>
<script>
function alert_click()
{
alert("you clicked");
}
function JavaScript_function()
{
alert("Hello");
}
myoperations.alert_script_signal.connect(JavaScript_function);
</script>
</head>
<body>
<form name="myform">
<input type="button" value="Hit me" onclick="alert_click()">
</form>
</body>
</html>

Here is the main file:

#include <QtGui/QApplication>
#include <QApplication>
#include <QDebug>
#include <QWebFrame>
#include <QWebPage>
#include <QWebView>
class MyJavaScriptOperations : public QObject {
Q_OBJECT
public:
QWebView *view;
MyJavaScriptOperations();
signals:
void  alert_script_signal();
public slots:
void JS_ADDED();
void loadFinished(bool);
};

void MyJavaScriptOperations::JS_ADDED()
{
qDebug()<<__PRETTY_FUNCTION__;
view->page()->mainFrame()->addToJavaScriptWindowObject("myoperations", this);
}

void MyJavaScriptOperations::loadFinished(bool oper)
{
qDebug()<<__PRETTY_FUNCTION__<< oper;
emit alert_script_signal();
}

MyJavaScriptOperations::MyJavaScriptOperations()
{
qDebug()<<__PRETTY_FUNCTION__;
view = new QWebView();
view->resize(400, 500);
connect(view->page()->mainFrame(), SIGNAL(javaScriptWindowObjectCleared()), this, SLOT(JS_ADDED()));
connect(view, SIGNAL(loadFinished(bool)), this, SLOT(loadFinished(bool)));
view->load(QUrl("./index.html"));
view->show();
}
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MyJavaScriptOperations *jvs = new MyJavaScriptOperations;
return a.exec();
}
#include "main.moc"
Figure 2

Figure 2 : QT DEMO callback output

The output is shown in Figure 2.

Qt is a rich framework for C++ developers. It not only provides these amazing features, but also has some interesting attributes like in-built SQlite, D-Bus and various containers. It’s easy to develop an entire GUI application with it. You can even port an existing HTML page to Qt. This makes Qt a wonderful choice to develop a cross-platform application quickly. It is now getting popular in the mobile world too.