Itemviews data redundancy

Encouraged by some recent posts on Qt Centre I decided to point out a common issue when dealing with Qt model-view framework.

Many people often treat models as a burden that needs to be carried to be able to display some data using Itemviews. One needs to perform a tedious task of implementing the QAbstractItemModel interface or filling one of the ready made models such as QStandardItemModel with data. Most often the model needs to represent some data which is contained in some structure and it is not rare to spot people write code similar to this one:

struct MyStruct {
  int x;
  int y;
};
 
class Model : ... {
  //...
  QList <MyStruct> export() const { ... }
  void import(const QList <MyStruct> &){  ... }
  //...
};

What happens here is that they provide export and import functions to convert between their own storage format and the model. It’s a similar thing if they instantiate QStandardItems and feed it with data from some datasource. In both cases the data is duplicated – it is kept both in the model and in the external container.

Instead the model should be perceived only as an interface to an existing data – no matter if it is kept inside or outside the model object, a good example being QSqlTableModel and family – however the data is cached within the model, it is really kept on some remote server.

Instead of the above snippet of code, the skeleton could look like the following:

class Model : public QAbstractItemModel {
public:
  Model(QList<MyStruct> *dat, QObject *parent=0)
  : QAbstractItemModel(parent){
    m_data = dat;
  }
  QVariant rowCount(const QModelIndex &parent) const {
    if(parent.isValid() || m_data.isNull()) return 0;
    return m_data->count();
  }
  //...
private:
  QPointer<QList <MyStruct> > m_data;
};

As you can see the model operates on an external list of items and as long as the list is valid, it will return correct data. Of course the same applies to the rest of the interface – one can add rows and modify data kept in the list.

The only problem that remains is that the list can be modified outside the model, causing all components using the model (views included) to not update themselves upon changes in the list. Fortunately there are ways to overcome it.

The first good solution is to use a data source that can emit changes made to it using Qt signals. Then one can connect those signals to the model to be able to emit proper signals from the model to its environment.

The second solution is to disallow access to the data source outside the model, but then it makes more sense to embed the source within the model itself, either with “has-a” or “is-a” relation (remember, multiple inheritance is a beautiful thing 😎 ). It is probably the best solution if you fully control the data source and you can modify the code that uses it. It is worth mentioning that you don’t have to use the methods provided by QAbstractItemModel to access the data if it feels odd or difficult in your situation. You can define custom methods to access the data through the model – both in read and write mode (for example using MyStruct as the carrier). As long as you emit proper model signals from those methods, your views will continue to work properly.

The third option is to trigger manual or periodic updates of the model – for flat models things like row and column count can be cached and compared against the real source. If they are out of sync, one can try emiting one of generic signals – layoutChanged() or modelReset() to save the situation. Just remember that calling modelReset() will cause all your views to loose selections and item visibility. For simpler models (or better data sources) it might be possible to trace exact changes in the source and emit proper signals upon detecting changes.

Remember, the more complex the data gets, the easier to fall out of sync when using two separate data structures. Save yourself time and nerves and use a single data set instead of two whenever you can, even if it doesn’t seem obvious from the start how to do it. A good design always pays off.

Qt Centre staff increasing

Today Qt Centre forum community has been given two new moderators. J-P Nurmi and Marcel Nita have joined the forum staff. We have acknowledged their Qt skills a long time ago and now we had a chance to promote their devotion to the site. I wish the new Super Moderators great fun and as little work as possible in their new service to Community.

This is not the only addition to the moderator team. Last week we have opened a new sub-forum dedicated to Qwt and of course Uwe Rathmann, the author of the library moderates the section – so if you have any questions related to Qt widgets for technical applications, you can ask them at Qt Centre.

Congratulations to all the new moderators!

Mass mailing

Finally I managed to get most of the diplomas and gifts for the QtCentre Programming Contest mailed out. A few are still to be sent, because of some stupid mistakes we made. Anyway you should start receiving them. And if anyone still hasn’t received one of the prizes he won, let us know by email.

Sorry it all took so long, but we’ve learned a lot, so if we decide to start the second edition, we’ll organize ourselves much better this time.

Should we do the second edition? I’d like to know peoples’ comments on that…

50000 posts

Yesterday around midnight we breached the 50k posts barrier at Qt Centre forum. Unfortunately Jacek snatched that 50,000th post and it’s a pitty because we were planning to reward the poster, but we won’t reward ourselves, so we’ll have to wait for the 65,535th post or something like that :)

