簡體   English   中英

按項目數據查找/刪除QStandardItemModel中的行

[英]Finding / removing a row from a QStandardItemModel by item data

我有一個帶有單個列的QStandardItemModel (表示一個列表)。 列表中的每個項目都有一個唯一的整數ID,存儲為QStandardItem的數據(通過QStandardItem::setData ,我猜測它默認為Qt::UserRole+1 )。

給定其中一個ID,我想找到並刪除模型中的相應行。 現在我這樣做:

void NetworkManager::removeSessionFromModel (QStandardItemModel *model, int sessionId) {

    foreach (const QStandardItem *item, model->findItems("*", Qt::MatchWildcard)) {
        if (item->data() == sessionId) {
            model->removeRow(item->index().row());
            break;
        }
    }

}

它工作正常,但該功能的每一行都讓我感到畏縮。 有沒有更清潔的方法來做這些?

如何直接遍歷QStandardItemModel 像這樣的東西:

void NetworkManager::removeSessionFromModel (QStandardItemModel *model, int sessionId) 
{
    for (int i = 0; i < model->rowCount(); ++i)
    {
        if (model->item(i)->data() == sessionId)
        {
            model->removeRow(i);
            break;
        }
    } 
}

不確定QStandardItemModel如何隨機訪問,可能您的方法更有效。

編輯:

實際上,有一個函數可以做你想要的: QAbstractItemModel :: match

它返回一個QModelIndexList ,其中包含在給定角色中具有匹配數據的所有條目。

void NetworkManager::removeSessionFromModel (QStandardItemModel *model, int sessionId)
{
    QModelIndexList list = model->match(model->index(0, 0), Qt::UserRole + 1, sessionId);

    if (!list.empty())
        model->removeRow(list .first().row());
}

將數據設置為特定角色可以按如下方式完成:

model->setData(model->index(row, col), QVariant(13), Qt::UserRole + 1);

您需要從商品ID中獲取行索引。

更有效的方法是使用QMap,其中行索引為值,項ID為鍵。

在這種情況下,您還需要在每次添加/刪除行時保持映射值。

如果您的列表中沒有3百萬個項目,請保持簡單並使用您的代碼。 通過優化此代碼,您可能還會增加復雜性並降低可維護性,並且您得到的是0.05毫秒而不是0,06毫秒。

在GUI代碼中,我經常使用這樣的代碼:它很簡單,每個人都可以立即獲得它並完成工作。 它也足夠快。

您使用的是findItems錯誤,它只能通過傳遞您要搜索的值返回您想要的項目。 如果你現在正在調用它,那么你至少要循環兩次你的項目,因為findItems必須遍歷所有項目以找到與你的模式匹配的項目,在你的情況下所有項目都匹配,然后你迭代再次返回項目以查找sessionId

void NetworkManager::removeSessionFromModel (QStandardItemModel *model, int sessionId) {

    auto items = model->findItems(QString::number(sessionId));
    if (!items.empty()) {
        auto row = items.first()->index().row();
        model->removeRow(row);
    }
}

或者,您可以使用match方法,因為findItems在內部使用它,因此您可以避免分配StandardItem來獲取其索引。 同樣match在匹配模式的項目數之后立即返回,在這種情況下會找到sessionId的值,因此它並不總是迭代所有項目; 那更有效率。 顯然,如果在迭代所有項后找不到該值,則返回一個空列表。

auto start = model->index(0, 0);
auto indexes = model->match(start, Qt::UserRole + 1, QString::number(sessionId), 1, Qt::MatchExactly);
if (!indexes.empty()) {
    auto row = indexes.first().row();
    model->removeRow(row);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM