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);
}