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.

September 03, 2010

The Qt Blog

Be an early bird at Qt Developer Days

Developers, experts and business leaders looking to join us at Qt Developer Days are running out of time to take advantage of the $200 / €200 discount early bird rate.

Qt Developer Days 2010

Qt Developer Days 2010

Attendees that register before September 15 for the three day event package at Qt Developer Days Munich or San Francisco receive full registration for €499 / $499 instead of the normal price of €699 / $699.

The same discount applies to the day two and three package, with early bird prices of €399 / $399 rather than the full rate of €599 / $599.

Day one focuses on Qt training, while days two and three feature general sessions (keynotes on day two), technical track, Qt labs, Qt in use track, a sponsor and partner exhibition and a support desk.

Qt Developer Days is packed tight with tracks and sessions with all of the key experts behind Qt, as well as keynotes from industry players like Dreamworks, who will be sharing insights about their work using Qt to create amazing animation.

Qt Quick has its own training track this year, and there is also a dedicated training track for “Qt mobile development for Nokia devices”. Read more about the agenda here .

All packages include access to the conference sessions, the exhibition area, lunch and refreshments across the days registered for, a welcome reception presented by platinum event sponsor Tieto and the traditional Dinner with the Trolls evening on day two.

We also allow attendees to take advantage of our discounted hotel rates, and there are special group discounts available too.

The brightest and best people at Qt are booked and ready for Qt Developer Days. Register before September 15 to join us there and it will benefit your hip pocket as well as your Qt knowledge, skills and experience.

Visit the Qt Developer Days website at http://qt.nokia.com/qtdevdays2010

by David Stone at September 03, 2010 12:18 PM

Unifying Users’ Web TV Experiences Via Social Media with Qt Quick

The mixd.tv app allows users to search, view and share online video content.

The mixd.tv app allows users to search, view and share online video content.

The arrival of Internet-based television services over the last five years has been a game-changing technology.

As a company, mixd.tv recognized that the current abundance of web TV is not without its challenges. Web video is widely dispersed all over the Internet on different video platforms and finding the right video content is complicated and extremely time-consuming. The mixd.tv desktop application aims to address these fragmentation challenges – offering a new way to access and share online video content via social media channels in a natural web 2.0 connected style.

Fully aware that its service will be judged on its ‘last mile’ of delivery and the quality of its user interface (UI), mixd.tv evaluated the Qt framework – including the Qt Quick UI Creation Kit – as an alternative to its existing GTK frontend. The goal of the mixd.tv project was to deliver a social media TV service using a user interface that featured organic animations and effects.

With mixd.tv, users can find and play videos from different online video and TV sites with support for Windows, Linux and Mac OS X. Videos can be collected in playlists and shared on a community website at http://mixd.tv where others can follow these playlists.

“Using QML and Qt Quick to build our User Interface, we now have a UI to display video content (including thumbnails and content description) as well as dialogs to create and select playlists. Our use of Qt Quick has been wide-ranging: we’ve built buttons and scrollbars, and are also using grid models to display videos, playlists and search plugins,” said Kristian Müller, mixd.tv CEO.

The user interface itself communicates with a Python backend via Python-boost as a bridge framework, with the option open to add more video services via an open Python plugin API. Working within a tight knit team, mixd.tv found that Qt Quick opened up wider opportunities for its UI designers and developers to use Qt, some of whom were more familiar with scripting languages.

Three developers began work on the Qt Quick elements of the project – working with the Python backend and the Qt Quick based frontend simultaneously.  The team was productive with Qt Quick after only a week, and within three weeks they had the first working prototype up and running.

Using Qt Quick, mixd.tv was able to radically speed up UI development.

“After integrating Qt into our build process, we are now able to create preliminary demos with turnaround times of around one day. We are constantly learning new things about Qt Quick, but are already productive with the technology, producing UI layouts and effects in little time.  Performing more advanced tasks, such as adding an advanced component like an animated volume bar, usually takes us around a day,” said Müller.

