My First Qt Quick App – QuickFlickr

Some time ago I wrote how you can build and run QML applications on N900, but since that I haven’t done anything related to QML, until now. I’m not the only one at the moment who is trying to study how QML works and how you can deploy it in your application. I have always learned by doing, so therefore I decided to write a small application with QML.

I like to photograph and I have missed a good Flickr client for N900, so it was a natural choice to write a small Flickr client. I call it QuickFlickr, naturally:) So here’s the sneak preview of QuickFlickr. On the video I run it on Mac, because it takes too much time to build exactly the same version of Qt and Declarative module that I’m running on my laptop.

The application is far from ready and it lacks of proper graphics and bunch of functionality like uploading local images to the Flickr, but I will work on this app in order to learn more QML. I also managed to improve the performance quite much after I shot this screencast. I’ll add another video where you can see the performance improvement.

QuickFlickr – the Design

One of the design issues that I wanted to try, was to implement actual Flickr API usage in C++ using QtFlickr library and to provide all the content from C++ side to the UI / QML side. The QML side only visualizes the data that comes from C++ side. I didn’t want to implement too much logic in QML side.

So I wanted to “simulate” how this kind of application would have been done in  a real project. With this I mean that there are developers implementing the “difficult stuff” in C++ side and then the UI designers do the eye-candy UIs using QML. In my opinion, many of the QML examples and demos do little bit too much in the QML side, such as they implement too much stuff using the javascript. On the other hand, I understand that the idea of demos is to demonstrate the power of QML, but I’m not sure how much designers would like work with JavaScript.

Working with QML

I spend most of the time to make Flickr API to work in C++ side and then the rest of the time I spend for doing QML. I was really amazed how fast I could create the basic functionality there like displaying the content of a model in a Flickable ListView only with a few lines of code:  a ListView item and delegate item. In the C++ side, I created the UI by using QDeclarativeView which I used for loading the main QML component which constructs the UI. I also used it for accessing the QDeclarativeEngine and to the root context.

I have implemented almost identical functionality with Qt/C++ and QGraphicsView and it really took ages to get it working.  With QML it took only few hours to get really neat looking stuff. Another positive thing was that because you don’t need to re-compile the code after the smallest change, you can see the result very fast.

As I stated it didn’t take too much time to implement the basic functionality in QML side, but fine tuning all the details took pretty much time.  I also spend couple hours to solve some issues that I ran into every time after updating the Qt version, but it is acceptable at this point because the Declarative module is under development.

Anchored Layout

If you don’t know what Anchored layout is, it’s worth to check it’s documentation from here. At first I thought that how I can do most of my layouting using it, but after a while, I noticed that it’s pretty easy way to implement quite complex layout. Yes, there also are Grid, Row and Column layouts, so don’t be worry about that.

You can also easily define AnchorAnimation for AnchorLayout in a Transition between states (AnchorChanges). For example in a QuickFlickr’s Fullscreen View’s “Details”  state, the Image is moved from the middle to the left and scaled down little bit.

The next picture demonstrates how I used AnchoredLayout in a FullScreenDelegate object. That object contains two states: one state for showing only a fullscreen image and the other state for showing the details.

Marko Saari takes amazing pictures with cool lighting setups. You can check his photostream from Flickr.

In the image above the FullScreenDelegate displays only an image inside a black rectangle. All the other items in a delegate are set to invisible with 0 opacity.

FullScreenDelegate with more visible items in AnchoredLayout.

In the second state, the FullScreenDelegate displays more information about the image such as title, tags, views, description and views. The image is scaled down little bit to make more room for other items. I’m not sure how good design this is for a delegate, but it “Works for Me”:)

In my opinion Anchored Layout is a powerful layout and you can create complex layouts even though it looks quite simple at first glance.

Problems with Layouts

As you can see from the video, I used Grid layout in the main page. I tried to use Grid’s “add” and “move” transitions e.g. when the application starts, those menu items would “fly” there and they did, but they somehow moved the whole Grid to the wrong position. I guess, I need to file a bug from this.

