如何向 QFileSystemModel 添加自定义角色

How to add a custom role to QFileSystemModel

我想将自定义角色添加到 QFileSystemModel(可能是派生模型)。我想使用此角色来保存显示在自定义委托中文件名旁边的 CheckBox 的检查状态。如何做到这一点?

我使用示例 Qt Quick Controls - File System Browser Example 删除了部分选择。

步骤如下:

  • roleNames中添加新角色:

    QHash<int,QByteArray> roleNames() const Q_DECL_OVERRIDE
    {
        QHash<int, QByteArray> result = QFileSystemModel::roleNames();
        result.insert(SizeRole, QByteArrayLiteral("size"));
        result.insert(DisplayableFilePermissionsRole, QByteArrayLiteral("displayableFilePermissions"));
        result.insert(LastModifiedRole, QByteArrayLiteral("lastModified"));
        result.insert(Qt::CheckStateRole, QByteArrayLiteral("checkRole"));
        return result;
    }
    
  • 创建一个存储选区信息的容器,本例中我将使用QMap:

    QMap<QPersistentModelIndex, Qt::CheckState> m_checks;
    
  • 覆盖data()方法,returns容器中存储的状态,如果没有返回Qt::UnChecked默认值:

    QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const Q_DECL_OVERRIDE
    {
        if (index.isValid() && role >= SizeRole) {
            ...
        }
        else if (role == Qt::CheckStateRole) {
            QPersistentModelIndex pix(index);
            if(m_checks.contains(pix)){
                return m_checks[pix];
            }
            return Qt::Unchecked;
        }
        return QFileSystemModel::data(index, role);
    }
    
  • 覆盖setData()方法,必要时必须修改并创建数据。

    bool setData(const QModelIndex &index, const QVariant &value, int role=Qt::EditRole){
        if(role == Qt::CheckStateRole && index.isValid()){
    
            Qt::CheckState current = value.value<Qt::CheckState>();
            if(m_checks.contains(index)){
                Qt::CheckState last = m_checks[index];
                if(last == current)
                    return false;
                m_checks[index] = current;
            }
            else{
                m_checks.insert(index, current);
            }
            emit dataChanged(index, index, {role});
            return true;
        }
        return QFileSystemModel::setData(index, value, role);
    }
    
  • 我添加了一个新列,我在其中建立了对 CheckBox 的委托,并使用 onCheckedChanged 插槽设置了使用 setData() 的值方法,传递QModelIndex,数据和角色,在本例中传递10,因为它是Qt::CheckStateRole.

    的值编号
    TreeView {
        id: view
        model: fileSystemModel
        ...
    
        TableViewColumn {
            role: "checkRole"
            delegate: Component {
                CheckBox {
                    id: mycbx
                    checked: styleData.value
                    onCheckedChanged: view.model.setData(styleData.index, checked, 10)
                }
            }
        }
    ...
    

完整的例子可以在下面link.

中找到