PDA

View Full Version : A QList With large number of rows - Please give pointers.



krishnaramram
23rd October 2011, 11:24
Hello,

I am trying to display a list view of all contacts in phone book within my app.I used QListWidget and ListWidgetItem to setup my List view. It works well, but if the list is very huge for example if the number of contacts is more than 200 or so, the list loads in around 4-5 secs, and during such time the app hangs. This approach is also bad i guess in terms of memory usage. Adding to the QlistWidget is via a for loop for all the items i have.

I need pointers to how to optimize it. I understand delegating listview is correct thing to do. Please correct me on the following.

1.) Can i use set a model for QListWidget, and use delegates for it.

2.) Each row in my list has a background,a button, and text field. I need to able to set these for each row. I think the delegates paint and size hint methods must be used.

2.) Setting the model for the list view. Do I need to inherit my data structure from the model classes and implement methods? I hope this is the starting point for setting a model.

In Cocoa-touch framework there is something called UITableViewDelegate and UITableViewCell e.t.c., in which the view just loads only visible rows. I am looking for something similar and hope QList MVC is similar.

ChrisW67
23rd October 2011, 22:55
You either use QListWidget (with its embedded model) or you use QListView and a model. You can apply a delegate to either the widget or the view to control how data is displayed. You can use a custom delegate to do the background colour, or you can use the model Qt::BackgroundRole to suggest a colour to the default delegate. Which option you choose is driven by numerous factors including convenience and the form the source data takes.

To create your own custom model you derive from QAbstractTableModel, QAbstractListModel or QAbstractItemModel depending on the form of your data.

None of this has any bearing on how fast the data is loaded, which seems to be excessive for 200 records.

The QSqlTableModel does paged on-demand loading of large data sets from SQL tables, but it would load 200 rows in the first chunk of 256 anyway.

krishnaramram
24th October 2011, 06:51
Thanks many for your reply. Rephrasing my problem.

In my case there are two things taking time -
1.) the time for fetching data, form whichever store, i.e. file, database, e.t.c.

2.) the time for rendering it in a list view.

In my case time for (1) is fixed, no matter what I do, as I am reading contacts from phone book.

For Optimizing (2) should delegating help?

Rendering kind of takes around 2/3 of the time.I add around 200+ items to a list widget using AddItem(ListWidgetItem) this is around 4-5 secs.Now suppose i delegate the list view, should it not load in little less time, because the items it renders are all the ones the list needs to set up. Probably the model needs to be set up, but once that is done its should be very efficient?

In other words the list just 'setups' the number of visible rows.

ChrisW67
24th October 2011, 09:11
The list widget only paints items that are visible in the view anyway.

You must be doing something odd because I can add 500 simple items to a list widget in around a millisecond. The list widget is fully displayed while the items are being added, and scrolls smoothly top to bottom. Even on a much slower machine I cannot see it taking 5000 milliseconds for 200.


#include <QtGui>
#include <QDebug>

class MyListWidget: public QListWidget {
Q_OBJECT
public:
MyListWidget(QWidget *p = 0): QListWidget(p) {
QTimer::singleShot(0, this, SLOT(fill()));
}

public slots:
void fill() {
QTime t;
qDebug() << __func__;
t.start();
for (int i = 0; i < 500; ++i) {
QListWidgetItem *item = new QListWidgetItem(QString("Item %1").arg(i));
addItem(item);
}
qDebug() << "Elapsed time:" << t.elapsed() << "ms";
}
};

int main(int argc, char *argv[])
{
QApplication app(argc, argv);

MyListWidget w;
w.show();

return app.exec();
}
#include "main.moc"

output:


fill
Elapsed time: 1 ms


What are you doing while loading the data into the list widget that is taking so long?

krishnaramram
24th October 2011, 13:39
My app is being built for Symbian phones, and I am using N8. This is the code I call for each row in list, taking the contact name and phonenumber from phonebook. This piece of code is called for as many contacts as the app has in the phonebook.

//Parent widget to hold Two labels firstlbl,secondlbl and a button callButtonWidget
QWidget *w = new QWidget;
QFont font("Arail");

QLabel *firstlbl = new QLabel(w); //Holds the name of the contact
QLabel *secondlbl = new QLabel(w); //holds the number for a contact

secondlbl->setStyleSheet("font-size: 15px;color:white;");

firstlbl->setFont(font);
secondlbl->setFont(font);

firstlbl->setStyleSheet("font-size: 20px;color:white;");
firstlbl->setText(*name);
secondlbl->setText(*number);

firstlbl->setGeometry(10,0,290,30);
secondlbl->setGeometry(10,30,290,30);

//Call ButtonWidget derives from Signal mapper.
//Need to identify call button clicked on what row.
callButtonWidget = new CallButtonWidget(*number,w);
QObject::connect(callButtonWidget,SIGNAL(clicked(Q String)),this,SLOT(calling_clicked(QString)));
callButtonWidget->setGeometry(280,20,50,50);

QListWidgetItem *item = new QListWidgetItem;
item->setSizeHint(QSize(360,90));
listWidget->addItem( item );

//Setting the widget item.
listWidget->setItemWidget( item, w);

This is how my List widget looks like.
7029

john_god
24th October 2011, 14:22
I had the same problem using a QTableWidget in symbian, the speed performance was so much slower than desktop.
Right now I'm dont have my code at hand, but I think it was setSizeHint(), and a autoresize option. The table was filled with items in a for loop.I removed the autoresize option with a fixed value in the constructor, and it got better. But with large numbers like 200, I think it's still bad. Try removing setSizeHint() to see what happens.