Nevertheless I’m very happy to see that after 20 months of Qt Centre activity we managed to gather such a knowledge base. I hope that the 100 posts per weekday trend will continue so that soon we can title ourselves “the biggest Qt community site and forum” instead of “the biggest actively maintained Qt community site and forum”. Although the post count is not really that important (the knowledge base is contained also in the wiki and the FAQ section ), it’s a solid figure allowing one to compare different forum based sites.

If you have any comments or ideas regarding Qt Centre, don’t hesitate to contact us via mail, private messaging, the feedback section of the forum or by commenting this post.

“Don’t play with matches while sitting on an open barrel of powder”

We have a saying in Poland like the one in the title of this post. Well… seems I forgot about it today (well… now it’s already tomorrow, so today means yesterday).

What happened? I bought myself a new shiny harddisk for my laptop and an external USB drive to put the old disk into use. That’s nothing bad of course. At least not on its own… But while preparing a working environment on the new disk I had the old disk hot-plugged to access its data. At some moment one of the volumes became inaccessible. The NTFS filesystem seems to be invalid and despite my tries to salvage the disk I was unsuccessful and it looks like I’ll have to say good bye to the data stored on that partition.

As it was a Windows installation and I rarely work on Windows there wasn’t much precious data there… Actually there was only one piece of valuable data there – one that wasn’t copied anywhere else… And now for the best part – what was that data? Well… not my bank passwords (thank God!) and not my PhD thesis (the risk of it being lost was minimal as the thesis doesn’t exist yet, but never underestimate the power of quantum fluctuations!). But unfortunately it was a final project of the diploma for the Qt Centre Programming Contest… What a shame… if I don’t find a way to access my data, I’ll have to make the diploma again and last time it took three months to do it :)

So… if anyone knows how to validate an invalid ntfs filesystem (standard Windows tools said it was unrepairable) without buying expensive software, I’d be grateful for any help in that matter.

Memo for today – Uncle Bill doesn’t like me.

Qt lectures

A while ago I wrote in one of my previous posts that many things had happened during last few months and I’d like to share some of them with you. So here is the first thing…

 

As you probably know I am a PhD candidate in Institute of Computer Science on Warsaw University of Technology. Part of my responsibilities involves having academic activities with students. Last semestre I managed to make myself part of the “Programming Interactive Applications” course that shows students the basics of technologies such as WinAPI, .NET, MFC, XLib and Qt. I was asked to conduct a six hour course on Qt, which entered the course just a semestre earlier. It was a very big thing for me – one might say that it was a vocation for becoming a “Qt Apostle” (I admit I borrowed that term from Scott Collins) so I treated it very seriously.

I think the lecture came out quite fine. The biggest problem was to decide what to tell about and what to omit. I talked quite much about paradigms like meta-types, signals and slots, layouts and virtual method based event handling. Because of that I had less time to talk about more advanced things like Arthur (I just managed to talk a bit about device independence and window-viewport transformations) or Interview (which is a pitty because you know how I like it…). But thanks to that I had more time to present the graphics view framework.

 Apart from the lectures I were to give students two exercises (not conducting them though). The first one was about creating a simple image viewer using available widgets and the second one was to prepare a kitchen timer widget and a Designer plugin for it. Students seemed to be interested in the projects so I guess the choice was correct. Starting with the semestre that starts in a week I’ll be conducting the exercises as well, so maybe I’ll have additional time to brainwash… eem… present some more Qt knowledge to students.

All in all people seemed interested in the topic which gives me much satisfaction. I should probably change or update the contents of the lectures a bit, so I’m waiting for your fresh ideas and comments. There is enough knowledge (as well as motivation and urg to pass that knowledge) to make a dedicated course, but unfortunately I don’t think an average PhD student can make that happen.

QRetargetScale

Of course I couldn’t resist myself from implementing the algorithm I have written about in the previous post.

Images below have been scaled to fit on the page. The second one was scaled down using the application.


QRetargetScale download

Image retargetting

I just stumbled upon descriptions of an innovative image scaling algorithm. I’m pretty impressed with the results. How about adding Qt::RetargetTransformation to Qt::TransformationMode? 😉

 

And an obligatory movie:

 

Qt book review

The Book of Qt4 coverSome time ago I’ve been asked if I wanted to write a review of one of the new books related to Qt. I agreed and soon after I had a copy of the book in my hands. Thanks go to Camille Herrera of No Starch Press for letting me do this. I’m certainly waiting for more!

 

The Book of Qt4 – The Art of Building Qt Applications review

 

If you do or don’t agree with my review, please leave your comment. Another review of the book is available here (the site seems to be currently down though).

Contest results

Oh, by the way – we have announced the results of the Qt Centre Programming Contest.