Looking back at the sum total of its work with Qt, mixd.tv has radically increased its anticipated development speed for the UI – and in terms of tweaks and augmentations at this closed beta stage, the company says that it can change the layout of the UI as needed without touching the backend. Instead of a full restart, testing a new colour on a button requires just a mouse click when working with Qt Quick.

Relying heavily on Qt Quick as a central element and driving force in this project, mixd.tv is acutely aware of the importance of its UI. Although its basic service is free, the company clearly has a monetization model for its new technology proposition. Given the high demands inherent in a visual market like online video and TV, delivering a powerful, feature-rich UI is a must for mixd.tv. For these reasons, the company put its faith in the Qt user interface and application development framework including Qt Quick.

by Adam Walhout at September 03, 2010 11:50 AM

September 02, 2010

Qt Labs

Fonts in Lighthouse

The font system in Lighthouse was more or less a straight copy from QWS. From time to time I use the browser example test Lighthouse, but I was pretty annoyed that Lighthouse didn’t pick up the fonts on my system, but used the fonts that was shipped with Qt. Also one thing that has been in the back of my head when thinking about fonts and Lighthouse is that QtGui was linking against (or including) FreeType. This is something we don’t want if we are going to port Lighthouse to some other platform with some other glyph rasterizer.

So last week I put something together:
QPlatformIntegration has a new accessor:
QPlatformFontDatabase *QPlatformIntegration::fontDatabase() const;

QPlatformFontDatabase has relatively small interface:

virtual void populateFontDatabase();
virtual QFontEngine *fontEngine(const QFontDef &fontDef, QUnicodeTables::Script script, void *handle);
virtual QStringList fallbacksForFamily(const QString family, const QFont::Style &style, const QUnicodeTables::Script &script) const;
virtual void addApplicationFont(const QByteArray &fontData, const QString &fileName);
virtual void releaseHandle(void *handle);

QPlatformIntegration is suppose to return one QPlatformFontDatabase, and its this class which is responsible to populate an internal db with font families.

I ended up pushing the creation of fontengines to the plugin as well. This way the fontengines don’t need to be part of QtGui, but can be pushed to the plugins.

Its a bit much to expect everyone who wants to write a Lighthouse plugin to write a QPlatformFontDatabase from scratch, so todays functionality++ is implemented and put inside the platforms plugins src directory:
$QTSRCDIR/src/plugins/platforms/fontdatabases

When I made the patch Paul had one big objection: There is no default implementation. Do we need to have some include magic in the pro file, and have non cross platform code in the minimal plugin?

ARGH…. I thought. There is no way to have completely cross platform way of doing this…

Default implementation
However, there is. A few years ago Simon and Paul made a pre-rendered font format they ended up calling qpf2 (wild guess is that it stands for QtPre-renderedFont2). That font-engine was tightly coupled with Linux, but that was because of some ultra-fancy cross process glyph caching which QWS used. By just using the cross platform code the default implementation of QPlatformFontDatabase will pick up all qpf2 files in the prefix/lib/fonts dir and use them when rendering text. Sizes will be completely wrong, but hey a letter in the wrong size is much much better than an empty box?

Unix FontDatabases
I have no interest in xlfd so I have ignored these fonts. However using fontconfig to pickup fonts which I can rasterize with freetype is interesting. There are no X dependencies so it will work with the LinuxFb plugin or the DirectFb plugin. I ended up making 2 fontdatabases. QBasicUnixFontDatabase which is simmilar to what QWS did, and QFontconfigDatabase. However, choosing is a bit crap I think. So I made a QGenericUnixFontDatabase as well. It takes checks the Qt configuration and does the right thing based on that.

I decided that using these implementations needed to be as easy as possible, so all that is needed is to include the pri file and instansiate the fontdatabase in the platform integration. I have changed all the plugins in the repository to use QGenericUnixFontDatabase, so have a look in ie. directfb to see how to do this for your plugin.

by Jørgen Lind at September 02, 2010 02:17 PM

Qt SDK packages for Qt 4.7.0 Release Candidate available

