Displaying large amounts of data - Using QListView, QListBox and QIconView

Introduction

In most of the cases it's quite obvious how to use these three classes and display data in it. But when it comes to displaying larger amount of data it helps a lot if the programmer knows how these classes work internally to be able to use them better, as they offer already some optimations (and also I'm tired of telling the same things again and again :-)

Finally these three classes are quite consistent in Qt 2.1, so most of the things I will tell here apply to all of them. First I'll tell some stuff about the basics and later on some more fency stuff is coming.

NOTE: Never use QTableView to write a widget for displaying large amounts of data. In most cases one of the classes mentioned here should fit your needs. If this is not the case and you need to write your own class, use QScrollView as baseclass. Although in the first impression QTableView often looks like a good choice later on you will find out that this was not the case, and QScrollView fits better.

Inserting and removing items

All classes contain a number of items. To insert such an item it's the easiest way to use the related item class (QListViewItem, etc.). To insert such an item create a new instance and specify the view in the constructor of the item. That's all and nothing special so far. Now when it comes to inserting lots of items at once (e.g. using a loop) I have seen people playing around with timers and other paint optimations the avoid that the views repaint its contents too often (this means that the views don't do a repaint for each item insertion). But the programmers which use these classes don't need to do that at all, the views already do exactly that type of timer magic. So If you do e.g.

QIconView *view = .... // something
for ( int i = 0; i < 2000; ++i ) {
    (void)new QIconViewItem( view, QString( "Item %1" ).arg( i ) );
the iconview will not do a repaint for each new inserted item, but it will only do a repaint after the loop terminated. So inserting will not flicker or be slow. The same applies for QListBox and QListView. So, don't do any timer magic of your own, the views do that for you! This means the views internally delay the repaint after inserting a new item using a QTimer. Now when a new item is inserted this timer is stopped and restarted. So, if lots of items are inserted, this repaint timer is stopped and restarted all the time and it never comes to a repaint until the last item has been inserted and some milliseconds elapsed.

To remove an item, you don't need to use any methods of the view or so. Just delete the item using the delete operator. The destructors of the items do all the needed work.

Now, in some cases you might still want to disable repainting (updating) the view yourself. This can be done using setEnableUpdates( bool ). But remember, all three classes are derived from QScrollView, so you have do enable/disable updating of the viewport!. So do e.g.

myView->viewport()->setEnableUpdates( FALSE );
// ....
myView->viewport()->setEnableUpdates( TRUE );

Reacting on the correct signals

Finally also all three view classes have a set of consistent signals. This means each class has some specific signals + some general signals. Most of the time you will use some of the general signals, as these are the signals which are emitted on special mouse and key events.
I leave out here the arguments, as they differ a bit depending on the view. But in most signals you get a pointer a view item + some other arguments. Here are the signals + a short description. For further details (e.g. arguments) refer to the class documentation of these classes. Any of the pressed signals is emitted in the mousePressEvent, the clicked signals are emitted in the mouseReleaseEvent (=press+release).

Then there are a number of signals emitted by each view which I will not discuss here, as I think the signals mentioned here are the most important ones.

Single Click / Double Click

TODO

Sorting Items

TODO

Selection Modes

Each of the three classes supports four selection modes. These are following

In other words, Single is a real single-selection view, Multi a real multi-selection view, and Extended a view where users can select multiple items but usually want to select either just one or a range of contiguous items, and NoSelection is for a view where the user can look but not touch.

Because of compatibility reasons the enum with the selection modes has not been moved to the Qt namespace. So, each view class contains an enum with the same selection modes, which meas for setting a selection mode you have to use <TheViewClass>::<SelectionMode> (e.g. iconview->setSelectionMode( QIconView::Extended ) ).

Drag'n'Drop

TODO

In-Place renaiming of items

TODO

Special Settings of QListBox

TODO

In most cases listboxes are used to dispay plain lists. But QListBox can also display its items in multiple columns with dynamic or static widths and heights. See following QListBox memeber methods for further details:

Here is a screenshot of a plain listbox and one of a listbox with multiple columns (with dynamic column widths)
One column listbox screenshot Multi colum listbox screenshot

Finally, to iterate over all items of a QListBox use following code:

QListBox *lb = .... // something
for ( int i = 0; i < lb->count(); ++i ) {
    lb->item( i )->doSomething();

Special Settings of QListView

TODO

Finally, to iterate over all items of a QListView, use the QListViewItemIterator class:

QListView *view = ... //something
QListViewItemIterator it( view );
for ( ; it.current(); ++it )
    it.current()->doSomething();

Special Settings of QIconView

TODO

Finally, to iterate over all items of a QIconView, use following code:

QIconView *view = ... //something
for ( QIconViewItem *item = view->firstItem(); item; item = item->nextItem() )
    item->doSomething();


Reginald Stadlbauer <[email protected]>