我正在Unix中开发Qt C ++应用程序,而且我一直试图做一些与此图像相似的事情:
如您所见,有一个文件和文件夹列表,用户可以选择多个文件和文件夹(如果选择了一个文件夹,则所有子项也会被选中)。如果显示文件夹/文件图标,我真的不在乎。
我能够创建一个QDir
列表,它存储了给定根路径的所有文件和文件夹路径。问题是我不知道用哪些小部件来设计选择面板。
顺便说一句,to_uncompress = JSON.parse(to_uncompress)
的lis是一个向量,但它可以很容易地修改为其他任何东西。
谢谢!
答案 0 :(得分:2)
您可以尝试为QFileSystemModel创建代理模型,使用Qt :: ItemIsUserCheckable覆盖flags(),覆盖setData()并将模型应用于QTreeView。完整的示例可以在https://github.com/em2er/filesysmodel找到。这段代码只是一个概念,我没有彻底测试过,但你可以从中得到一些想法。在截图中看起来很像: 。
此外,您可以将其与Merged Proxy Model结合使用,以在一个视图中显示多个起始路径。
答案 1 :(得分:1)
您可能需要考虑QTreeWidget,或者它是一个更高级的版本 - QTreeView和适当的数据模型。
答案 2 :(得分:0)
正如一些用户建议的那样,我最终使用了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_;
};
创建模型时,必须设置一个标志,表示它应该有一个可检查框。这就是为什么我们将使用flags
函数:
Qt::ItemFlags FileSelector::flags(const QModelIndex& index) const
{
return QFileSystemModel::flags(index) | Qt::ItemIsUserCheckable;
}
当在复选框中单击时,将调用方法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);
}
当发出dataChanged
信号或您打开树的新路径时,将调用data
函数。在这里,您必须确保仅显示第一列(文件名旁边)的复选框,并检索复选框的状态,以将其标记为选中/取消选中。
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);
}
我唯一无法完成的就是获得所有孩子,因为必须打开文件夹才能找回孩子。因此,在您打开它之前,关闭的文件夹将不会有任何子项。
希望这可以帮助那些遇到与我一样的问题的人!