Qt in the Cloud with QWebClient

Posted by Morten Johan Sørvig on September 18, 2009 · 35 comments

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.

QShare(this)

Possibly related posts:

  1. QtDemo is no longer my Twitter client
  2. Touching the X11
  3. Multi-process Lighthouse
  4. HTTP caching with Qt

35 comments

1 lit-uriy September 18, 2009 at 11:38 am
 

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

2 Morten September 18, 2009 at 11:42 am
 

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

3 SABROG September 18, 2009 at 12:33 pm
 

UML dont leave in here? ;)

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

May be just write Java Applet on QtJambi?

4 ZeD September 18, 2009 at 1:29 pm
 

@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

5 OperaUser September 18, 2009 at 1:48 pm
 

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.

6 Visguy September 18, 2009 at 1:53 pm
 

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!

7 Piotr Gabryjeluk September 18, 2009 at 2:42 pm
 

Simply brilliant

8 surge September 18, 2009 at 3:27 pm
 

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#/

9 Scorp1us September 18, 2009 at 4:03 pm
 

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.

10 Scorp1us September 18, 2009 at 4:06 pm
 

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…

11 Me@Home September 18, 2009 at 4:27 pm
 

Great, i hope you’ll continue this project!

12 SABROG September 18, 2009 at 4:32 pm
 

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

13 profoX September 18, 2009 at 5:18 pm
 

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 :)

14 Das September 18, 2009 at 6:05 pm
 

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.

15 blubb September 18, 2009 at 9:08 pm
 

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

16 Josh September 19, 2009 at 6:58 am
 

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?

17 Josh September 19, 2009 at 7:41 am
 

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?

18 lit-uriy September 19, 2009 at 8:45 pm
 

Ooops, thanks all

19 lit-uriy September 19, 2009 at 9:10 pm
 

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”. :)

20 MB September 19, 2009 at 9:21 pm
 

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 !

21 lit-uriy September 19, 2009 at 10:50 pm
 

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

22 rec September 19, 2009 at 11:51 pm
 

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.

23 Alessandro September 20, 2009 at 12:08 am
 

@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

24 Michael September 21, 2009 at 2:16 am
 

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.

25 Vaidas September 21, 2009 at 7:34 am
 

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.

26 lit-uriy September 21, 2009 at 2:41 pm
 

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

27 Morten September 21, 2009 at 5:14 pm
 

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 :)

28 lit-uriy September 21, 2009 at 7:16 pm
 

Morten, I congratulate on replenishment in a family!

29 Jason September 22, 2009 at 5:54 am
 

Gonna put that demo up again?

30 Vaidas September 22, 2009 at 7:33 am
 

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

31 Andrea September 22, 2009 at 10:59 am
 

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 :-)

32 Andrea September 22, 2009 at 11:13 am
 

Sorry. Still sleeping. Forget last post.

33 Lawand September 22, 2009 at 3:11 pm
 

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

34 Adam Higerd September 25, 2009 at 10:45 pm
 

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.

35 tikis September 28, 2009 at 10:04 am
 

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

Comments on this entry are closed.

Previous post:

Next post: