QFileSystemModel - iterating through current index children
-
Open source, or in-house use only?
-
In house only...
-
Hi Andre,
when I set the model of my QTreeView to the CheckableProxyModel, how can I determine if the QModelIndex I just double-clicked on is a Directory or not? My previous implementation prior to setting the model to CheckableProxyModel is as follow:
@
void TreeEditor::openFile(const QModelIndex& index)
{
if(index.isValid() && index.model())
{
QFileSystemModel* model = (QFileSystemModel*)index.model();if(!model->isDir(index)) { QString filePath = model->filePath(index); open(filePath); } }
}
@Do I have add a function to the CheckableProxyModel class to find out if the index I clicked on is a directory?
-
Keep using isDir, but map the item index before querying it. At least, that is how I would do it. I guess a branch node in the tree is not in all cases the same as a node representing a directory.
I would keep this functionality out of CheckableProxyModel. Just let that class do what it does. If you add this, you will bind it to be only usable in combination with a QFileSystemModel. That would be a shame.
@
void TreeEditor::openFile(const QModelIndex& index)
{
if(index.isValid() && index.model())
{
QFileSystemModel* model = m_fileSystemModel; // just keep a pointer around
CheckableProxyModel* proxy = m_checkableProxyModel; //same hereif(!model->isDir(proxy->mapToSource(index))) { QString filePath = index.data(QFileSystemModel::FilePathRole).toString(); open(filePath); } }
}
@ -
I understand that this is pertaining only to QFileSystemModel so I don´t want to add it to the CheckableProxyModel class, but how can I dynamically populate the QTreeView with only the directory I am interested in. My previous code to set the current directory as the root of the QTreeView was as follow:
@
QDir::setCurrent(strCurrTestDir);
QModelIndex idx = fsModel->index(strCurrTestDir);
fileTree->setRootIndex(idx);
@Resolved:
@
QDir::setCurrent(strCurrTestDir);
QModelIndex idx = fsModel->index(strCurrTestDir);
fileTree->setRootIndex(m_checkProxy->mapFromSource(idx));
@ -
Hi Andre,
your implementation of the Qtree´s checkstate propogation works great!!! Thank you!
One specific question related to my project is that since I am interested in getting the unchecked files for processing. What would be the quickest method for me to get all of the unchecked filenames under the unchecked directories? Should I be using QDirectoryIterator?
-
Yes. Get the unchecked directories from the proxy model, and iterate over those directories using a QDirectoryIterator.
I am glad my proxy model works for you!
-
Hi Andre,
I'm trying to understand your checkableproxymodel code. It's very well written & thanks for the same.
In mainwindow.cpp, selectedItemsChanged() function, I see the path of checked & unchecked files/directories. Also I want the size of checked files. How to get the size of the file I check ?Kindly help me. Thank you.
-
[quote author="rawfool" date="1399037548"]Hi Andre,
I'm trying to understand your checkableproxymodel code. It's very well written & thanks for the same.
In mainwindow.cpp, selectedItemsChanged() function, I see the path of checked & unchecked files/directories. Also I want the size of checked files. How to get the size of the file I check ?Kindly help me. Thank you.[/quote]
That's really a bit besides the point of the model, but ok. The model only provides a proxy on top of any other tree-type model you put behind it. If that model is a model describing the file system, then you can use it to access information on files. If it is something else, then, well...
In the example, the base model is a QFileSystemModel. QFileSystemModel provides roles for the path, the icon and the permissions, but not for the file size (weird omission, I think). The size is available from column 1 in the model though, but as a string, not as a value in bytes. To get that data, you have to use something like this:
@
foreach (const QModelIndex index, selectedFiles) {
list += "<li>" + index.data(QFileSystemModel::FilePathRole).toString() + "</li>";
QModelIndex sizeIndex = index.model().index(index.row(), 1, index.parent());
qDebug() << "size of" << index.data(QFileSystemModel::FilePathRole)
<< "is" << index.data();
}
@
(note: completely untested code) -
Hi Andre, thanks for replying.
I'm getting an error after adding the above code and it says -@error: request for member 'index' in 'index.QModelIndex::model()', which is of non-class type 'const QAbstractItemModel*'@
for the line -
@QModelIndex sizeIndex = index.model().index(index.row(), 1, index.parent());@I'm novice to model view concepts, so unable to solve this. Can you help me make it right. Thank you.
-
That's why I said: untested code. It is meant as a pointer (pun intended), not as a ready-made solution.
So, use -> instead of .
-
Hi Andre,
In selectedItemsChanged() slot, instead of iterating through all the checked/unchecked items, is there a way to get only checked/unchecked/modified item?
Thank you.
-
So, you want to know what changed exactly? No, there is currently no API for that. I guess it could be added by modifying the setCheckState method.
-
Thank you for responding.
Yeah, I want to know what has changed in the tree.
Actually I'm adding the checked items to a QTableView. On every check/uncheck of file or directory, I'm adding the same to QAbstractTableModel based class.For every update, I'm clearing the data and adding again in foreach loop.
So, the problem is if there are 100000 files in a directory, and if 99998 files are checked and for another check, I will have to delete all the data, again iterate through all the 99998+1 items, which is a burden. -
Wouldn't it be possible to just use the same model for your table? What data is in your table?
-
Actually I'm just starting to learn Model View architecture, and I'm not proficient in those concepts, so I'm struggling to find my feet.
Things to be shown in my table which contains three columns(Directory/File, Path, Size) -
- On every check of file, a row has to be added with the corresponding attributes.
- On uncheck of the file/folder, the row with that record has to be deleted.
- On check of dir, only dir path needs to be shown. No need to show the files under it.
It's same as the output data of selectedItemsChanged() slot but without iterations of adding/deletion of items.
Exactly like in the picture attached below -
!http://enterpriseblog.net/wp-content/uploads/2008/07/idrive.gif(Table attached to tree)!Can you help me how to do this please?
-
What you are for, is a way to flatten the tree-shaped model into a flat list, selecting only the checked items (so, the items appearing in the items you can retreive from the selectedItems method). Interesting challange.
I think I'd make a QAbstractTableModel derived proxy model, on which you can set a source model and a list of QModelIndex objects to show from that source model. The CheckableProxyModel can serve as the source model, and the lists of selected files and directories can be combined to provide the input. A proxy based on QSFPM won't work, as you also want to change the structure of the data you represent.
The basic problem you have now: how to efficiently update, will still have to be solved, but it can essentially be solved by first creating a diff off the current list of indices versus the new list. Standard algoritms can be used to do that, and the fact that QModelIndex has operator<() helps a lot there. That results in a list of indices to remove, and a list of indices to add to the model. That can be done in a relatively simple way. Storing QModelIndex instances is not recommended, you'd have to use QPersistentModelIndex. No idea how that will perform if you have a lot of them.
The number of rows of the proxy model would be the number of items set on it, but the number of columns would be the number of columns from the source model. The data and flags methods would simply use the stored model index to retrieve the corresponding data from the source model.
All in all: a doable but not entirely trivial task. I can imagine that it sounds tricky to do if you are just learing the model/view framework. It is simpler than the CheckableProxyModel itself though :-)
-
Ok Andre, thank you for your guidance. Will try the way you mentioned. Thank you.
-
I actually find it an interesting question, and may try my hand on it too. That's how/why I made CheckableProxyModel itself too: an interesting question :)
-
Cool. :)