For those who prefer to test and use a complete package, we added Qt SDK packages that contain the Qt 4.7.0 Release Candidate and Qt Creator 2.0.1. You can download the SDK packages here.

by Daniel Molkentin at September 02, 2010 12:41 PM

August 31, 2010

Qt Labs

QtDemo is no longer my Twitter client

On the off-chance that anyone other than me uses QtDemo as their twitter client (because I know that some people have a well-developed sense of humor), it should be known that the QML Twitter client demo is being scaled back from a proper client to a read-only search application. This is due to Twitter’s planned switch to requiring OAuth authentication, and for further discussion of this you can read the paragraph below. The key point is that a full Twitter client is now more involved than a QML demo should be, and to cut out a swath of OAuth code we had to cut some functionality too. Those who are undaunted by additional complexity can checkout the OAuth enabled demo, which was dumped at http://gitorious.org/qt-qml-demo-playground/qt-qml-demo-playground in the twitter-oauth directory.

The problem with OAuth is that it’s meant for web applications. For native applications, it just doesn’t work. The problem is that you need to either A) Launch a web browser (ruining your experience, especially on small devices) or B) fake it all in a WebView behind the scenes (which is doing extra implementation work just to keep the same UI, password entry and all). On top of this, native applications can’t really hide their secret key, especially open source ones. I can see why Twitter is allowing native application developers to ask for special treatment (xAuth), but don’t understand why they want to dole it out on a case by case basis - as I figure that all good native clients will shun OAuth.

by Alan Alpert at August 31, 2010 04:19 PM

4.7 program update

Every Monday the Qt program team meets to discuss the current status for the next release. We thought it might be a good idea to share some of the results of our discussions with you.

We are now focusing on getting 4.7.0 out of the door. Today we were reviewing showstopper bugs - that means bugs with priority P0 and P1 that are not explicitly scheduled for a later release - and decided to down prioritize QTBUG-12644 and QTBUG-12611. Down prioritizing here means that we aim to get it in but won’t hold the release if we can’t make it. The fixes will then go into 4.7.1.

We are currently going through the feedback we received on 4.7.0-RC and hope you keep it coming. However, we have decided that anything that comes in after Friday will go into an early patch release, probably 4.7.1.

by Alexandra Leisse at August 31, 2010 12:14 PM

August 30, 2010

LynxLine

Jongling Qt models

When you work intensively with data in your application then soon or not but you will realize that the best way of keeping them is some model object inherits from QAbstractItemModel, then data are hidden inside implementation of model. Adding, removing and modification are accessible through your API of the model class and it calls for appropriate model modifications (like beginInsertRows/endInsertRows). If you implement it in the way, then it is ideal for developer to use it in vews, operate with datas, implementing undo (see previous post: Undo in complex Qt projects).

It is often situation when all application data are some kind of hierarchical tree of objects and properties. So, all of them can be kept in just one tree-like model class, but I see that developers do not use the approach and it happens because they do not see how some selective piece of data can be shown or have expectations of implementing own view classes, which is not trivial though and you may spent too much efforts there. Instead a lot of code related to synchronization between models can appear and it leads to complication of logic.

Same time, it can be resolved by implementation proxy models and use just standard view classes from Qt which are very effective. And I would like to show here that it is really simple:

There is simple example that I had to implement recently. The application shows list of objects, and same time it should show list of all properties of all objects. My first impression was to implement two separate models that may have shared data or base data are kept in one of model + some synchronization. But I saw that data manipulations leads to code complication + undo should be implemented smoothly.

We can implement just one model which is tree of objects (two levels). In one view (we can use QListView to show only first level of tree) we show listed objects. But what about another view to list of all objects of second level – we can implement proxy model which will be model of view

ProxyModel

Let’s have a look at QAbstractProxyModel. For mapping we need the implementation of mapFromSource() and mapToSource() plus rowCount / columnCount() / parent() and index().
Because destination model is table-like, parent() returns just QModelIndex(), columnCount() returns count of source model, and index() returns just createIndex(row, column).
More complex are rowCount(), mapFromSource() and mapToSource() because they need to calculate. (see a listings below)

Another piece of logic – appropriate behavior on adding /removing rows and data changes. QAbstractItemModel has very convenient signals reporting process of adding rows or columns. With recalculating indexes we can just call same methods of proxy models, like:


...
connect(source, SIGNAL(rowsAboutToBeInserted(QModelIndex, int, int)),
        this, SLOT(s_rowsAboutToBeInserted(QModelIndex, int, int)));
connect(source, SIGNAL(rowsInserted(QModelIndex, int, int)),
        this, SLOT(s_rowsInserted(QModelIndex, int, int)));
...

void Proxy::s_rowsAboutToBeInserted(QModelIndex p, int from, int to)
{
    if (!p.isValid())
        return;

    int f = ... // calculate
    int t = ... // calculate
    beginInsertRows(QModelIndex(), f, t);
}

void Proxy::s_rowsInserted(QModelIndex p, int, int)
{
    // post adding routines if needed
    endInsertRows();
}

So, to summarize: it is not much efforts to implement proxy model which do appropriate data mappings in both directions. As benefit you have data kept in one place, all necessary signals by model to report changes in data (model). By mapping / proxying / filtering you can visualize in view any piece of data, even from different levels of hierarchy, etc. To visualize you can use just standard Qt view which are very effective.

Full listings of my proxy model:

UngroupProxyModel.h
UngroupProxyModel.cpp

by admin at August 30, 2010 09:47 AM

August 29, 2010

Holger Hans Peter Freyther

Going from dummy to real data

I was writing about my current QML project earlier and now was the time to go from dummy data to real ones. For the prototyping phase we were using models created with ListModel and the attributes we need in the UI. For some JavaScript code that is called to execute actions we were using ListModel.get(index) to get the item and then execute code.

The QML Documentation was bringing me very far. I was using the rootContext of the QDeclarativeView to add a controler object and the models to the QML runtime. The controler is called when the models needs to be updated, e.g. I am calling them from ScriptAction on state transitions. For QML a model only needs to set the rolenames and then handle the different roles. This was working quite nicely, and the old modeltest can help to debug the model.

After the above a simple ListView { model: myModel } will work nicely. Now I was writing about that we are using ListModel.get and I assumed that it would just magically work for my model as well, e.g. using the rolenames as well. From what I have seen that is not the case. This means your model needs to implement a Q_INVOKABLE QVariant get(int index); and internally use a QMap and somehow duplicate code that is already there.

Another problem came from updating models. This is something that does not happen with static data, but happens in my case. I was using the big hammer with emit beginResetModel() and emit endResetModel() in the model and on the QML side one can use onCountChanged in the ListView to handle a massive update and execute JavaScript. In my case this was used to automatically select the first item and set the currentIndex of another ListView.

by zecke (noreply@blogger.com) at August 29, 2010 04:50 PM

August 28, 2010

Richard Moore

Implementing a Reusable Custom QNetworkReply

In my last blog post, I showed how to use a proxy QNetworkAccessManager to restrict network accesses to sites included in a whitelist. One limitation the previous version had is that it stopped the disallowed requests by rewriting the request itself to be to an invalid url. This then caused the default implementation of QNetworkAccessManager to generate an error reply for us. This post will look at how to create a custom reply directly, to allow us to display messages to the user etc. or even provide 'virtual' content.

The approach I've taken is to try to write a reusable utility class for sending basic network replies. I've called the class QCustomNetworkReply since if there's a reasonable level of support then I'll try to work it up into a merge request for Qt. To begin with, lets see how the whitelisting proxy looks now that it uses the new class:

QNetworkReply *WhiteListNetworkAccessManager::createRequest( Operation op,
                                                             const QNetworkRequest &req,
                                                             QIODevice *outgoingData )
{
    // If host is not whitelisted then kill it
    if ( !isAllowed( req.url().host() ) ) {
        QCustomNetworkReply *reply = new QCustomNetworkReply();
        reply->setHttpStatusCode( 403, "Forbidden" );
        reply->setContentType("text/html");
        reply->setContent( QString("<html><body><h1>That url is not in the whitelist</h1></body></html>") );

        return reply;
    }

    QNetworkReply *reply = QNetworkAccessManager::createRequest( op, myReq, outgoingData );
    return reply;
}

