Morten Johan Sørvig
Qt
Labs
Internet
 in Qt, Labs, Internet
 on Friday, September 18, 2009 @ 09:18

I’ve been playing with javascript lately, and here’s the result: QWebClient, a thin client for Qt applications. This is a pure Javascript implementation which runs in any modern browser (no plugins required). QWebClient works by starting an http server in the application process, which the browser then connects to. The project currently has research quality - get the source at qt.gitorious.org

webclient-irc.png

Live Demo on hold! Try again later :)

View Source
(The demo itself is running on an Amazon EC2 instance. If you don’t see a live demo here, try reloading the page. If it still doesn’t work something has gone horribly wrong on the server or my credit card has maxed out.)

Prior Art

At this point I’d like to acknowledge the Wt project, which is a forerunner when it comes to C++-driven web applications. The difference between the two projects can be summarized by this table:

Wt QWebClient
Focus Web Toolkit Thin client for Qt apps
Quality Stable code base Greater Hack

User Code

Adding thin client functionality to your application requires two lines of code for a simple one-user thin client. Supporting more than one user requires instantiating several copies if the user interface, which can be more complex depending on the application architecture. On the browser side the client code is equally simple, and if you request index.html from the server you will recieve the code.

Qt Side (Server) Browser Side (Client)
QWidget *rootWidget = ...
QWebClient webclient;
webClient.setRootWidget(&rootWidget);
<html><head>
<script type=”text/javascript” src=”:qwebclient.js” mce_src=”:qwebclient.js”></script>
</head>

<body>
<div class=”qwebclient”></div>
</body>

</html>

(Notice “src=:qwebclient.js”, the Qt resource system syntax has fond its way to the web!)

Scope

I’m targeting the use case where you have a server process running somewhere on a trusted network and want to expose a simple gui controlling it. This means:

  • Simple, Form-like applications only, no animations or high-perforance graphics.
  • Trusted networks only, there is little security. The implementation so far has been done with (eventual) security in mind though, so it’s not hopeless.
  • Limited scalability, support a few users only (check out http://79.125.3.129:1818/statistics to see how the live demo fares)
  • It’s a thin client, all program activity happens on the server (opening file and network connections, etc).

How Does It Work?

1. QWeblient starts a server at a user-configurable port

2. The Web Browser connects to the server and requests index.html. index.html loads qwebclient.js, which contains the thin client source code.

3.The Browser executes onLoad() which asyncronously requests /content from the server. The server replies with a json-encoded div element structure representing the widget hierachy. Common ui elemnts such as line edits are instantiated as native elements on the client side. All other widgets are transferred as images.

4.Keyboard and mouse events are POSTed to the server, which repsonds with content updates

5. When there are no client events, the browser will request /idle with one of its connections. The server will not reply to this request but keep the tcp connection open. (This the long-polling technique.)

6. Server events are sent to the client using the open long-polling connection.

Obligatory Conclusion

This has been a fun project! Crossing over from the C++ world to the web world is interesting, you get to speak http using QTcpSocket on the server side and then debug result in FireBug on the client side.

35 Responses to “Qt in the Cloud with QWebClient”

» Posted by lit-uriy
 on Friday, September 18, 2009 @ 09:38

Hi Morten, My question is not on the topic: In what program you have drawn these pictures?

» Posted by Morten
 on Friday, September 18, 2009 @ 09:42

lit-uriy: Google Docs. Free and works quite well :)

» Posted by SABROG
 on Friday, September 18, 2009 @ 10:33

UML dont leave in here? ;)

Why remove “chat” (client example on javascript)?

May be just write Java Applet on QtJambi?

» Posted by ZeD
 on Friday, September 18, 2009 @ 11:29

@lit-uriy
if you like, there is http://www.websequencediagrams.com when you can “program” a sequence diagram
also, if you don’t like call a browser, you can fetch my little stupid script from http://code.google.com/p/unusefulscripts/source/browse/trunk/websequencediagrams.py to play with

» Posted by OperaUser
 on Friday, September 18, 2009 @ 11:48

This is totally awesome! As I said in the chat (when it was working), I played with QWebView via QWebClient and got it working! But there were a minor issue - When clicking with mouse, widget was receiving wrong information about the point where click occured - I had to click about 30 px below the links in order to open them.

» Posted by Visguy
 on Friday, September 18, 2009 @ 11:53

This is fantastic, I can see a wide range of applications for this kind of thing. I had to make a few patches for it to run on 64bit (thanks to the pointer-to-int casts everywhere), but now it runs better than I expected. Keep up the good work!

» Posted by Piotr Gabryjeluk
 on Friday, September 18, 2009 @ 12:42

Simply brilliant

