QSortFilterProxyModel和QTreeView排序功能

一字千金發表於2024-08-12

1、需求,建立一個樹有多層結構,同一層按照插入順序逆序排列;

ui.treeView->setHeaderHidden(true);     //tree widget頭標題是否顯示,此處隱藏標題
    //ui.treeWidget->header()->setHorizontalScrollMode(QAbstractItemView::ScrollPerPixel);
    ui.treeView->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
    //ui.treeView->header()->setSectionResizeMode(0, QHeaderView::ResizeToContents);
    ui.treeView->header()->setCascadingSectionResizes(false);
    ui.treeView->header()->setStretchLastSection(true);
    m_modelTree = new QStandardItemModel(ui.treeView);
    m_TreeDelegate = new TreeTaskDelegate(ui.treeView);
    connect(m_TreeDelegate, &TreeTaskDelegate::signalBtClicked, this, &TreeTaskList::SlotTreeBtClicked);
    connect(m_TreeDelegate, &TreeTaskDelegate::signalEditFinish, this, &TreeTaskList::SlotEditFinish);
    ui.treeView->setItemDelegate(m_TreeDelegate);
    m_proxyModel = new QSortFilterProxyModel(ui.treeView);
    m_proxyModel->setSourceModel(m_modelTree);
    ui.treeView->setModel(m_proxyModel);
    m_modelTree->setColumnCount(1);
//    ui.treeView->setSortingEnabled(true);
    //ui.treeView->sortByColumn(0,Qt::AscendingOrder);
    m_proxyModel->setSortRole(Qt::UserRole+1);
    m_proxyModel->sort(0, Qt::DescendingOrder);
    ui.treeView->setIconSize(QSize(24, 24));
    ui.treeView->setColumnWidth(0, 300);

上面設定了一個排序按照角色Qt::UserRole+1去排序,排序方式為逆序排序;插入排序之後可以實現自動排序的功能;建立item的時候把建立時間設定到角色Qt::UserRole+1中去,然後QSortFilterProxyModel就會自動按照這個角色的值進行排序

QStandardItem *topItem = new QStandardItem();
        topItem->setCheckable(true);
        QString path = info.value("path").toString();
        topItem->setData( info.value("createtime").toString(),Qt::UserRole+1);
        info.insert("treeItem", QVariant::fromValue<QStandardItem *>(topItem));
        topItem->setData(info,Qt::UserRole);

如果批次匯入,建立時間相同時,沒有勾選時排好序,但是點選勾選的時候會出現重新排序,勾選和未勾選的分開排序,勾選的項跑到最下面去了,這不是我想要的排序方式,於是又給時間後面加上了一個rowcount值,在時間相同的情況,rouwcount肯定不一樣,所以排序就不會變動

QStandardItem* videoFileItem = new QStandardItem();
    videoFileItem->setCheckable(true);
    //videoFileItem->setText(0, caseInfo.value("createtime").toString());
    QString path = caseInfo.value("path").toString();
    videoTaskInfo.insert("treeItem", QVariant::fromValue<QStandardItem*>(videoFileItem));
    for (auto it = videoTaskInfo.begin(); it != videoTaskInfo.end(); it++)
    {
        caseInfo.insert(it.key(), it.value());
    }
    videoFileItem->setData( caseInfo,Qt::UserRole);
    videoFileItem->setData(caseInfo.value("createtime").toString()+"_"+QString::number(parant->rowCount()), Qt::UserRole+1);//時間相同時,勾選順序會變動
    videoFileItem->setSizeHint( QSize(300, 40));QSortFilterProxyModel 

方法2

重寫QSortFilterProxyModel的lessthan函式,可以實現多個條件或者計算複雜的排序;

bool QTreeTaskFilterProxyModel::lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const
{
    QString left = source_left.data(Qt::UserRole+1).toString();
    QString right = source_right.data(Qt::UserRole).toString();
    return left <= right;
}

相關文章