Planet Qt - Highlighting Qt development and applications

Planet Qt needs your help. Submit rss/atom feeds to your favorite blogs about Qt development or news about Qt Applications. For developers that only occasionally blog about Qt use the rss feed for articles tagged with Qt.

July 30, 2010

Attila Csipa

Where are those mobile Qt apps ? (Part 3, Resolution)

After a short historical overview and a short list of growing pains, in this, third installment of the mobile Qt app story, I will focus on what boulders remain in the path of widespread adoption of Qt among app mobile developers. Most of the technical groundwork has been laid down, but to reach a final resolution, it needs to include a bit more than just a healthy base.


Decouple Qt releases from firmware releases

As seen from the infamous PR1.2 delay, a coupled-with-the-firmware release cycle is detrimental to the platform. If multiple devices are on the market, it would mean instant-fragmentation as developers would have to code for the Qt released with the last firmware. This is eating Android alive, too, as various handsets have different upgrade cycles. A separate distribution mechanism HAS to be employed. It will be tricky as with MeeGo and Symbian^4 Qt is part of the OS and many teams will be reluctant to bet firmware functionality on the backward compatibility of Qt. But that is not the only thing that can cause fragmentation if it isn't true that...

One mobile widget framework is enough


I harp about this regularly (and will continue to do so until I get good news from an official source :), the option to have separate widget frameworks for Symbian (Orbit/uiemo) and MeeGo (DirectUI/MeeGo Touch Framework) is something that is completely against what Qt is trying to accomplish by bridging the two OS-es. 

All you bases are belong to us

Qt is almost a country of it's own, addressing (or having a development version that addresses) various aspects of software development, both mobile and desktop. However, there is one thing where it is sorely lacking - the wizz-bang games department. Yes, QGraphicsView and 3D enablers are cool and all, but that is not enough (even with QML and UI scripting). It would certainly be an overkill and unnecessary delay to implement a complete game engine in Qt, but there are alternatives - make a Unity3D port, or, better yet, in the spirit of open source, sponsor Ogre binding (and GLES) development for Qt, with the necessary physics libs.

Build it and they will come - Ovi and devices

Professional mobile developers can and will materialize only after the market for the Qt apps materializes. The prerequisite for this is that Qt gets a first-class treatment in the Ovi store, and the QA process is not a hit-and-miss, something that developers are guessing about. Once the Ovi store really starts accepting Qt apps en masse, the question turns into how many devices can be targeted via Qt. I can hear you say "well that's like almost all Symbian handsets in the last 2-3 years". Yeah, but... 


Market share is not necessarily mindshare

Devices that can be retrofitted with Qt already exist in the (tens of) millions range. However, these devices are mostly low to midrange devices as there were no runaway Symbian successes in the high-end segment for a while now. It will be hard to convince people to target a market, no matter how objectively big if they believe/see it as a relic, which means... 

You've got to be cool

The vehicles for the Qt platform need to be cool and carriers of high tech. This is the wave Android is riding in 2010. Now, the best way to do this is having iconic devices (iPhone killers if you wish), but this is not ONLY about devices, it's about how you handle your technology in general, your devs, your community, blogs and everything related to it. Qt has to be perceived cool, a must-have even by non-tech people, not just a sticker on the corner of a box and something geeks nod over on irc. It IS the differentiating factor. Take for example the happenings of last week in the Nokia N900 land. A triple-release is done - preview of the Qt Web Runtime, a new version of Qt Mobility and the super-cool fcamera project. This triplet just oozes with tech-cool demo potential, but it just isn't leveraged, hardly getting even a blog post. Instead there is a campaign and an 'exciting news' about Ovi doing a comic (I'm sure it will be good, but... ). This points to comms issues, but also lack of

Communication/Community Focus

While I don't know how many different communities and aspects of Qt should there addressed separately, I'm pretty sure we are already overloaded, even before the hordes of the new Qt developer generations emerge. There is the Qt Developer Network, then we have Forum Nokia (home of the Nokia Qt SDK), followed by a more specific MeeGo community that is vested (well, at least the handset variant) in Qt, and the same will be true for Symbian. OTOH If you want to publish/talk about Qt development on currently available devices, you should go to maemo.org. While in community waters, we should also mention Qt Centre. Quite a handful of forums, mailing lists and irc channels to follow, and I have not even talked about communities focused squarely at end-users ! Speaking of end-users, some people who even knew about those Qt/fcam releases I mentioned above were quite discontent, because there is/was no concept of...

Control and drive expectations

The 'other' platforms and ecosystem have built up and trained users to expect certain things in a certain way, and if they are not educated, they will not understand what is going on and will easily dismiss even good news when it is not is a form they expect it in. See the above - new releases of QtMobility, WRT, etc were not treated by many as real news or support by Nokia for the N900, even though they were done by official Nokia teams. The concept of the 'holy firmware release' is still strong, because people don't understand the concept of libraries and components (as that is not how most other platforms operate).


Those would be my major points, and while they might sound a bit grim (some not even related to Qt itself), I don't think they are insurmountable at all, it just takes a little effort (some already underway) and presto, the arid Qt mobile app landscape can bloom like a savanna after a rain.

by Attila Csipa (noreply@blogger.com) at July 30, 2010 11:07 AM

July 28, 2010

Stephen Kelly

Grantlee version 0.1.4 now available

The Grantlee community is pleased to announce the release of Grantlee version 0.1.4.

This is the 3rd release of Grantlee in the month of July. Lets hope the development pace continues.

Grantlee now compiles almost cleanly with QT_NO_CAST_FROM_ASCII and QT_NO_CAST_TO_ASCII. I say almost because I can’t actually build Grantlee with those flags by default without breaking binary compatibility, because of some interesting design decisions. Making it compile with those flags was a good learning experience though, and a step towards full localization support in Grantlee templates through multiple APIs.

Another significant new feature in this release is that Grantlee now automatically finds its own default plugins at runtime. This is something I didn’t initially implement because I wrongly thought it was a platform issue to find plugins, even default plugins. Most new users of Grantlee hit into problems with this though, and finally Michael Jansen contributed a patch to resolve the issue. This should lower the barrier to entry to developing with Grantlee a little bit and that’s always a good thing.

Michael is also doing some really cool type introspection stuff, so keep a look out for that. I think it could lead to performance improvements and increased flexibility in type handling.


by steveire at July 28, 2010 08:08 PM

July 27, 2010

Robin Burchell

Tracking QSharedPointer leaks

Smart pointers are a great thing. When used properly, they can really help make life easier, and simpler. But things can, and do, occasionally go wrong - and that is when the hurt comes in. Qt provides a number of smart pointer classes, some might say too many, but that's a topic for a whole different discussion, one of which is QSharedPointer.

From the documentation:
"The QSharedPointer class holds a strong reference to a shared pointer
The QSharedPointer is an automatic, shared pointer in C++. It behaves
exactly like a normal pointer for normal purposes, including respect
for constness.

QSharedPointer will delete the pointer it is holding when it goes out
of scope, provided no other QSharedPointer objects are referencing it.

A QSharedPointer object can be created from a normal pointer, another
QSharedPointer object or by promoting a QWeakPointer object to a strong
reference.

Essentially, QSharedPointer works through reference counting, which means if you somehow make a mistake with cleaning up your references, the object your shared pointer refers to won't be deleted, and you've got a hard to track memory leak on your hands. This is precisely what happened to me recently at work, amongst a jungle of a few different libraries, so tracing the problem by hand was really not going to happen, so I needed a miracle, or short of that, a reliable way to track reference count changes on a QSharedPointer instance.

Reading up on QSharedPointer's internals, it became obvious that the reference counting was stored in the dpointer of each QSharedPointer instance. The dpointer is shared amongst QSharedPointer instances referring to the same pointer. So, we should be able to set a watch in gdb to break whenever the refcount changes.

First, we need to find out the address of a QSharedPointer instance, so set a breakpoint just after we first create it:


 (gdb) break main.cpp:22
 Breakpoint 1 at 0x8048806: file main.cpp, line 22.
 (gdb) r
 Starting program: /home/burchr/qsharedpointer/qsharedpointer.
 [Thread debugging using libthread_db enabled]

 Breakpoint 1, main (argc=1, argv=0xbffff444) at main.cpp:22
 22>-    QSharedPointer<MyClass> copy(initial);
 (gdb) p initial
 $1 = {<QtSharedPointer::ExternalRefCount<MyClass>> = {<QtSharedPointer::Basic<MyClass>> = { value = 0x804c438}, d = 0x804c448}, <No data fields>}

Now we have the address, we can set a watch on the QBasicAtomicInt in the dpointer, we can watch the refcount for changes:
 (gdb) watch $1.d->weakref
 Hardware watchpoint 2: $1.d->weakref


Continue debugging, and gdb will break whenever the refcount changes, telling us the old and new values, like so:
 (gdb) c
 Continuing.
 Hardware watchpoint 2: $1.d->weakref

 Old value = {_q_value = 1}
 New value = {_q_value = 2}
 0x08048953 in QBasicAtomicInt::ref (this=0x804c44c)
     at /usr/include/QtCore/qatomic_i386.h:120
 120>                 : "memory");