Data Models, Delegates and Views

If you’re familiar with Qt you have probably ran into data models. With QML you can use data models to make e.g. a ListView, a GridView or a PathView to display some content. This works pretty much in a same way as using them with Qt/C++. As you can see from the video, the UI has been built by using only a Grid (main page) and  a ListView (contact uploads and photostream).

In QuickFlickr application, I decided to provide data e.g. contact uploads or photostream of contacts using data models. In C++ side I used QtFlickr API to get some content from Flickr. I created a one class called FlickrItem which I used for encapsulation of a single item from a Flickr. I created a QList<FlickrItem*> and that list (data model) was passed to the QML side for a ListView. With this approach, I didn’t use the full blown QAbstractItemModel which is also supported by QML… I was bit lazy in that sense;P

Having a data model and a view is not enough to get model content to visualized. (Images above) You still need to create a delegate. Delegate is used for “drawing” the content of the single FlickrItem.  This is where QML is very handy. Delegate can access the data of C++ object (FlickrItem) via Qt’s property system. So for example FlickrItem introduces  bunch of properties like the url of the image: Q_PROPERTY(QUrl url READ url WRITE setUrl).

From your QML delegate you can “ask/call” the property directly to get the actual data out from your object. Sounds easy and it really is.

Problems with Data Models and Delegate

Even though it was really easy and fast to make C++ data model, pass it to the QML/ListView and visualize data with delegate, found couple of problems during my experiment.

  1. I wanted to call a method of a FlickrItem instance, which triggers e.g. a signal in C++ side and I couldn’t make it to happen. I tried to use Q_INVOKABLE but for some reason, I was only able to call these Q_PROPERTY methods. So defining a Q_INVOKABLE void foo() in FLickrItem didn’t work for my delegate.
  2. Sorting of the ListView’s content is not very handy at least if using QList<FlickerItem*> approach. I’m not sure would it be possible somehow if I would have used QSortFilterProxyModel and QAbstractItemModel instead of QList. The only way how I could order the content was to order the QList before passing it to the ListView.

Performance

I used iMac and MacBook Pro for development so the performance shouldn’t be an issue there. Actually after updating Qt version at some point, the performance improved quite a lot. It is also possible to improve the panning by setting cacheBuffer large enough, but this will of course increase the memory usages.

Actually what you see on the video,  is not running as well it could. After I shot the video I managed to improve the performance quite a lot by setting QGLWidget  to the viewport for the QDeclarativeView. On the video I ran it by using “-graphicssystem opengl” switch, which doesn’t seem to work as well as it could.

Addition: Here’s the second video of the QuickFlickr where I manage to improve the performance. Too bad that the screentoaster that I used for getting the screencast, doesn’t show it running as fast as it was runnign while recording. I guess, I need to find some proper software for capturing screen (not for stills:).

Declarative Thinking

As C++ programmer, I think the biggest challenge for me was to change the way of thinking. In C++ for example the scopes of the variables are pretty tight. Of course this depends on the way how you program, but in QML it was hard to get used of it that you can access members or properties of a QML component from another component.
I’m not so familiar with JavaScript(ing) so I rather do the “difficult” stuff in C++ side instead of QML side, unless they are fully UI specific for example I did minopr thumbnail size calculations in a small piece of script. I guess this is just a matter of taste, but some of the Declarative examples were quite confusing because they are using JavaScript so much. In my opinion the readability of a qml source file decreases if you want to include too much scripts there. Maybe better way would be to separate scripts to own .js files and import them to the QML files.
This chapter is called “Declarative Thinking” and why I wanted to raise this change of thinking is because of interfaces get more important when implementing QML based application. With this I mean, that in a real life, I believe that most of the QML applications are split in two: the C++ and UI/QML side.

To design application properly it requires more from C++ developers to introduce better interfaces for QML developer. I’m not saying this is bad, actually it is much better because this way it forces C++ developers to do their job better.

