Fastest way to display a scrollable table with text content?
-
Hi,
i am trying to do an android app that displays a medium large scrollable table, that adapts its width to the available space.
It has about 4 columns, 600 rows and has text content only.
So far i tried to put a lot of qlabel's into a grid layout. With gives me kinda ok scrolling speed, but building the table takes more then 3 seconds on my device, which is to much.
I also tried to use QTableView, also with QLabel in it, which allows me to build the table in about 0.5 seconds, which is okay (though i'd say still slow for a 4x600 entry table in c++), but the scrolling is very slow... plus it is no fluid scrolling, its table row wise scrolling (which actually is weired why this is slower then smooth scrolling)
What options do i have that improve the performance in displaying this type of data on mobile device?
Why is the grid layout so much slower then the table in build up? Does it try to recalculate everything after adding each widget? and if so, can i tell it that i'm going to add a lot of widgets now and make it recalculate only after the last one added?
-
Hi and welcome to devnet,
Since it's text, why are you using QLabel at all ?
-
Indeed but you wrote that you tried with a QTableView with QLabel in it. Since it's only text, there's no need to set any QLabel on that QTableView. Just show the QTableView
-
so here is what i did to improve the user experience on a large table on mobile:
QLayout provides a function setEnabled(true/false) which start stops automatic adaption when adding widgets
I subclassed qwidget for the table and added a signal dataAvailable() and a slot onDataAvailable() and set a QGridLayout on it (actually i settled on QVBoxLayout with QHBoxLayout entries in it, but i don't think it makes a difference performance wise)
Then when creating the widget, i store the data in the class and set a int row = 0, and in the constructor i do a
connect(this, SIGNAL(dataAvailable()), SLOT(onDataAvailable()), Qt::QueuedConnection);
(the last parameter is important)
In the onDataAvailable() do a setEnabled(false) on the layout,i count up the row variable and add up to 10 rows to the layout, do a setEnabled(true), then i emit dataAvailable() until all rows have been added.
This way the table still takes about 3 seconds to build up, but it starts displaying immediatly and feels much quicker. The question still remains though, is there a faster way? QTableView is not really an option, as it scrolls row by row which gives bad user experience when you have large enough rows for the user to select them with his finger.
Here is the code:
DataTable::DataTable(QWidget *parent) : QWidget(parent) { connect(this, SIGNAL(dataAvailable()), SLOT(onDataAvailable()), Qt::QueuedConnection); } void DataTable::addData(const QStringList &d) { data_.push_back(d); } void DataTable::create() { layout_ = new QGridLayout(); setLayout(layout_); row = 0; emit dataAvailable(); } void DataTable::onDataAvailable() { layout_->setEnabled(false); int block = 0; for (int r = row; r < data_.size() && block < 10; r++) { for (int i = 0; i < data_.at(r).length(); i++) { QLabel *lbl = new QLabel(data_.at(r).at(i)); lbl->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Maximum); lbl->setMinimumHeight(100); lbl->setMaximumHeight(100); layout_->addWidget(lbl, row, i); } row++; block++; } layout_->setEnabled(true); if (row < data_.size()) { emit dataAvailable(); } }
-
Wouldn't QScroller be what you are looking for when using a QTableView ?