» Posted by surge
 on Friday, September 18, 2009 @ 13:27

Wt is grate! Some times you able to change W on Q in source code and compile Wt application as Qt.
Explore Wt here
http://www.webtoolkit.eu/widgets#/

» Posted by Scorp1us
 on Friday, September 18, 2009 @ 14:03

This, I think, is awesome! I just hope I understand it. It means that I can now expose my QtGUI apps in a browser? If so ROCK ON. If not, what did I miss?!?

I would like to prod you that an even better way would be to provide a QHttpObjectServer which would be able to use JSON or XML to to AJAX to standard web clients. Then provide a C++ client library, so that we can use one Qt-based server to business logic, but still have a QtGUI app or a web app. The current solution here, while very cool, would cause confusion in the market place because now days EVERYONE uses a browser, and people don’t like that. So many times I am old, “we don’t want a client app, we want a web interface” It goes beyond not having to install a client. They want something that also looks and works like a classical web page. This doesn’t do that.

Still I am very happy about this. It is a step in the right direction.

» Posted by Scorp1us
 on Friday, September 18, 2009 @ 14:06

In my excitement, I posted without proofing.
that we can use one Qt-based server to _DO_ business logic,
because now days EVERYONE uses a browser, and people don’t like that _I provide a GUI app, even if it is cross-platform._

In these days of the web and dynamic interfaces, I think it is a must-do for 4.7…

» Posted by Me@Home
 on Friday, September 18, 2009 @ 14:27

Great, i hope you’ll continue this project!

» Posted by SABROG
 on Friday, September 18, 2009 @ 14:32

surge, i think this is better: http://developer.yahoo.com/yui/

» Posted by profoX
 on Friday, September 18, 2009 @ 15:18

I was thinking about starting a project like this as well a few weeks ago! :)
It would be very cool if this could work as a FastCGI extension in the future.
I think this is a very interesting project, but I do wonder about stuff like 3D, multimedia and QPainter performance on a thin webclient :)

» Posted by Das
 on Friday, September 18, 2009 @ 16:05

Nice demo. It will be nice also than QtNokia fixes the solution to develop browser plugins (fails in Mac for example). This will allow us to execute code in the client at full speed, making possible 3D for example.

» Posted by blubb
 on Friday, September 18, 2009 @ 19:08

Quite interesting to see how the web has evolved! From text-only to table layouts to css to ajax to thin client!!

» Posted by Josh
 on Saturday, September 19, 2009 @ 04:58

I agree with Das that having a solution based on browser plugins that allows for execution of code in the client at full speed would be great. This is great as well though. Really both are *needed* for different use cases. Anyone have a link to a demo of this up somewhere?

» Posted by Josh
 on Saturday, September 19, 2009 @ 05:41

I just got this to compile on my 64-bit machine and it’s great. Thanks! In reference to “Common ui elements such as line edits are instantiated as native elements on the client side. All other widgets are transferred as images.” What widgets can be instantiated as native elements (a list would be helpful)? Also, what would it take for a non-native widget (such as a QTextEdit) to be interactive? I was able to modify an example to get a QTextEdit to come up, but it was unresponsive to keyboard input. I’m assuming I would have to connect changes to the QTextEdit to some sort of repaint.? Thoughts on how to do this?

» Posted by lit-uriy
 on Saturday, September 19, 2009 @ 18:45

Ooops, thanks all

» Posted by lit-uriy
 on Saturday, September 19, 2009 @ 19:10

Morten, my fantasy about the web-application on Qt looks so. We write the application on Qt, but instead of “QApplication” it is necessary to use “QWebApplication”.
:)

» Posted by MB
 on Saturday, September 19, 2009 @ 19:21

Very nice project, I have been searching for this kind of tool for a long time : an “AJAX platform” support for Qt :
- you can have your Qt interface in Windows, Linux, MacOS… why not as a web page ? (ok, low performance graphics only)
- I hate web-specific programming such as AJAX, but it removes the need to distribute a program for thousands of one-time users and allows to centralize collective work on a server.
- I would like a tool to juste add a “CGI/AJAX platform” : the compiled program would be put on a webserver. The program would then take care of input and output with the client (creating AJAX pages for the client browser) without a need for the programmer to do anything more than a standard Qt program.

