我在 Qt 4.8.4 中使用 QTableView 来可视化大量数据(大/许多蛋白质氨基酸序列),我希望能够使细胞尽可能小,这样我就可以将尽可能多的数据打包成一个给定的窗口。我遇到的问题是,当同时显示许多单元格时,所有内容(例如滚动、调整大小和一般重新绘制)都会变慢。下面是一些示例代码(改编自 examples/tutorials/1_readonly 教程):

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();
}

这是运行表 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();
}

当我在 OSX 上向上和向下滚动时使用 Instruments 时,它在 QWidgetPrivate::drawWidget 和堆栈 QWidgetPrivate::paintSiblingsRecursive 上花费了大量时间......也就是说,它花费了大量时间重新绘制我的表格。

我是 Qt 的新手,所以我不确定如何解决这个问题。我是不是该:
  • 覆盖paint方法?即也许我可以将我的整个表格保存为一个图像,当滚动发生时,只需重新绘制图像直到移动停止(然后返回直接绘制表格)?
  • 根本不使用 Qt 中的表格?也许我可以只使用文本字段来完成我的目的?例如对于文本中的每个字母,我想要悬停文本、选择、着色字母的背景等。

  • 这两个选项似乎需要大量的工作来弥补因切换到 QTableView 而失去的基础。还有其他建议吗?

    最佳答案

    众所周知,QTableView 在处理大型数据集时速度很慢。我建议你切换到 Qt Graphics View Framework 。它效率更高,并且足够灵活以显示表格。

    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();
    

    关于c++ - QTableView 具有 1000 多个可见单元格的性能下降,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/19691577/

    10-12 17:27