Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

QTableView slow performance with 1000s of visible cells

Tags:

c++

qt

I'm using QTableView in Qt 4.8.4 to visualize a lot of data (large/many protein amino acid sequences) and I'd like to be able to make cells as small as possible so I can pack as many as possible into a given window. The problem I'm running into is that when there are many cells displayed at once, everything (e.g. scrolling, resizing, and in general repainting) slows down to a crawl. Here's some sample code (adapted from the examples/tutorials/1_readonly tutorial):

MyModel::MyModel(QObject *parent):QAbstractTableModel(parent){}

int MyModel::rowCount(const QModelIndex & /*parent*/) const {
   return 200;
}
int MyModel::columnCount(const QModelIndex & /*parent*/) const {
    return 60;
}
QVariant MyModel::data(const QModelIndex &index, int role) const {
    if (role == Qt::DisplayRole){
       return QString("%1").arg(index.row()%10);
    }
    return QVariant();
}

and here's the code which runs the table view:

int main(int argc, char *argv[]){
   QApplication a(argc, argv);
   QTableView tableView;    
   tableView.horizontalHeader()->setDefaultSectionSize(15);
   tableView.verticalHeader()->setDefaultSectionSize(15);
   tableView.setFont(QFont("Courier",12));
   MyModel myModel(0);
   tableView.setModel( &myModel );
   tableView.setGeometry(0,0,1000,1000);
   tableView.show();
   return a.exec();
}

When I use Instruments on OSX while scrolling up and down, it's spending a lot of time in QWidgetPrivate::drawWidget and down the stack, QWidgetPrivate::paintSiblingsRecursive... i.e., it's spending a lot of time redrawing my table.

I'm new to Qt, so I'm not sure how to approach this problem. Should I:

  • override the paint method? i.e. perhaps I could save my whole table as an image, and when scrolling happens, to just repaint the image until movement stops (and then return to painting the table directly)?
  • Not use tables in Qt at all? Perhaps I can just use a Text field to accomplish my purposes? e.g. for each letter in the text, i'd like hovertext, selections, coloring letter's backgrounds, etc.

Both of these options seem like a lot of work to make up for ground lost by switching away from QTableView. Are there any other suggestions?

like image 551
amos Avatar asked Dec 26 '22 18:12

amos


2 Answers

QTableView is known to be slow when dealing with large datasets. I suggest you to switch to Qt Graphics View Framework. It's much more efficient and is flexible enough to display a table.

QGraphicsScene scene;
QFont font("Courier",12);
QFontMetrics font_metrics(font);
int padding = 2;
int column_width = font_metrics.width("X") + padding * 2;
int row_height = font_metrics.height() + padding * 2;
int rows = 200, columns = 60;
for(int x = 0; x < columns; x++) {
  for(int y = 0; y < rows; y++) {
    QGraphicsSimpleTextItem* item = scene.addSimpleText(QString().setNum(y % 10), font);
    item->setPos(x * column_width + padding, y * row_height + padding);
  }
}
for(int x = 0; x < columns + 1; x++) {
  int line_x = x * column_width;
  scene.addLine(line_x, 0, line_x, rows * row_height)->setPen(QPen(Qt::gray));
}
for(int y = 0; y < rows + 1; y++) {
  int line_y = y * row_height;
  scene.addLine(0, line_y, columns * column_width, line_y)->setPen(QPen(Qt::gray));
}
QGraphicsView view(&scene);
view.resize(700, 700);
view.show();
like image 141
Pavel Strakhov Avatar answered Dec 28 '22 06:12

Pavel Strakhov


Try to use QTreeView, but set uniformRowHeights to true. Millions of items worked last time I've checked.

EDIT: QTreeView supports tables and more!

like image 21
user1095108 Avatar answered Dec 28 '22 07:12

user1095108