I have a project that requires a web interface (about 5000 people should go to a web page without installing anything else on their computer, and then use a nice Qt Interface to enter some text data).
I like Python and PyQt a lot, and after some research I found only the pyjamas project (http://pyjs.org) that looks like what I need (programming in Python with the interface compiled to javascript).
Unfortunately, it is not the nice Qt library I am used to…

Do you think your project could be used like this ?
Thank you very much for your work !

» Posted by lit-uriy
 on Saturday, September 19, 2009 @ 20:50

QWebClient+Qwt = http://lit-uriy.narod.ru/temp/screen.png :)
But IRC Does not wish to communicate in Russian: (

» Posted by rec
 on Saturday, September 19, 2009 @ 21:51

This is superb and I urge you to develop it further … the possibilities are endless. Brilliant! I will be watching this very closely.

On a related note, we are currently working on a project that uses JavaScript (we are playing with jQuery) in the browser to request pages and AJAX data from a Qt-based web-server (the pages fetched are stored as Qt resources on the server). To make this work we basically wrote an HTTP server using Qt which though relatively straightforward, has still been a lot of work. I would love Qt to supply web-server classes that could serve up pages/data easily, with all the HTTP work taken care of under the hood. Does anything like this already exist? We actually want something similar to this demo, but with a ‘web’ look-and-feel instead of a Qt one.

» Posted by Alessandro
 on Saturday, September 19, 2009 @ 22:08

@Morten, High five for the great idea and realization! I am sure that many applications will now add web frontends to their Qt apps, since it is so incredibly easy :)
Btw. Golem.de, a very popular IT news website in Germany, wrote about it: http://www.golem.de/0909/69937.html

» Posted by Michael
 on Monday, September 21, 2009 @ 00:16

The idea is great! Some time ago I was thinking about a different approach to the same problem. I think it should be relatively easy to implement VNC server in Qt window. On the other side there are a couple of Flash-based VNC viewers. So, every Qt window is a VNC server which streams its content. I think this approach can be acceptable for some device’s web interface. But in general… Yes, scalability is a big problem.

» Posted by Vaidas
 on Monday, September 21, 2009 @ 05:34

Hey, how to compile this diamond? I’ve getting errors that some constants are missing: LOG_DEBUG, LOG_ERR, LOG_INFO… seems like it’s due to syslog.h is missing.

» Posted by lit-uriy
 on Monday, September 21, 2009 @ 12:41

Vaidas, I adjusted files:
3rdparty/json/config.h
3rdparty/json/json_tokener.c
3rdparty/json/printbuf.c
Since on Win32 they are oriented for Visual Studio
See: http://pastebin.com/m6fc4cf74

» Posted by Morten
 on Monday, September 21, 2009 @ 15:14

Thanks for the coments! I think there are several dircetions (some of them mentioned here) that further development could take, as long as one is aware of the limitations that thin-client based approach has.

If you have patches, please submit them at http://qt.gitorious.org/qt-labs/webclient/merge_requests so I can merge them.

It will be a little while before I get to do that though, as I’m writing this from the maternety ward where my son was born this Saturday :)

» Posted by lit-uriy
 on Monday, September 21, 2009 @ 17:16

Morten, I congratulate on replenishment in a family!

» Posted by Jason
 on Tuesday, September 22, 2009 @ 03:54

Gonna put that demo up again?

» Posted by Vaidas
 on Tuesday, September 22, 2009 @ 05:33

lit-uriy: thank you! your patch helped. Nice…. :)

» Posted by Andrea
 on Tuesday, September 22, 2009 @ 08:59

Does not comile on mac os x.

Undefined symbols:
“_main”, referenced from:
__start in crt1.o
ld: symbol(s) not found
collect2: ld returned 1 exit status

It is a while I don’t get this error … so I don’t remember how to fix it :-)

» Posted by Andrea
 on Tuesday, September 22, 2009 @ 09:13

Sorry. Still sleeping. Forget last post.

» Posted by Lawand
 on Tuesday, September 22, 2009 @ 13:11

I can see how QWebClient and WebGL would become friends :)

» Posted by Adam Higerd
 on Friday, September 25, 2009 @ 20:45

I wonder how your implementation compares to mine. QxtWeb has been under development for over two years and has been in production commercial use for about one, primarily on an embedded ARM device but also on desktop-type hardware. It’s been great for us so far; you’ve gone the step further that I hadn’t gotten around to yet with regards to generating an in-browser GUI. In that regard it looks like we’ve got different opinions and approaches, but I know my target is to be able to take a .ui file and convert it into an AJAX-based web GUI using browser-native controls whenever possible instead of pushing pixmaps.

In a nutshell, I’m quite interested in this.

» Posted by tikis
 on Monday, September 28, 2009 @ 08:04

Nice application. I was recently working for the same goal, marriage of Qt and Web, but in a very different approach. I left a post at the forum, but got not too much attention. If you have time, take a look:

http://labs.trolltech.com/forums/topic/1188?replies=1



© 2008 Nokia Corporation and/or its subsidiaries. Nokia, Qt and their respective logos are trademarks of Nokia Corporation in Finland and/or other countries worldwide.
All other trademarks are property of their respective owners.