Much thanks to:

by viroteck@viroteck.net (Robin Burchell) at July 27, 2010 03:31 PM

Qt Labs

Qt Mobility 1.1.0 Technology Preview

The Qt Mobility teams are working full steam to bring you new APIs and extend our Qt developer offering.

To that end, we are very pleased to share the Technology Preview of our latest APIs.
This set of new APIs will be matured, with your help, and released later this year as QtMobility 1.1.0.

As you may know, we have also worked hard to resolve issues within the QtMobility 1.0.1 release, and to that end, earlier today we released our 1.0.2 package. While the quality of 1.0 is of the highest importance, we did not want to delay in sharing our drafts here for 1.1, as we believe that sharing early and often with you helps to achieve robust, high quality APIs.

Those longer term veterans understand that the Technology Preview releases are the best opportunity for you to help shape our new APIs before they solidify.

Releasing a Technology Preview early on like this however has some limitations for those reviewing. Specifically, given the early stage of development we have included only minimal backend support. But it is better to release the API drafts early and give you the opportunity to review and contribute before things become too settled.

On the subject of Contributions:
Your contribution toward desktop backends in particular is always most welcome as the program are firstly prioritising mobilie platforms; specifically Symbian and Maemo. (And later this year in Q3/Q4 we change our default development environment to Meego! :) )

Some detail on the logistics of how to go about reviewing this Technology Preview release:
This time round we are introducing ‘DevNet’ to the process.
DevNet facilitates better API review and communications.
Each of the new APIs will be individually introduced via Wiki on DevNet at http://developer.qt.nokia.com/.
There will also be a forum thread for each API, where you can share your review comments and track progress of the API as it matures toward Beta.
Good eh!? we certainly hope so :)
Also, let us know how you feel about that.

Ok, so whats in the box this time round!?
This Technology Preview contains 8 new APIs and also, in a few cases, some extensions to the existing APIs that were introduced in 1.0.
We are also introducing Qt Quick (QML) bindings for our APIs and several of those too are shared in this preview!

