QT从文件和文件夹列表中选择多项 我在UNIX中开发了Qt C++应用程序,我一直在尝试做类似于这个图像显示的东西:

QT从文件和文件夹列表中选择多项 我在UNIX中开发了Qt C++应用程序,我一直在尝试做类似于这个图像显示的东西:,c++,qt,qdir,C++,Qt,Qdir,如您所见,有一个文件和文件夹列表,用户可以选择多个文件和文件夹(如果选择了一个文件夹,则也会选择所有孩子)。我真的不在乎是否显示文件夹/文件图标 我能够创建一个QDir列表,其中存储给定根路径的所有文件和文件夹路径。问题是我真的不知道使用哪些小部件来设计选择面板 顺便说一下,QDir的lis是一个向量,但它可以很容易地修改为其他任何内容 谢谢 > P>您可能需要考虑QTreWIDGET,或者它是一个更高级的版本——QTreeView和一个适当的数据模型。 < P>您可以尝试用Qt::ITEMIS

如您所见,有一个文件和文件夹列表,用户可以选择多个文件和文件夹(如果选择了一个文件夹,则也会选择所有孩子)。我真的不在乎是否显示文件夹/文件图标

我能够创建一个
QDir
列表,其中存储给定根路径的所有文件和文件夹路径。问题是我真的不知道使用哪些小部件来设计选择面板

顺便说一下,
QDir
的lis是一个向量,但它可以很容易地修改为其他任何内容


谢谢

> P>您可能需要考虑QTreWIDGET,或者它是一个更高级的版本——QTreeView和一个适当的数据模型。

< P>您可以尝试用Qt::ITEMISUSER CHECKEABLE,重写StEATDATA()覆盖代理模型,并将模型应用到QTrIEVIEW中。完整的示例可在上找到。这段代码只是一个概念,我还没有对它进行彻底的测试,但您可以从中获得一些想法。在屏幕截图上看起来很像: .


您还可以将其与组合起来,在一个视图中显示多个起始路径。

正如一些用户所建议的,我最终使用了
QFileSystemModel
。我将给出我如何实现它的完整描述,以防其他人提出这个问题并需要明确的响应

首先,一个
QFileSystemModel
是一个没有复选框的文件树,要添加它们,必须覆盖一个扩展
QFileSystemModel
的新类和至少3个方法

class FileSelector : public QFileSystemModel
{
public:
    FileSelector(const char *rootPath, QObject *parent = nullptr);
    ~FileSelector();

    bool setData(const QModelIndex& index, const QVariant& value, int role);
    Qt::ItemFlags flags(const QModelIndex& index) const;
    QVariant data(const QModelIndex& index, int role) const;

private:
    QObject *parent_;
    /* checklist_ stores all the elements which have been marked as checked */
    QSet<QPersistentModelIndex> checklist_;
};
在复选框中单击时,将调用方法
setData
,其中包含所单击元素的索引(不是复选框本身,而是:

bool FileSelector::setData(const QModelIndex& index, const QVariant& value, int role)
{
    if (role == Qt::CheckStateRole && index.column() == 0) {
        QModelIndexList list;
        getAllChildren(index, list); // this function gets all children 
        // given the index and saves them into list (also saves index in the head)
        if(value == Qt::Checked)
        {
            for(int i = 0; i < list.size(); i++)
            {
               checklist_.insert(list[i]);
               // signals that a change has been made
               emit dataChanged(list[i], list[i]);
            }
        }
        else if(value == Qt::Unchecked)
        {
            for(int i = 0; i < list.size(); i++)
            {
                checklist_.remove(list[i]);
                emit dataChanged(list[i], list[i]);
            }
        }
        return true;
    }
    return QFileSystemModel::setData(index, value, role);
}
我唯一无法完成的事情是获取所有的child,因为必须打开文件夹才能检索child。因此,在打开关闭的文件夹之前,它不会有任何子文件夹


希望这能帮助那些和我有同样问题的人!

你看到这个了吗:或者这可能会有帮助D@em2er我没有,但我明天会。你认为它会修复它吗?举个例子,在OP图像中,如果我选择了
kankan
文件夹(已折叠)选择
MyPicture
文件夹(已打开)时,将不会获取任何child将得到8个child。不确定,但可以。QFileSysModel经过优化,不会因为磁盘操作速度慢而分派不可见和嵌套的元素。解决这个问题的愚蠢方法是在检查时展开树视图项并执行这些操作,但我想这不是一个选项。嗯,我明白了……在我的情况下,选择父文件夹就足够了打开,所以这只是一个可视的东西,因为如果文件夹未展开,我无法检查子文件,并且当我展开它时,子文件显示为未选中。但明天将尝试!关于合并代理模型的最后一个链接已失效(在中提供).基本上,它提到了源文件,特别是@antok,刚刚更新了您的链接,谢谢!
bool FileSelector::setData(const QModelIndex& index, const QVariant& value, int role)
{
    if (role == Qt::CheckStateRole && index.column() == 0) {
        QModelIndexList list;
        getAllChildren(index, list); // this function gets all children 
        // given the index and saves them into list (also saves index in the head)
        if(value == Qt::Checked)
        {
            for(int i = 0; i < list.size(); i++)
            {
               checklist_.insert(list[i]);
               // signals that a change has been made
               emit dataChanged(list[i], list[i]);
            }
        }
        else if(value == Qt::Unchecked)
        {
            for(int i = 0; i < list.size(); i++)
            {
                checklist_.remove(list[i]);
                emit dataChanged(list[i], list[i]);
            }
        }
        return true;
    }
    return QFileSystemModel::setData(index, value, role);
}
QVariant FileSelector::data(const QModelIndex& index, int role) const
{
    if (role == Qt::CheckStateRole && index.column() == 0) {
        if(checklist_.contains(index)) return Qt::Checked;
        else return Qt::Unchecked;
    }
    return QFileSystemModel::data(index, role);
}