You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在两个视图展示QFileSystemModel:树视图及选中项的列表/表格视图

嘿,这个需求我之前帮不少开发者处理过,思路其实挺清晰的,咱们一步步拆解来实现:

核心思路

既然你已经在自定义的QFileSystemModel里维护了选中项的QPersistentModelIndex列表,最靠谱的方案是做一个专门的代理模型,用它过滤出选中的项,再把这个代理模型绑定到你的第二个视图(ListView/TableView)上。这种方式能保证两个视图的数据完全同步,而且性能和可维护性都不错。

具体实现步骤

1. 实现自定义过滤代理模型(C++端)

继承QSortFilterProxyModel,重写filterAcceptsRow方法,只让选中的行通过过滤。同时把选中列表做成可绑定的属性,方便QML同步数据。

#include <QSortFilterProxyModel>
#include <QPersistentModelIndex>

class SelectedFilesProxyModel : public QSortFilterProxyModel
{
    Q_OBJECT
    Q_PROPERTY(QList<QPersistentModelIndex> selectedIndexes READ selectedIndexes WRITE setSelectedIndexes NOTIFY selectedIndexesChanged)
public:
    explicit SelectedFilesProxyModel(QObject *parent = nullptr) 
        : QSortFilterProxyModel(parent) {}

    QList<QPersistentModelIndex> selectedIndexes() const { 
        return m_selectedIndexes; 
    }

    void setSelectedIndexes(const QList<QPersistentModelIndex> &indexes) {
        if (m_selectedIndexes != indexes) {
            m_selectedIndexes = indexes;
            invalidateFilter(); // 触发过滤规则刷新
            emit selectedIndexesChanged();
        }
    }

protected:
    bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const override {
        // 获取原模型对应的索引,判断是否在选中列表里
        QModelIndex sourceIndex = sourceModel()->index(source_row, 0, source_parent);
        return m_selectedIndexes.contains(QPersistentModelIndex(sourceIndex));
    }

private:
    QList<QPersistentModelIndex> m_selectedIndexes;
signals:
    void selectedIndexesChanged();
};

记得在main.cpp里把这个模型注册到QML环境:

qmlRegisterType<SelectedFilesProxyModel>("com.your.models", 1, 0, "SelectedFilesProxyModel");

2. QML中绑定模型并展示

在QML里把代理模型和你的自定义QFileSystemModel关联起来,然后用第二个视图绑定代理模型就行。这里以ListView为例:

import QtQuick 2.15
import QtQuick.Controls 2.15
import com.your.models 1.0

Window {
    width: 900
    height: 600
    Row {
        width: parent.width
        height: parent.height

        // 原TreeView(保持你原来的配置)
        TreeView {
            id: fileTree
            width: parent.width / 2
            height: parent.height
            model: customFileModel
            // ... 你的复选框绑定、列配置等原有代码
        }

        // 展示选中项的ListView
        ListView {
            width: parent.width / 2
            height: parent.height
            model: selectedProxy

            delegate: Item {
                width: parent.width
                height: 40
                Text {
                    anchors.centerIn: parent
                    text: model.fileName // 展示文件名,也可以换成filePath等其他属性
                }
                // 如果要支持在ListView里取消选中,加个复选框绑定原模型的选中Role
                CheckBox {
                    anchors.right: parent.right
                    anchors.verticalCenter: parent.verticalCenter
                    checked: model.customSelectedRole // 替换成你自定义的选中Role名称
                }
            }
        }
    }

    // 你的自定义QFileSystemModel实例
    YourCustomFileSystemModel {
        id: customFileModel
        // ... 你的模型初始化配置
    }

    // 代理模型,关联原模型和选中列表
    SelectedFilesProxyModel {
        id: selectedProxy
        sourceModel: customFileModel
        selectedIndexes: customFileModel.selectedIndexes // 绑定原模型的选中列表属性
    }
}

3. 保证选中状态的同步更新

在你的自定义QFileSystemModel里,修改选中状态时要及时更新selectedIndexes列表并发出信号,这样代理模型才能立刻刷新过滤结果。比如:

void YourCustomFileSystemModel::toggleItemSelection(const QModelIndex &index) {
    bool currentState = data(index, CustomSelectedRole).toBool();
    // 更新选中状态
    setData(index, !currentState, CustomSelectedRole);

    QPersistentModelIndex persistentIdx(index);
    if (!currentState) {
        m_selectedIndexes.append(persistentIdx);
    } else {
        m_selectedIndexes.removeOne(persistentIdx);
    }
    // 发出信号通知QML绑定更新
    emit selectedIndexesChanged();
}
额外优化提示
  • 如果选中项数量很大或者频繁变化,可以在代理模型里做个哈希缓存,把QPersistentModelIndex存到QSet里,这样判断是否选中的效率会更高。
  • 如果用TableView展示,只需要把ListView换成TableView,配置对应的TableViewColumn即可,代理模型完全通用。
  • 要是想支持选中项的排序,代理模型本身就支持排序,直接调用sort()方法或者在QML里设置sortIndicator就行。

内容的提问来源于stack exchange,提问作者maxwell

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 03:51:41