Graphics View, Qt Quick and Next Generation Widgets

QML is based on GraphicsView i.e. each QML Item is an instance QDeclarativeItem which inherits QGraphicsObject. If you use QDeclarativeView in your application for instantiating your QML UI it actually creates QGraphicsView and QGraphicsScene and hides all the bulk stuff like creating QdeclarativeComponent and so on.
I must humbly bow all the Trolls who have make this possible because it’s really amazing how well the Declarative module seems to integrate to the existing Qt code base.
One lack of QML and of GraphicsView is the lack of widgets. If you want to build your own application on top of QML or GraphicsView, then you will need to create all the widgets (buttons) yourself. QML introduce Item for TextEdit and in QgraphicsView side there QgraphicsTextItem. I believe that one reason for the fact that there is no “widgets” for QML and for QgraphicsView is that when the next generation widgets are ready, then the widgets can be usable for both QML and GraphicsView.
Some time ago I had a small discussion with one of the Trolls who told me that the plan for NGW is that they will separate the current “Control” part for the existing QWidgets. The control part is used for drawing the actual primitives of the QWidgets via Qt’s style system. When the Contol part is separated, then it can be used from QGraphicsView side also. After this it “only” requires that there is a QGraphicsWidget/Object based widget, which uses the same controller than the corresponding QWidget based widget. This way the both widgets will get same appearance based on the platform style. The drawing only happens in a different place and in GraphicsView’s case it happens in GraphicsScene.
This was just my guess, why there aren’t any widgets in QML side at the moment. Interesting to see where all this will go.

Conclusion

I can consider myself as a C++ developer and therefore it wasn’t so straightforward to get into a QML. I manage to build pretty neat QML based UI for QuickFlickr less than 10 hours starting it from scratch. During the development, I reported a few bugs, which were fixed really fast. When I ran into some problems, Trolls were very helpful in QML irc channel #qt-qml @freenode.
The QML stuff that I have used in QuickFlickr so far, are quite basic stuff and I didn’t do any difficult things there. I still need to take a look at how to extend QML with own components and get little bit deeper with the JavaScript.
If I have understood the meaning of WebRunTime (WRT) correctly it means that you can basically use platform services from JavaScript code. It also means that you can develop native looking apps using  web tools (html, css, etc). I think this is also a one place where QML might be very handy.
If you’re interested in about QML and how it works, just crab the source code, build it and start QMLing. I believe that the Trolls who are developing QML are more than satisfied if they will get more feedback and users for QML. It’s still few months left before they will release Qt 4.7 so let’s help them to do it as good as it can.
Thanks for reading my blog.

Tags: , , ,

6 Responses to “My First Qt Quick App – QuickFlickr”

  1. saxen says:

    wow, that’s sound great! when we will see it on repos?!
    nice work ;)

    • zchydem says:

      @saxen Thanks for your comment.

      I would wait for a while to get Declarative module’s API stabilized. Then it of course requires that there’s Qt 4.7 Maemo 5 version with Declarative UI available.

      If I manage to make QuickFlickr to little better shape I can always provide the package with required Qt modules.

      I’ll inform the status of the QuickFlickr in this blog.

  2. saxen says:

    ok i’ll wait for it! in the meantime i’ve just written few words about quickflickr ;)

    regards!

  3. kypeli says:

    Excellent post as usual! Nice to see that you have also taken into consideration the look ‘n feel of the application since the application actually looks nice too :) Something I would have a hard time to do.

    I should also take a look how to cross the C++ border from QML since this demonstrates in my opinion how we do applications in the future. I think in the end there will be still one layer above QML, maybe a GUI application that the graphics designers will use. And the application developer’s job will be to work mostly on the C++ backend side, but also work more closely with the graphics designers now that QML enables it so nicely.

  4. DomesticMouse says:

    As someone who is learning how to do a hybrid c++/qml app on qt4.7 trunk, I’d really like to have a geek at your code to get a feeling for how it’s done properly… =)

Leave a Reply

You must be logged in to post a comment.