[英]QStandardItemModel - how to ignore data changed event by row moved but NOT by cell changes from user
[英]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.