The new code operates if the request is to be disallowed. First it creates our custom reply, it then specifies the HTTP response code to send. Finally it sets up the content type and the content itself. Finally, we return our custom reply. As you can see, the API of the QCustomNetworkReply class is fairly simple to use (in fact the only required part is setting the content).

Now we've seen how it's used, lets take a look at how the custom network reply works. The class declaration is fairly simple:

class QCustomNetworkReply : public QNetworkReply
{
    Q_OBJECT

public:
    QCustomNetworkReply( QObject *parent=0 );
    ~QCustomNetworkReply();

    void setHttpStatusCode( int code, const QByteArray &statusText = QByteArray() );
    void setHeader( QNetworkRequest::KnownHeaders header, const QVariant &value );
    void setContentType( const QByteArray &contentType );

    void setContent( const QString &content );
    void setContent( const QByteArray &content );

    void abort();
    qint64 bytesAvailable() const;
    bool isSequential() const;

protected:
    qint64 readData(char *data, qint64 maxSize);

private:
    struct QCustomNetworkReplyPrivate *d;
};

The first group of methods are those for setting the various headers on our response. They are really just convenience wrappers around existing methods (for example making some protected functionality public). I won't go into any more detail about them since the implementations are obvious looking at the source. The two setContent methods are where things start to get interesting:

void QCustomNetworkReply::setContent( const QString &content )
{
    setContent(content.toUtf8());
}

void QCustomNetworkReply::setContent( const QByteArray &content )
{
    d->content = content;
    d->offset = 0;

    open(ReadOnly | Unbuffered);
    setHeader(QNetworkRequest::ContentLengthHeader, QVariant(content.size()));

    QTimer::singleShot( 0, this, SIGNAL(readyRead()) );
    QTimer::singleShot( 0, this, SIGNAL(finished()) );
}

The first method is simple a convenience and allows us to use a QString rather than a bytearray for the content, yhe second is where the real action is. First, we store the content. Next, we zero the offet that stores how much data has been read from our reply (remember a QNetworkReply is a QIODevice) and open our io device. Now that we have the content, we also set the response header that specifies the amount of data we have. Finally, we use two single shot timers to cause the readyRead() and finished() signal to be emitted when the event loop is reentered. We can't simply emit these signals immediately since the reply has not yet been returned by our QNetworkAccessManager, so nothing is listening for them.

The final part of the code is to provide a basic implementation of a QIODevice to allow the stored content to be read back out:

void QCustomNetworkReply::abort()
{
    // NOOP
}


qint64 QCustomNetworkReply::bytesAvailable() const
{
    return d->content.size() - d->offset;
}

bool QCustomNetworkReply::isSequential() const
{
    return true;
}


qint64 QCustomNetworkReply::readData(char *data, qint64 maxSize)
{
    if (d->offset >= d->content.size())
        return -1;

    qint64 number = qMin(maxSize, d->content.size() - d->offset);
    memcpy(data, d->content.constData() + d->offset, number);
    d->offset += number;

    return number;
}

That's all there is to it - see all fairly straight forward. The nice part is that now we have the QCustomNetworkReply, we don't need to do any of that work again and can simply reuse this class whenever we want to send data directly to clients of QNetworkAccessManager. As usual, the code is available from my qt-examples git repository at http://gitorious.org/qt-examples/.

by rich at August 28, 2010 01:55 PM

August 27, 2010

Robin Burchell

Another day, another itch.