The list is as follows:

  • Service Framework API (Out-of process)
  • Document Gallery API
  • Maps/Navigation API
  • Organizer API
  • Landmarks API
  • Camera API
  • Versit/Organizer API
  • Telephony Events API
  • Feedback API
  • Contacts API
  • You can download the source package from:
    ftp://ftp.qt.nokia.com/qt/solutions/qt-mobility-opensource-src-1.1.0-tp.tar.gz
    ftp://ftp.qt.nokia.com/qt/solutions/qt-mobility-opensource-src-1.1.0-tp.zip

    Some APIs have been worked on a little more than others but overall, we believe they are in good shape for you to commence your review. Backend implementation wise, most of the APIs have the Maemo 5 backend which is currently our primary development environment.
    For each API there is an example application that demonstrates usage.
    Please note that Symbian SIS packages are not provided within this technology preview release as the backend is still under heavy development.

    We hope you enjoy this early preview of the ongoing work and as always,
    please continue to contribute, as your feedback is very valuable in helping us get it right!

    Thank you,

    Gerard and Min.
    On behalf of the Qt Mobility Program team

    by Gerard at July 27, 2010 10:09 AM

    Qt Mobility 1.0.2 Released

    Its here!
    For those in Europe enjoying a well deserved vacation by the side of a pool, or indeed for the rest of us around the world working hard on our projects, the availability of this package should come as very good news.

    The team, have worked very hard to ensure that our 1.0.2 package addresses those critical fixes (P0, P1 errors) that we communicated about on our recent alert post.

    In short, the more prominent APIs issues were: Location API crashes on Symbian platforms and Sensors API failing on Maemo 5.

    So we are very happy/relieved to be able to say that the promised 1.0.2 package has now arrived and can be downloaded from our Qt Solutions webpage.

    Also, coming very soon…your chance to download the technology preview release and be the first to try the next set of new APIs!! Not long to wait now at all :)

    We hope you enjoy!

    Kind regards,
    Gerard & Min.

    On behalf of the Qt Mobility Team.

    by Gerard at July 27, 2010 09:43 AM

    July 24, 2010

    Roberto Alsina

    This is why Qt (and PyQt) are cool

    Alejandro Dolina once wrote (and this is from memory that's probably 25 years old) of a round table discussing "What's Tango?", and how after two hours of discussing the nature, characteristics and history of tango, one of the members of the panel picked up a bandoneón, played "El apache argentino" stood up and left without saying a word.

    So, why are Qt and PyQt cool?

    Audio player widget:

    # -*- coding: utf-8 -*-
    
    import sys, os
    from PyQt4 import QtCore, QtGui, uic
    from PyQt4.phonon import Phonon
    import icons_rc
    
    class AudioPlayer(QtGui.QWidget):
        def __init__(self, url, parent = None):
    
            self.url = url
    
            QtGui.QWidget.__init__(self, parent)
            self.setSizePolicy(QtGui.QSizePolicy.Expanding,
                QtGui.QSizePolicy.Preferred)
    
    
            self.player = Phonon.createPlayer(Phonon.MusicCategory,
                Phonon.MediaSource(url))
            self.player.setTickInterval(100)
            self.player.tick.connect(self.tock)
    
            self.play_pause = QtGui.QPushButton(self)
            self.play_pause.setIcon(QtGui.QIcon(':/icons/player_play.svg'))
            self.play_pause.clicked.connect(self.playClicked)
            self.player.stateChanged.connect(self.stateChanged)
    
            self.slider = Phonon.SeekSlider(self.player , self)
    
            self.status = QtGui.QLabel(self)
            self.status.setAlignment(QtCore.Qt.AlignRight |
                QtCore.Qt.AlignVCenter)
    
            self.download = QtGui.QPushButton("Download", self)
            self.download.clicked.connect(self.fetch)
    
            layout = QtGui.QHBoxLayout(self)
            layout.addWidget(self.play_pause)
            layout.addWidget(self.slider)
            layout.addWidget(self.status)
            layout.addWidget(self.download)
    
        def playClicked(self):
            if self.player.state() == Phonon.PlayingState:
                self.player.pause()
            else:
                self.player.play()
    
        def stateChanged(self, new, old):
            if new == Phonon.PlayingState:
                self.play_pause.setIcon(QtGui.QIcon(':/icons/player_pause.svg'))
            else:
                self.play_pause.setIcon(QtGui.QIcon(':/icons/player_play.svg'))
    
        def tock(self, time):
            time = time/1000
            h = time/3600
            m = (time-3600*h) / 60
            s = (time-3600*h-m*60)
            self.status.setText('%02d:%02d:%02d'%(h,m,s))
    
        def fetch(self):
            print 'Should download %s'%self.url
    
    def main():
        app = QtGui.QApplication(sys.argv)
        window=AudioPlayer(sys.argv[1])
        window.show()
        # It's exec_ because exec is a reserved word in Python
        sys.exit(app.exec_())
    
    if __name__ == "__main__":
        main()
    

    Video player widget:

    import sys, os
    from PyQt4 import QtCore, QtGui, uic
    from PyQt4.phonon import Phonon
    import icons_rc
    
    class VideoPlayer(QtGui.QWidget):
        def __init__(self, url, parent = None):
    
            self.url = url
    
            QtGui.QWidget.__init__(self, parent)
            self.setSizePolicy(QtGui.QSizePolicy.Expanding,
                QtGui.QSizePolicy.Preferred)
    
    
            self.player = Phonon.VideoPlayer(Phonon.VideoCategory,self)
            self.player.load(Phonon.MediaSource(self.url))
            self.player.mediaObject().setTickInterval(100)
            self.player.mediaObject().tick.connect(self.tock)
    
            self.play_pause = QtGui.QPushButton(self)
            self.play_pause.setIcon(QtGui.QIcon(':/icons/player_play.svg'))
            self.play_pause.clicked.connect(self.playClicked)
            self.player.mediaObject().stateChanged.connect(self.stateChanged)
    
            self.slider = Phonon.SeekSlider(self.player.mediaObject() , self)
    
            self.status = QtGui.QLabel(self)
            self.status.setAlignment(QtCore.Qt.AlignRight |
                QtCore.Qt.AlignVCenter)
    
            self.download = QtGui.QPushButton("Download", self)
            self.download.clicked.connect(self.fetch)
            topLayout = QtGui.QVBoxLayout(self)
            topLayout.addWidget(self.player)
            layout = QtGui.QHBoxLayout(self)
            layout.addWidget(self.play_pause)
            layout.addWidget(self.slider)
            layout.addWidget(self.status)
            layout.addWidget(self.download)
            topLayout.addLayout(layout)
            self.setLayout(topLayout)
    
        def playClicked(self):
            if self.player.mediaObject().state() == Phonon.PlayingState:
                self.player.pause()
            else:
                self.player.play()
    
        def stateChanged(self, new, old):
            if new == Phonon.PlayingState:
                self.play_pause.setIcon(QtGui.QIcon(':/icons/player_pause.svg'))
            else:
                self.play_pause.setIcon(QtGui.QIcon(':/icons/player_play.svg'))
    
        def tock(self, time):
            time = time/1000
            h = time/3600
            m = (time-3600*h) / 60
            s = (time-3600*h-m*60)
            self.status.setText('%02d:%02d:%02d'%(h,m,s))
    
        def fetch(self):
            print 'Should download %s'%self.url
    
    def main():
        app = QtGui.QApplication(sys.argv)
        window=VideoPlayer(sys.argv[1])
        window.show()
        # It's exec_ because exec is a reserved word in Python
        sys.exit(app.exec_())
    
    if __name__ == "__main__":
        main()
    

    ...


    July 24, 2010 08:37 PM

    Matteo Bertozzi

    iPhone/Qt: UDP Voice using AudioQueue/QAudioOutput

    Qt 4.6 Introduces QtMultimedia with support for raw audio input/output, while Mac OS X and iPhone OS has well known CoreAudio/AudioQueue from a long time.

    This example show how to implement a really rudimentary VOIP between an iOS (iPhone/iPod Touch/iPad) and a Desktop (using Qt). To simplify the example is just unidirectional iOS to Qt, because doing Qt to iOS part is just the specular code.

    The idea is very simple, Fetch the sample data from the microphone, and send over UDP. No compression no packet number just send raw data in simple way as possible.

    On iOS we’ve AudioQueueNewInput() that creates a new recording audio queue object, and AudioQueueNewOutput() that creates a new playback audio queue object.

    The specular Qt 4.6+ classes are QAudioInput class that provides an interface for receiving audio data from an audio input device, and QAudioOutput class that provides an interface for sending audio data to an audio output device. To handle audio samples we can easily wrap QIODevice read() and write() calls.

    The source code is really easy. iOS code contains AudioRecorder.h/AudioRecorder.m that is a C code that wrap AudioQueue Input to record a stream, with a callback handler to intercept packet data. The Qt4 Source code contains just  a QIODevice Wrapper that read from UDP and prepare for QAudioOutputStream. It’s really really simple, but gives you an idea.

    The Source code is available here, and contains both Qt 4.6+ and iOS sources: iPhone/Qt UDP Voice Source Code.

    Note: Due to a QTBUG-8878 we cannot use 8, 16, 24 KHz Frequency. Will be fixed in Qt 4.6.4.

    by Matteo Bertozzi at July 24, 2010 02:23 PM

    July 23, 2010

    Roberto Alsina

    Desktop apps and clouds (with video)

    I enjoy creating desktop applications. That means I may be a member of a dying breed, since web apps are going to make us all obsolete next week, but I do enjoy doing it.

    The bad side of it is, of course that sometimes it's much more convenient to use a web application. For example, I have abandoned my own baby (uRSSus) because google reader is just easier and more convenient to use.

    But then I thought... what bothers me of uRSSus? And there are quite a few things!

    1. It's not in all computers I may use

      That means I will not ever be able to use it exclusively.

    2. It's pretty useless without an Internet connection (but so is google reader mostly)

    3. Since I can't use it exclusively, I end with feeds on uRSSus that are not on google reader and viceversa.

    4. It's freaking slow

    So, I decided to see what I could do about that without giving up the good side of uRSSus:

    1. It looks much nicer than a web app, because it looks like a desktop app
    2. It does things like opening the site instead of showing the feed item (great for partial content feeds)
    3. I wrote it (yes, that's a feature for me. I like self-made programs)

    So, this attempt at rewriting the desktop RSS reader produced this:

    As you can see in the above video, this reader syncs the subscription list to google reader. It will also eventually sync your read/unread posts.

    It still can open full sites instead of feed items, it has/will have a heck of an offline mode (full pages captured as images, for example), and... it's very very fast.

    It's much faster than google reader in Chromium, and hella faster than uRSSus. That was done via smarter coding, so it probably means I was braindead before and experienced a minor recovery.

    The code is not fit for release (for example, the database schema will change) but you can try it: http://code.google.com/p/kakawana/source/checkout


    July 23, 2010 02:50 AM

    July 22, 2010

    Qt Labs

    Qt 4.7.0 String Freeze

    Qt 4.7.0 string freeze is now in effect. No changes to strings will be accepted from this point.

    Qt aims at being fully internationalized by use of its own i18n framework. Localization to languages we have no internal resources for needs to be provided by the community. If you would like to contribute your own translation please look at the Qt Localization guide.

    by Toby Tomkins at July 22, 2010 06:08 AM

    July 21, 2010

    Robin Burchell

    Qt: Bootstrapping openness

    I witnessed (and was pleased to take part in) some interesting discussions on #qt-labs this afternoon, all stemming from a contribution to Qt3Support being rejected.

    A long story short, the contribution - despite looking reasonably valid - was rejected because Qt3Support is effectively unmaintained, and as a result, any changes to it could have negative impacts on users of the support API.

    I understand that argument, yet at the same time - I can't help but think it's a bit of a backwards approach to be taking. Typically, a contributor will wander along, find a bitrotting module/project that interests them, throw patches at the previous maintainer - and shortly after doing so, find themselves a de-facto (or indeed official) maintainer through their efforts.

    This is a natural progression of things and should really be encouraged, it allows what would otherwise be dead code to live on. However, in Qt3Support's case, the central point was that they'd love someone else to take responsibility for it, but don't want to expend the effort themselves to triage, maintain, and otherwise support it right now.

    To me, it's a false saving.

    Time you save not maintaining it now (and encouraging potential contributors/future maintainers along the way) is spent being forced to put the code on life support maintenance if you decide you want that code, for whatever reason, later on.

    Not to mention that those people who might be happily contributing you ideas or patches (to code old and new) are instead going to be spending their spare time doing something more rewarding than having their hard work rejected in the future.

    Openness doesn't just happen overnight. It isn't just in the licensing. It requires real persistent effort and culture change. This is something I plan to keep revisiting over my next few posts.

    {Note}: Before commenting, please note that this issue isn't *just* based around Qt3Support. That is one example of the problem, yes, but the patch was actually to QWorkspace which actually wasn't part of Qt3Support, and QtSql is in a similar boat - and there is nothing to port code using QtSql *to*.

    by viroteck@viroteck.net (Robin Burchell) at July 21, 2010 06:43 PM

    July 20, 2010

    The Qt Blog

    Call for Ambassadors | Qt Ambassador Program Launches

    It took a while, but finally, the Qt Ambassador Program makes its introduction to the Qt World. The call for Qt Ambassador applications is now open to all. Yippie!

    During our first Beta phase of the Qt Ambassador Program via Qtcentre.org, we received 85 applications and have so far accepted 30 ambassadors. Props to the CiMPLE project by Think Labs (a visual programming language for children to program robotic kits) for being the first-ever Qt Ambassador. Bravo indeed.

    What is the Qt Ambassador Program?

    The Qt Ambassador Program is a membership-only program that honors Qt development projects. All developers around the world who create products and projects with Qt are eligible to apply. Membership to the Qt Ambassador Program is free and based on your outstanding and innovative Qt project.

    Note: The Qt Ambassador Program is still in a Beta phase, so of course, there is a slight possibility that you may encounter certain kinks and quirks that need some ironing out. Make sure to send your feedback directly to qt-ambassador@nokia.com.

    Become a Qt Ambassador

    Don’t waste another second and apply now to the Qt Ambassador Program!

    Ambassador t-shirt design

    Ambassador t-shirt design

    by Katherine Barrios at July 20, 2010 01:52 PM

    Qt Labs

    Designing code for QML UIs

    QML is starting to approach its initial release. Those who have been using QML for a while can rejoice, for this means that we’re no longer changing everything and the stability of having an actual release can now be seen on the horizon (although maybe I’m just bitter because I had to change Samegame again today, because the QML behavior underneath has changed in what should be the last destabilizing change of this release). To celebrate, I’m going to do some blog posts on QML; just some various brain dumps on how to get the most out of QML. I think this is useful, largely because I think that QML is so amazingly powerful when you do get the most out of it. For now, getting the most out of QML is sadly limited to just awesome, fluid UIs. It’s still worth it. Since the docs explain how to get started and animating your UIs with QML, I’m going to start from the other side here. Presumably a lot of labs readers are C++ developers, and are wondering how they can get the most out of QML even though they write C++. In this case you can get a lot out of QML from using it as the UI layer on top of your C++ application logic. So here are the ‘recommended best practices’ to think about, so that you can make your next application QML-compatible from the start. Since this is basically just separation of the UI layer and the application logic layer, these practices are probably a good idea anyways. (Note that this is NOT the model-view-controller pattern, even though there is some overlap.)

    Separating the UI from the application logic, QML style, starts at design time. Think about what it is that your application really does. Naturally you’ll want to have a fluid, aethetically pleasing yet eminently usable user interface for it, but that part comes later. Your application may interface with a custom database, or it may play a game, or it may perform complex calculations over and over. For simple things, like just accessing web content or adding two numbers, you can make do with what comes with QML, such as the integrate QtScript or XmlListModel. For everything else, there’s Qt C++. If your application is, for example, interfacing with a custom database then you’ll likely be implementing that interface in C++ still. Because the layers are separate you should implement, on its own, the C++ parts that drive the application logic.

    When writing the C++ layer, you want to end up with a QObject derived class which exposes all the relevant application data through properties, signals and slots. For a database example, you would have properties that get set to provide the connection details, then you would have signals when the connection state progresses, and then you would have some way of getting the data. Depending on the data, this could be slots that return a value, properties that include whole models for viewing in the UI, or a mixture with slots that might update the data in the models exposed through properties. This is similar to existing Qt APIs for data objects. If you look at QAction, you will see that it provides a variety of properties for setting details about the action as well as a signal when the action is triggered. Looking at QAction as an example, it also has slots for manipulating properties. While this is not necessary for QML, it is perfectly acceptable for use from C++. Another example would be the folderlistmodel plugin in src/imports/folderlistmodel, A final real-world example would be the system info API in Qt Mobility which you could expose to QML and then just pick up and use due to the property based interface.

    For the most part it really is as simple as just using properties, signals and slots. The only QML specific advice I’d give is to think more declaratively. The techincal requirements for QML integration are easy to meet, but for something that’s really easy to use with QML it helps to consider the declarative approach when designing the interface. This is not incompatible with a good C++ interface. The main difference is with the use of properties. From C++, properties are little more than a convenience for the documentation. But from QML, properties are the primary method of interaction. It will be more useful from QML to have a boolean property isOn than to have turnOn and turnOff slots in C++. It will also be a lot easier than having a toggleOnOffState() slot and a getOnOffState() slot. Because properties are the main method of interaction for QML, it’s also better to have properties rather than just slots when passing data in or out of the C++ class - even when the communication is strictly one way. This is because the declarative approach thinks in terms of properties (The state is on. I want the state off.) rather than imperative steps (The state is on when getState()==true. If getState()==true, setState(false).). Other minor details from thinking declaratively are to always remember to have a notify signal for properties, and to allow the properties to be set in any order instead of having strict initialization order requirements. It’s a subtle distinction though, and in the end though you’ll just have a C++ class with a black box implementation and an interface comprised of properties, signals and slots. Such a class can then be used by a variety of things to construct a full application by adding a UI. From this class, you can add a C++ QWidget UI, a QML UI or something else (perhaps a pyside UI) on top to create a full application.

    As this is a best practices approach, it includes a test plan. You’ll want to test this with automated unit tests before even writing your first UI. Because you want a C++ part completely separate from the UI, it needs to be tested separately to any of your UI front ends. This can seem like a lot of overhead, but the actual data part is usually quite small compared to the UI. If it isn’t then it’s probably something really hairy and you need the extra testing anyways ;) .

    The advantage of having a completely separate UI and data layer is that you can alter or add new UIs at a moments notice. Imagine ‘themes’ that can change the entire look and feel, not just a few colors and pixmaps. Even better, imagine the ease in which you can port your application to a completely different platform. I think Qt’s cross-platform widgets do a fine job on some of the desktop platforms, although that is debatable. Less debatable is how well they do when porting your app from a desktop platform to a 240×320 keypad phone and a 800×480 touchscreen phone. With such radical changes in the form factor and basic I/O devices, there is no alternative to a complete UI rewrite if you want to have an excellent UI. But if you have the UI and data layer completely separated, you can easily rewrite the entire UI in QML, and get the same functionality behind it with a simple recompile. So while ‘write once, deploy everywhere’ is an impossible dream with the UI across phones (and similar devices) you don’t have to give up hope on the application logic, which was the harder one to write anyways.

    A second advantage is that the separate UI and data layer allows them to be developed individually. While a developer is writing and testing the data logic, a designer can prototype and write the UI with dummy data. Then the unification of the two to make a real application becomes really simple. Or, for free software projects, if the developer has a great idea but wrote a lousy interface for it, then a designer has a much lower barrier towards contributing to make it more usable. He could just write a UI in QML and, at least in cases where the C++ logic was deployed via the QML plugin system, actually create and use it without needing to compile or even read the ‘intimidating’ C++ code.

    It might be Qt specific, but my advice for future designs is to expose the application logic in a QObject derived class, using properties, signals and slots for the interface. You can then expose it through a QML or C++ plugin, use it with a QML or C++ UI, or even run unit tests on it directly. This design helps with modularity where it counts, in the data layer, and allows UI swapping at will (or even at runtime, if you’re so inclined).

    by Alan Alpert at July 20, 2010 02:57 AM

    July 19, 2010

    Stephen Kelly

    Grantlee version 0.1.3 now available

    The Grantlee community is pleased to announce the release of Grantlee version 0.1.3.

    The most interesting part of this release is the support for generating ruby code in the code generator example.

    The patch adding ruby support did not touch any C++ code. It did touch some ui files and Qt Resource files. It would be possible to add extra language support without even recompiling the application if not for the Qt Resource usage. Part of the intent of that example application though is to show how to use Qt Resources with Grantlee though, so that is not going to happen for that app :) .


    by steveire at July 19, 2010 06:21 PM

    Qt Labs

    The Qt Web Runtime journey begins…

    Ever since we introduced the Qt WebKit integration, it has rapidly become one of the most popular features within Qt. Enabling the development of web applications is crucial for meeting market demands. We see an increasing amount of Qt being used for web enabled device creation – from netbooks and mobiles to TV’s and a broad range of home media devices – therefore we see a need to provide device manufacturers with more means to make packaging and security of web applications easier on devices.

    In light of this we are pleased to announce that we have started to build a web application framework, Qt Web Runtime, on top of Qt and Qt WebKit, which will enable web apps to be more powerful than before.

    One important objective with Qt WRT is to enable a W3C-standards-based web runtime, so you will be able to package apps and deploy them to smartphones (or a variety of embedded devices) just like with regular apps. One of the key advantages is that you can access many of the device resources like camera, contacts, messages, etc. simply by using JavaScript APIs.

    A quick example of how to get access to the accelerometer of a device is illustrated by the small piece of code below. You register for notification of events pertaining to acceleration (on the channel AccelerometerAxis) through startChannel() and your provided callback functions get called whenever there is any acceleration around any axis of the device.

    var wrtSensors = nokia.device.load("sensors");
    wrtSensors.startChannel(callback, "AccelerometerAxis", errorCallback);
    
    function callback(data) {
           console.log("x-axis: " + data.axisX + " y-axis: " + data.axisY + " z-axis: " + data.axisZ);
    }      
    
    function errorCallback(err) {
           console.log("Ouch, " + err.message + "error code:" + err.code);
    }

    Just like Qt runs cross-platform, Qt WRT is planned to run across different platforms and devices. Taking Web Runtime to Qt means that this technology will be open sourced and part of Qt’s new open governance model. We really hope, in the coming months, that you will be interested in contributing to the success of Qt Web Runtime and how we govern it together.

    We are working on a feedback/contribution infrastructure and will provide more info as soon as we have more pieces in place, so that we can develop Web Runtime together with you - in the open. As part of Qt’s public roadmap and our open governance model, you all have the opportunity to be involved in how Web Runtime evolves and grows, and we are looking forward to seeing you involved in that process.

    So today, the journey with Web Runtime begins. A snapshot of the current Qt WRT code has been placed on get.qt.nokia.com/qtwrt to give you an idea of how Qt WRT looks today. Note that this snapshot of the code only works on Nokia N900. Subsequent releases will support more platforms and devices, so stay tuned since we plan to share more code with you within the coming month.

    If you want to provide some feedback or join the discussion, please head over to the QtWRT forum on the Qt Developer Network.

    by Ashraf Alkarmi at July 19, 2010 02:40 PM

    July 17, 2010

    Roberto Alsina

    Slow-Slow and Fast-Fast (video)

    My previous post explained how to cache whole web pages as images. Now see it in action. This is a lightweight RSS reader, optimized for comic books (but it works for any feed) and for offline use (but it works online too, of course).

    Not ready for public use yet, but if you look around you can find the code somewhere ;-)


    July 17, 2010 03:53 AM

    July 16, 2010

    Code Improved

    What’s wrong with C++

    …from the point of view of someone that actually uses it? The bits from my last post haven’t even dried up yet, and another fascinating rant about C++ has popped up, this time from Zed Shaw.

    What’s interesting about these rants is that the ranter isn’t really using C++. They’re C hackers, or they program mostly in Python, or they used C++ at the beginning of the 90s. So I thought it would be interesting to write about my experience with C++.

    First, a little background info…

    I started learning C++ about 10 years ago, first the C part and then the ++ part. Nothing serious, just toying around with small projects to learn and have fun. I didn’t use it professionally until about four and a half years ago, when I started working on a large scale C++ project. Since then I’ve used it almost daily.

    Two and a half years ago I came across Qt almost by accident: the large scale project that I was working on was being ported to Linux and the port was enabled by Qt. Since then, I’ve used Qt almost daily too.

    Right now I’m working on a  Qt C++ project that’s about 25KLOC in size and growing. It’s a multi-platform, threaded client-server and it’s a line of bussiness app if you’d believe it. Working on it is fun, and I’m glad that I picked Qt and C++.

    Okay, enough with the history, what about C++ and its warts?

    Issues that bother me in practice

    • Compile times and the include dependency specification: this is a problem that every C++ programmer will have sooner or later. It can be delayed and mitigated with a good physical design, precompiled headers and distributed compilers/linkers, but it can’t be solved without throwing away compatibility to existing code completely.
    • The small standard library: not a big issue in itself, since you can find other libraries for anything you might want to do, but it’s unpleasant to install all those libraries and make sure that they work together nicely. Using more libraries instead of a large standard library also means that you have to wait on each library vendor to port the library to different OSes/compilers, upgrade it and so on.
    • lack of reflection: I like Qt’s moc and I miss it in standard C++. I also wish it had more features.
    • lack of type inference: even with typedefs I’m typing more than I have to. C++0x will thankfully fix this.
    • localization & internationalization support in the standard library: the implementation is complicated and difficult to use. After browsing through C++ IOstreams and locales I’ve decided to just use Qt and not worry about it.
    • template error messages: they’re long and hard to understand. I usually parse a template error message in about 10-20 seconds depending on the difficulty. The worst offenders are metaprogramming-heavy libraries such as Boost Spirit. In that case, I try to analyze the code first and see what might be wrong. STLFilt can help.
    • functional programming support: this will get better in C++0x, but I can’t use C++0x now, at least not on all platforms and with the other libraries I’m using. Functors and free functions are cumbersome to use with algorithms.
    • tools and parsing: C++ has access to solid, mature tools, but those tools are much harder to develop than for other languages and generally don’t have as many features.

    Issues that don’t bother me at all, but are regularly brought up in rants

    • memory management: never a problem for me. The last time I’ve had a memory leak was about two years ago and it got caught at code review. C++ has good support for memory management and good tools that can be used for runtime debugging. It might as well have GC, I wouldn’t be able to tell the  difference.
    • memory corruption: memory corruption can be both exciting and scary. Exciting because you have to go down to the memory address level and do some sleuthing, scary because it can take days or weeks to find some bugs. I usually don’t sweat these bugs, they were very rare in the code I’ve worked on, and when they occurred they were easily found. e.g: the last one I’ve solved in maybe 30 seconds, the tools have gotten very good. The worst I’ve encountered was a problem with an embedded STL in a large project that took a week to figure out and only because of my lack of experience at that time. Some people love debugging.
    • multi-threading: it is hard in most languages. The trick is using higher-level libraries such as QtConcurrent, Intel’s TBB or OpenMP. Sure, if you’re doing PThreads it’s going to be painful.
    • string formatting and string support: I generally don’t use iostreams or std::string, but when I did I found them acceptable. Unicode support was the biggest issue, but “there’s a applib for that”. Now I use Qt’s strings and streams; they’re as easy to use as Python as far as I’m concerned. Don’t want Qt? Use boost::format or any other of the nice formatting libraries.
    • templates in general: I use them when needed to break dependencies, write generic code, etc. I try to keep template code manageable, without going into the metaprogramming stuff; they are one of my favourite C++ features.
    • exception rules: I don’t see any problem with exceptions in C++ as long as you’re using RAII. Other languages (e.g.: Python) use them extensively for error handling.
    • STL & Boost: I’ve used both for a lot of time and I find them very useful. Contrary to popular belief, most templates don’t use metaprogramming techniques. You don’t have to install Boost, it’s mostly headers. A large part of Boost became TR1 so it should even ship with your compiler now.
    • const: This one came from Zed, I don’t think I’ve seen that many people complain about const. Personally, I constify everything that I can, even const type* const.
    • everybody learns a different 10% of C++: strange, because I use all of it and always have. It’s not that hard either, I’m not a genius… Sane projects have coding guidelines and architectural documents. If your teammate can waltz right in with a template metaprogram or is generally macro-happy and it doesn’t raise eyebrows at code review, you have bigger problems than using C++. I’ve had to fix two C++ projects so far; my only job was to do what it takes to make the programs work and ship them to the customer. Most problems were memory leaks, superfluous use of casts, functions that didn’t compile on all platforms and so on. Fixable. What I couldn’t fix – and had to patch up as best as possible – were issues with the program logic and architecture. Those were not caused by C++.

    Ok, but what about…

    You probably have your favourite C++ misfeatures.  Odds are that they don’t matter than much in practice, or workarounds are available. Maybe I just got used to them and consider them a C++ tax.

    by razvanpetru at July 16, 2010 09:37 PM

    Roberto Alsina

    Capturing a webpage as an image using Pyhon and Qt

    For a small project I am doing I wanted the capability to see web pages offline. So, I started thinking of a way to do that, and all solutions were annoying or impractical.

    So, I googled and found CutyCapt which uses Qt and WebKit to turn web pages into images. Good enough for me!

    Since I wanted to use this from a PyQt app, it makes sense to do the same thing CutyCapt does, but as a python module/script, so here's a quick implementation that works for me, even if it lacks a bunch of CutyCapt's features.

    With a little extra effort, it can even save as PDF or SVG, which would let you use it almost like a real web page.

    You just use it like this:

    python  capty.py http://www.kde.org kde.png
    

    And here's the code [download capty.py]

    # -*- coding: utf-8 -*-
    
    """This tries to do more or less the same thing as CutyCapt, but as a
    python module.
    
    This is a derived work from CutyCapt: http://cutycapt.sourceforge.net/
    
    ////////////////////////////////////////////////////////////////////
    //
    // CutyCapt - A Qt WebKit Web Page Rendering Capture Utility
    //
    // Copyright (C) 2003-2010 Bjoern Hoehrmann <bjoern@hoehrmann.de>
    //
    // This program is free software; you can redistribute it and/or
    // modify it under the terms of the GNU General Public License
    // as published by the Free Software Foundation; either version 2
    // of the License, or (at your option) any later version.
    //
    // This program is distributed in the hope that it will be useful,
    // but WITHOUT ANY WARRANTY; without even the implied warranty of
    // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    // GNU General Public License for more details.
    //
    // $Id$
    //
    ////////////////////////////////////////////////////////////////////
    
    """
    
    import sys
    from PyQt4 import QtCore, QtGui, QtWebKit
    
    
    class Capturer(object):
        """A class to capture webpages as images"""
    
        def __init__(self, url, filename):
            self.url = url
            self.filename = filename
            self.saw_initial_layout = False
            self.saw_document_complete = False
    
        def loadFinishedSlot(self):
            self.saw_document_complete = True
            if self.saw_initial_layout and self.saw_document_complete:
                self.doCapture()
    
        def initialLayoutSlot(self):
            self.saw_initial_layout = True
            if self.saw_initial_layout and self.saw_document_complete:
                self.doCapture()
    
        def capture(self):
            """Captures url as an image to the file specified"""
            self.wb = QtWebKit.QWebPage()
            self.wb.mainFrame().setScrollBarPolicy(
                QtCore.Qt.Horizontal, QtCore.Qt.ScrollBarAlwaysOff)
            self.wb.mainFrame().setScrollBarPolicy(
                QtCore.Qt.Vertical, QtCore.Qt.ScrollBarAlwaysOff)
    
            self.wb.loadFinished.connect(self.loadFinishedSlot)
            self.wb.mainFrame().initialLayoutCompleted.connect(
                self.initialLayoutSlot)
    
            self.wb.mainFrame().load(QtCore.QUrl(self.url))
    
        def doCapture(self):
            self.wb.setViewportSize(self.wb.mainFrame().contentsSize())
            img = QtGui.QImage(self.wb.viewportSize(), QtGui.QImage.Format_ARGB32)
            painter = QtGui.QPainter(img)
            self.wb.mainFrame().render(painter)
            painter.end()
            img.save(self.filename)
            QtCore.QCoreApplication.instance().quit()
    
    if __name__ == "__main__":
        """Run a simple capture"""
        app = QtGui.QApplication(sys.argv)
        c = Capturer(sys.argv[1], sys.argv[2])
        c.capture()
        app.exec_()
    


    July 16, 2010 07:58 PM

    July 15, 2010

    The Qt Blog

    Free Qt Quick and KDE Plasma mobile seminar

    Cybercom logoThis September, Qt partner Cybercom is putting on a free developer day in Helsinki, Finland, focussing on Qt Quick and KDE Plasma technologies.

    Featuring speakers such as Marco Martin from KDE and Qt’s own Alexis Menard, the day will be a valuable opportunity to learn and discuss Qt Quick and KDE Plasma. Several hours of the program are dedicated to demos and discussions.

    Details:
    What: one-day FREE Qt Quick and Plasma Mobile Seminar
    When: September 7th, 2010 from 9 am to 4pm
    Where: Technopolis Ruoholahti, Conference room Marx, Hiilikatu 3, 00180 HELSINKI

    The full agenda can be found at http://www.cybercomchannel.com/?page_id=187. Cybercom Developer Day is a free event and there are a limited amount of seats. You can request an invitation to attend the day via Cybercom’s invitation form at http://www.cybercomchannel.com/?page_id=175.

    Registration is now open.

    by David Stone at July 15, 2010 03:32 PM

    July 14, 2010

    Attila Csipa

    Where are those mobile Qt apps ? (Part 2, Adoption)

    After my last blog post that discussed the Qt toolkit's history, present and future in the Nokia ecosystem, in this second part of my blog series I will talk about the problems of Qt adoption among developers so far and the effects these problems had on (the lack of) mobile Qt applications today.

    This will not be an article about the flaws of C++, bloatedness of frameworks and similar issues. Sure, some people prefer other languages, other frameworks, or have a personal beef with Qt, but that is a different story. Here, I will talk about the WAY things happened, are happening and what could have been better handled - albeit from a Qt angle.


    Are we there yet ?

    Qt was originally a desktop application framework, but has been dabbling with embedded applications way before Nokia took over. However, the focus shifted dramatically and Qt (and derived technologies) went to overdrive, introducing new (and exciting !) technologies and approaches by the boatload (see MeeGo Touch, QML, etc). This not unlike what Android was/is doing - a forced growth where the race is on to pump R&D *before* the large footprint of deployed tech becomes a maintenance nightmare. On the flip side, this makes developers reluctant to write for *current* stable releases as stable is a mostly-working-kind-of-stable and they know not only there is something new and shiny coming up (it always is), but that it is coming *soon*.


    Desktop vs Mobile

    The long and successful history of Qt means there are (tens of) thousands of developers fairly familiar with Qt. However, this does not translate to mobile applications galore for several reasons. First of all, those people need to be motivated to write high quality mobile apps. They will not start to develop for mobile devices just because they are there, not any more than an enterprise Java developer would drop everything to make midlets. Sure, if someone is already familiar with a technology, that person will likely use it in it’s hobbies too - and that’s it, "desktop Qt people" are NOT the base that will spawn the bulk of serious mobile Qt developers/companies - those people will come from people with existing mobile background or interests. This seems to be slowly being realized now, as porting tutorials for Android and iPhone started appearing on Forum Nokia. This is an important shift, and while might be characterized as aggressive, it’s exactly those developers that need to be targeted to get the Qt ecosystem on the mobile industry radar.


    The big GTK+ migration

    Since July 2009, it has been known Qt will take the place of GTK+ in Maemo/MeeGo. To be precise, this is not as much about GTK+ itself, but about the GTK+ based Hildon application framework, initially developed by Nokia. It is understandable that such a major change touches on many existing developers and that such transitions are always difficult to manage. However, there were a lot of indecision and mixed signals from both Nokia and the community as to what exactly should be done "for now" and "for the future", what is or isn’t available in Qt and just how important it is for Qt to mimic/fit in the existing, but deprecated Hildon environment. In retrospect, once the strategic choice of going Qt was made, the push for Qt should have been much stronger, helped with migration plans/tutorials for existing developers.

     The big Symbian migration

    Almost literally the same applies to Symbian people. While nowadays it will be hard to find large gangs of fierce AVKON supporters and the public/private API approach of Symbian, there is still a significant "why do we need Qt" notion. It has to be made clear AVKON is dead and, again, just as with GTK, handing out Qt tutorials that start from scratch will not help as much as good, targeted migration plans/tutorials for Symbian people. Just putting Qt on a Symbian handset preinstalled will NOT be a sufficient motivator for existing developers.


    New vs existing developers 

    As seen from my stance in the "desktop vs mobile" section, it is clear why I think people already doing or interested in apps for mobile devices are important, and there has simply not been a widely successful effort (yet) to help ease people into Qt’s way of doing things. This is well illustrated in the experience with Maemo - most Qt apps were written by people who came to Maemo *first* and *then* started doing Qt.

    You have Python - use it. 

    There are two Python binding projects available for Qt, both open source but neither have the status of being an "official" Nokia binding and Ovi not supporting Python apps at all. Again, from Maemo experience we see that there is a huge interest in these because even with the limited documentation and support available the number of Python apps is comparable to the number of pure C++ Qt apps due to the low entry barrier of Python.

    TIMTOWDI*

    Some people will snarl at this, but.. there are simply too many ways to do things. Or, rather, there aren't (sufficiently) recommended ways of doing things. Quality training material is starting to appear, but any time somebody asks how do I do a GUI there needs to be a longish discussion as to what version is being targeted, what tools are acceptable, etc, etc. If there are 5 ways of popping up a Hello World dialog (many of them quite 'old school'), know that people WILL get lost or at least discouraged when they try do merge docs from all over the net.


    Show me the money

    As seen/heard from many professional (as in for-money) developers on various Maemo forums, they do not really care about Qt. Sure, it’s cool and a lot friendlier than some previous approaches, but the ultimate test for them is the market. If a super-appstore existed and it required you to code in assembler, it wouldn’t matter much, these guys would just bite the bullet and do it that way. The morale ? Technical merit seems to influence adoption rate a lot less that many believe and the primary aspect are really cost and perceived benefit. Let me emphasize - this only applies to large-scale commercial development, FOSS and hobby coders *will* be affected a lot more. And while we are talking about money...

    The closed door

    One of the lures of application stores is that they are simple to use, accessible to one-man-show developers, and, well, 'just work'. Unfortunately, Ovi was not really ready for the Qt apps (or the N900) in the planned 'end of 2009' timeframe - whether they had more important things to do or more important holes to fix, I wouldn’t know. In any case it took a hefty extra 6 months until you could actually submit Qt applications to Ovi, and the Ovi QA process for these is still trailing the community QA process in many ways.

    Chuck Norris releases PR1.2

    Well, at least for onlookers it felt like it would take Chuck Norris' superpowers to get the infamous PR1.2 firmware released for the N900. This alone was not a problem, firmware delays happen, but the bundled nature of firmwares meant that Qt4.6 that was ready at the end of March could not be distributed until the end of May, a 2 month delay for no reason at all. On a side note, due to bad communications, this issue caused an outage of several weeks for community developers unlucky enough to depend on packages that have been changed in the update. While this particular incident was Maemo-specific, the Symbian counterparts are not immune to such risks.


    So, does all this mean Qt is doomed, the future is grim and is all hope lost ? Not at all, as you might have noticed, many of the issues are growing pains, have already been resolved, or are at least in the phase of being taken care of. The change that is going on is really huge, a lot bigger than a lot of people realize, however, it would be not be sincere to say all will be peachy from here on. Even though the time for reaping the benefits is finally closing in, there are a few points that need to be addressed before Qt becomes a no-brainer for both commercial and community development and all those apps start pouring in. Tune in for for the final, third part of this series to see what these are.

    by Attila Csipa (noreply@blogger.com) at July 14, 2010 07:13 PM

    Arvid Picciani

    thread abuse

    What Threads are not, and how to avoid making a fool out of yourself

    1. Threads are not for learning-by-doing

    No matter how far you got without actual education, multithreading is a barrier where you will need formal education. They alter program flow from deterministic to non deterministic. In short that means, that errors generate different results each time you run it. There is no way to fix race conditions by try-and-error.
    "You had a problem, you added threads. Now you have two problems."
    Avoid threads at all cost. If you think you need a thread, let me show you why you do not:

    2. Threads are not timers

    if you have:

    void MyThread::run(){
        for(;;){
            do_stuff();
            sleep(1);
        }
    }
    
    you actually wanted:
    class MyStuff: public QObject{
    Q_OBJECT
    public:
        MyStuff(){
            connect(&timer,SIGNAL(timeout()),this,SLOT(doStuff()));
            timer.start(1000); 
        }
    private slots:
        void doStuff(){
            do_stuff();
        }
    private:
        QTimer timer;
    };
    
    or even just QObject::timerEvent

    3. Threads are not async network

    Or: the (inter)net is not sync. I know they teach that crap at university, i've been there. But the truth is, the network is async by design. Non-retarded operating systems - such as unix, where sockets originate - , do all the hard work for you. They nicely feed you a few hundret sockets into a single thread. If you need more then this, Qts current eventloops (select,glib) will be in your way anyway. Let me show you how to transform bad network code into good:
    You had:

    MyWorker::run(){
        while(;;){ 
            mySocket->waitForReadyRead(-1);
            data.append(mySocket->readAll());
        }
    }
    
    there's plenty more errors in this code, but for now lets focus on thread abuse. Here is what you should do instead:
    class MyFoo : public QObject{
    Q_OBJECT
    public:
        MyFoo(){
            mySocket=new Q*Socket;
            connect(mySocket,SIGNAL(readyRead()),this,SLOT(haveData()));
        }
    private slots:
        void haveData(){
            data.append(mySocket->readAll());
        }
    private:
        QByteArray data;
        Q*Socket * mySocket;
    
    };
    

    4. Thread are not process controllers.

    void MyProcess::run(){
        system("run stuff");
        system("run other stuff");
    }   
    
    OMGWTFBBQ?! There are so many things wrong with this on multiple levels. But let's assume you just want to know the 'right' way of doing it:
    class MyController : public QObject{
    Q_OBJECT
    public:
        MyController(){
            process=new QProcess;
            jobs.enqueue("run stuff");
            jobs.enqueue("run other stuff");
            connect(process,SIGNAL(finished(int,QProcess::ExitStatus )),this,SLOT(start()));
        }
    public slots:
        void start(){
            if(jobs.isEmpty()){
                emit done();
            }else{
                process->start(jobs.dequeue());
            }
        }
    private:
        QQueue jobs;
        QProcess * process;
    signals:
        void done();
    };
    
    Well minus the typos, and plus error checking, but you get the point.

    5. Threads are not state machines

    Well, in a lower level sense, they are. Point is, in a lot of cases where "one thing goes after another", and none of these are CPU bound, you can avoid threads and safe yourself the headache. This last entry serves as a guide for a generic aproach to avoiding threads.
    bad code:

        void Bla::run(){
            one_thing();
            another_thing();
            wait_for_more_data();
            more_thing();
            wait_for_more_data();
            i_get_bored_of_this_thing();        
        }
    
    good code:
    class Bla : public QObject(){
    Q_OBJECT
    public:
        Bla()
            :QObject()
            ,state(0)
        {
             connect(dataSource,SIGNAL(readyIndicator()),this,resourceReady());
        }
    private:
        int state:
    private slots:
        void resourceReady(){
            if(state=0){
                one_thing();
                another_thing();
                state=1;
            }else if(state=1){
                more_thing();
                state=2;
            }else if(state=2){
                i_get_bored_of_this_thing();
                state=3;
            }else{
                qWarning("did not expect more data.");
            }
        }
    };
    
    examples of resourceRead() are QIODevice::readRead() which is implemented in Q*Socket,QNetworkResponse, and stuff, QDBusPendingCallWatcheri::finished(), QFutureWatcher::finished(), etc etc. This is how we roll with Qt :)
    well, you could use enums, you could use QStateMachine, you could use multiple slots. Whatever suits you. Point being, Qt abstracts all the nasty things away nicely into async APIs, use them. Threads suck.

    6. Threads _are_ for CPU bound operations

    If you have more then one core, and you have code that uses lots of CPU, threads will actually do something useful for you. Just remember that its not trivial, and remember to read http://blog.exys.org/entries/2010/QThread_affinity.html and upcomming articles covering threads.

    July 14, 2010 10:31 AM

    Planet Qt is made from the many different sources. The opinions it contains are those of the contributor.