代码之家  ›  专栏  ›  技术社区  ›  Karl Voigtland

如何有效地选择符合特定条件的QTableView的行子集?

  •  5
  • Karl Voigtland  · 技术社区  · 15 年前

    QTableView 使用 QSqlTableModel

    在基础数据库(postgresql)表中有一个timestamp列。

    如何选择基础时间戳列为空的选择模型中的所有行?

    指向正确方向的指针会有帮助。

    我遇到的主要问题是表现。我尝试过的每个方法都会导致两个性能问题。

    第一种是对selectionModel()->select(selection)的调用大约需要30秒才能处理5000条选定记录。它似乎在为每一行发出选择改变的信号。即使信号处理程序被禁用,它仍然需要10秒。

    第二个性能问题是,即使在使用选定行更新视图之后,尝试滚动视图的速度也非常慢且滞后。我的猜测是,选择模型由5000个单独的选择组成,而不仅仅是选择范围的最小数目。

    在我正在试验的数据中,选择是连续的;因此它应该能够表示为单个选择范围。如果我只调用tableView->selectAll(),那么这非常快。

    我想知道的是是否有一种规范的、有效的方法来选择一堆匹配的行。或者,我的代码中可能存在导致性能回归的缺陷。是否有方法使用QSortFilterProxyModel count0 为了达到这个目的?我希望视图显示所有行,但要选择匹配的行。

    以下是我尝试的最后一个方法的代码片段:

    void MainWindow::selectNullTimestamp()
    {
    
        QModelIndex start = model->index(0, TIMESTAMP_COLUMN);
    
    
        QModelIndexList indexes = model
                    ->match(start, Qt::DisplayRole,
                QVariant(QString("")),
                -1,
                Qt::MatchFixedString);
    
        QItemSelectionModel* selection_model = ui->tableView->selectionModel();
    
        QItemSelection selection;
    
        foreach(QModelIndex index, indexes) {
    
            QModelIndex left =
                model->index(index.row(), 0);
    
            QModelIndex right =
                model->index(index.row(),
                                     NUM_COLUMNS - 1);
    
            QItemSelection sel(left, right);
    
            selection.merge(sel, QItemSelectionModel::Select);
    
        }
    
        selection_model->select(selection, QItemSelectionModel::Select);
    
    }
    
    4 回复  |  直到 7 年前
        1
  •  2
  •   Patrick    9 年前

    可能已经太晚了,但这总是有帮助的! 我面对这个问题,我认为使用QItemSelection可以有效地解决这个问题

    假设您的表视图称为myTableView,并且您希望选择偶数行[0、2、4、6,…]

    myTableView->clearSelection();
    QItemSelection selection;
    for (int i = 0 ; i < myTableView->rowCount(); i += 1)
    {
        QModelIndex leftIndex  = myTableView->model()->index(i, 0);
        QModelIndex rightIndex = myTableView->model()->index(i, myTableView->columnCount() -1);
    
        QItemSelection rowSelection(leftIndex, rightIndex);
        selection.merge(rowSelection, QItemSelectionModel::Select);
    }
    myTableView->selectionModel()->select(selection, QItemSelectionModel::Select);
    
        2
  •  1
  •   count0    15 年前

    在模型和视图之间使用qsortfilterproxy模型。

        3
  •  1
  •   Greg Giddings    12 年前

    为了避免混淆,TripsListView是与QSqlTableModel结合使用的QTableView。 这是一种查询方法。至于性能,它只做它必须做的事情。

    QModelIndexList indexesAll;
    QItemSelection selection;
    int i = 0;
    QSqlQuery query;
    query.exec(qs);
    salect = true;
    
    while ( query.next() ) {
    if ( salect ) {
        TripsListView->clearSelection ();
        TripsListView->setSelectionMode( QAbstractItemView::MultiSelection );
        TripsListView->selectRow(0);
        indexesAll = TripsListView->selectionModel()->selectedIndexes ();
        salect = false;
    }
    
    for ( i = i; i < TripsModel->rowCount(); i++ ) {
        if ( TripsModel->data(indexesAll[0].sibling(i, 0), Qt::DisplayRole).toInt() == query.value(0).toInt() ) {
        QModelIndex left = TripsModel->index( i, 0 );
    // I like this selection code.
        QModelIndex right = TripsModel->index( i, 12 );
    
        QItemSelection sel(left, right);
    
        selection.merge(sel, QItemSelectionModel::Select);
    
        break;
        }
    } 
    }
    
    if ( salect ) {
    
    }
    else { 
        TripsListView->clearSelection ();
        SearchTripsSelMod->select(selection, QItemSelectionModel::Select);
    }    
    
        4
  •  0
  •   swongu    15 年前

    为了响应代码更新,如果使用 QAbstractItemView::SelectRows QAbstractItemModel::match() .