(First, an apology in advance, this is a bit of a braindump, and as such, isn't very well structured.)

I've recently been diving into SQL support in Qt, provided by the QtSql module. Specifically, I've been looking into providing IPC on top of QSqlTableModel.

(For those of you who aren't too technically oriented, I'm trying to have multiple processes have the same basedata store, and know when another process modifies the data in some way, to keep all processes in sync).

While I won't go into details on that now, as it isn't complete, it has been an interesting journey, and I think I've found yet another few things I want to add to my todo list. You see, QSqlTableModel is a great class, but it has a number of shortcomings.

It can't be used in a tree

This one is pretty obvious. It is, after all, a table - not a tree. However, making it represent a tree wouldn't be all that difficult I think (a customised implementation of QAbstractItemModel::parent() method looking at e.g. the 'parent' column of a table and returning a QModelIndex to the appropriate row or similar).

I don't believe that this can be solved in the current implementation, though, as QSqlTableModel inherits QSqlQueryModel which inherits QAbstractTableModel - meaning there's a non-trivial amount of tableness about the current implementation.

For some data (think a task manager: you might have subtasks under a task), this is an annoying limitation.

Incremental fetching isn't always supported

I'm actually not positive on this point, but it looks like incremental fetching is left up to the database driver, meaning that on some database types, you won't have incremental fetching.

On a large database containing thousands of rows (or gigabytes of data) this could be a very bad thing if I am correct.

Partial updates aren't really supported

If you delete a row from a database table, what would you expect the client to do after deleting that row?

I know I certainly wouldn't expect it to re-run the query to refetch the data, yet that's exactly what QSqlTableModel seems to do. Not nice.

This also happens on any other conditions of alteration to the data, which strikes me as being rather inefficient.

Furthermore, it isn't really possible to update values on the fly; this proved to be quite an annoyance when implementing IPC notifications of updates. QSqlQueryModel internally contains a QSqlQuery. QSqlQuery has a ::value() method, to retrieve a QVariant containing the data in a given row of a result set. It doesn't, however, provide any method to change that data (even in memory), meaning that once again, a full reload is the only real solution to something else changing the data out from under you.

This isn't really so unexpected, as it's a bit of an odd use-case, but it has made my implementation trickier than I'd wish.

Conclusion?

I wish. I don't know what to do, yet, but I suspect it's going to involve writing code.

Thoughts welcome.

by viroteck@viroteck.net (Robin Burchell) at August 27, 2010 01:10 PM

Stephen Kelly

Grantlee version 0.1.5 now available

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

The release contains several bug fixes and makes it possible again to build Grantlee with Qt 4.5 again. The most significant part of this release though is that Templates can now be cached and rendering Templates is almost threadsafe. Prior to this release there were several template tags which stored state while being rendered. The cycle tag is a good example of where this is a problem, and many people complain about it. Because the template stored and modified some state while rendering, the second and subsequent renderings would not not start with a clean state, and would not produce identical output in all cases. That meant that Templates are often discarded right after use and reloaded later. It also meant that Templates had to be loaded from the file system on each access even if they were accessed very often, otherwise the cached version would be volatile and contain the wrong data.

With a change in the system to make the Template::render method re-entrant, state is no longer stored in the Template itself, but in a RenderContext object. An instance of that object is available to templates while rendering to store mutable data. Additionally, that would mean that a single template can be rendered by multiple threads at the same time which could be significant if using Grantlee for a mail-merge functionality. Unfortunately, due to a twist in how I implemented escaping in Grantlee, that version of render() is not threadsafe yet. That should be solved in a binary-incompatible release of Grantlee in the future as well as making the render() method const so that third party template tags must be re-entrant.

Changes so far in Grantlee do make Templates cache friendly though, so I introduced a CachingLoaderDecorator which can be used to cache any Templates loaded by a TemplateLoader. Do for now at least, worse is better.


by steveire at August 27, 2010 09:58 AM

Arora Web Browser

Arora on os2

The group over at netlabs.org has ported Qt4 to OS2. Along with that they have got QtWebKit building on OS2 and now have an Arora on OS2 binary you can download. With a few minor build related fixes (now in git) to Arora it now builds out of box and can be run on OS2.

by Benjamin Meyer (noreply@blogger.com) at August 27, 2010 08:31 AM

August 26, 2010

Qt Labs

Qt 4.7 Release Candidate and Qt Quick

As many of you may already know, a few minutes ago we pushed a Qt 4.7 Release Candidate (RC). Qt 4.7 is a great step forward with regard to performance and the introduction of Qt Quick, and with Qt 4.7 we will see Qt applications run faster and smother than ever before.

With the release of Qt 4.7 including Qt Quick, you will immediately gain access to powerful features for building fluid, animated applications and UIs. Qt Quick is made up of three pieces: (1) the QML language and (2) the QtDeclarative module in the Qt framework, and (3) Qt Quick tooling components in Qt Creator.

Today´s RC, and the final Qt 4.7 release, will bring the first two pieces of Qt Quick. With the release of Qt Creator 2.1 in the fourth quarter of this year, you will get access to a built out set of tooling to make the Qt Quick experience much richer and easier – completing the picture. Snapshots of Qt Creator 2.1 will be made available shortly.

We look forward to your feedback and we encourage you to try out Qt Quick!

by Henry Haverinen at August 26, 2010 12:37 PM

Qt 4.7.0 Release Candidate available

Qt 4.7.0 RC1 is now available for download from the Qt Download Page. Source packages (.zip and .tar.gz format) and binary packages (for Mac Cocoa, Mac Carbon, MinGW 4.4.0 and Visual Studio 2008) are available.

Note the naming change of Mac packages compared to Qt 4.6.x has been repeated in this second beta. This reflects the fact that Cocoa is now the primary Mac platform for Qt. Binary packages for Carbon will be discontinued from Qt 4.8 onwards, but will continue to be shipped for the remainder of the 4.7.x series.

The purpose of this release candidate is to provide quality stabilised code that is ready for the 4.7.0 final release.

For those using the public git repository, a “v4.7.0-rc1″ tag will appear soon.

If you would like to provide feedback, you can do so using the Qt Bug Tracker. If you want to contribute code, documentation or autotests to Qt, all the information you need to get started can be found at qt.nokia.com.

by Toby Tomkins at August 26, 2010 12:23 PM

August 25, 2010

Stephen Kelly

KIdentityProxyModel does nothing, fast

It has been brought to my attention that I have not blogged in a while. That usually means it’s time for a new proxy model.

The latest one is KIdentityProxyModel. It maintains an identity relationship to its source model such that the structure in the proxy mirrors exactly the structure in the source model, without sorting, filtering, flattening or otherwise changing the structure.

KidentityProxyModel in action

What the KIdentityProxyModel does provide though is a base class suitable for data proxying. There are many uses for such a class. Typically, an implementation of QAbstractItemModel will have an implementation of the data() method with a large switch statement for returning the decoration, the tooltip, the what’s-this text etc. It becomes cumbersome and difficult to maintain. Better of course is to use separate proxy models instead of a switch statement. If your tooltip text is defined in a ToolTipProxyModel, you can compile it in on the desktop, and compile it out on mobile/touch platforms where they make no sense. Similarly, you can define a DecorationProxyModel to return images of different sizes for desktop and mobile use. In KDE PIM we already use it to color the folders in kmail if you are reaching an IMAP folder size limit. Another use I have for it is to make any model have checkable items with the KCheckableProxyModel. (Ok, so I made two new proxy models :) ).

KCheckableProxyModel makes check state available through a QItemSelectionModel

The primary reason for a class like this is separation of concerns, a separation of platform code and re-usable components. The overhead of using a KIdentityProxyModel is very small, so even using multiple proxies does not incur a great cost. I haven’t made any benchmarks, so I offer only proof by inspection.

After writing this class I was informed that something similar used to exist in Qt4 as QProxyModel, but was deprecated some time ago. I didn’t even know it existed. Its implementation is very similar to KIdentityProxyModel, but an important difference is that KIdentityProxyModel implements QAbstractProxyModel, while QProxyModel implements QAbstractItemModel. That means that chaining is possible with KIdentityProxyModel, but not with QProxyModel.


by steveire at August 25, 2010 10:56 PM

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