1

I'm trying to make an pyqt app, which examines directory structure and the files in it. What I want to do is to add some extra info to the items in the qfilesystemmodel, for example, tagging files as 'checked' or 'unchecked'. I have found that each item (file or folder) in the model has four columns, name, size, timestamp and type. Is it possible to make the item have fifth column, which will contain custom information (tags) ? Or, Is there any way to annotate extra info on the items in the model ? If not, I think I have to have another model, such as qstanarditemmodel, to keep the tags. But I don't want it to be in a saperated model. Thanks!

2 Answers2

0

In short, no, not easily. The Qt developers stopped working on QFileSystemModel for complexity reasons. Basically, the backend file system engine is way too complex and fragile, and QFileSystemModel relies entirely upon it.

You could reimplement QFileSystemModel, but it would require a lot of painful work and accessing the private headers.

jonspaceharper
  • 4,207
  • 2
  • 22
  • 42
0

The QFileSystemModel class delegates to a live file-system. So it doesn't really contain any items that you can add information to. The items are actually the files and directories inside the file-system.

Given this, it follows that a second data structure will be required to hold the additional information. Otherwise, you'd need to somehow store the information in the files and directories themselves. This might be possible for certain file-types (e.g. images). But it is obviously unfeasible to do this for arbitrary file-types.

It should be possible to sub-class QFileSystemModel and reimplement the usual methods so that extra columns can be added. As a bare minimum, you would need to reimplement columnCount() and data() - but obviously the exact details of how you go about this will depend on the data structure you choose to hold the additional information. Very roughly, it might look something like this:

class FileSystemModel(QFileSystemModel):
    def __init__(self, parent=None):
        super(FileSystemModel, self).__init__(parent)
        self._data = DataStructure()

    def columnCount(self, parent):
        return super(FileSystemModel, self).columnCount(parent) + 1

    def data(self, index, role):
        if index.isValid() and index.column() == self.columnCount() - 1:
            if role == QtCore.Qt.DisplayRole:
                # return the relevant additional data
            elif role == QtCore.Qt.CheckStateRole:
                # etc, etc
        else:        
            return super(FileSystemModel, self).data(index,role)
ekhumoro
  • 115,249
  • 20
  • 229
  • 336
  • Without access to the underlying data, any inheritance of the model is fragile and readily breaks. – jonspaceharper Jul 14 '16 at 20:19
  • Remember that `QModelIndex` is a throwaway object. You can store the data with absolute pathnames as keys in a hash, but that's fragile, as well. It won't handle renames, deletes, and moves. – jonspaceharper Jul 14 '16 at 20:21
  • @JonHarper. If you look carefully at my rough example, you'll see that it doesn't touch the underlying data at all. Effectively, it just delegates to `QFileSystemModel`. Obviously it is unwise to store instances of `QModelIndex` - use [QPersistentModelIndex](http://doc.qt.io/qt-4.8/qpersistentmodelindex.html) for that if you need to. I don't see any reason why a secondary data structure can't be linked to a file-system model to add an extra column or two. It's not simple, but it's certainly possible to do it in a robust way if it's carefully thought through. – ekhumoro Jul 14 '16 at 20:55
  • Large numbers of `QPersistentModelIndex`es are slow and are not suitable for mapping. `QModelIndex` (and its persistent counterpart) have pointers to the model's underlying data, but that data is not guaranteed to remain valid. Without modifying the original code, it's simply not feasible. – jonspaceharper Jul 14 '16 at 22:15
  • @JonHarper. I didn't suggest using them in a mapping - I was merely pointing out that there was a better alternative to `QModelIndex`. But anyway, I think the issues with `QFileSystemModel` are a bit of a red herring here. What this problem boils down to is simply this: how can I keep some custom data in sync with a file-system? This is not necessarily easy, but it is certainly doable. And if you don't want to work up your own solution, I'm sure there are some third-party python packages that will do most of the heavy-lifting for you. – ekhumoro Jul 14 '16 at 23:47
  • Hi guys, at least I've learned that doing some trick with _internal_ data of QFileSystemModel should be tough and I will not be doing it. Having 2nd data model for custom data looks much easier and safer. Thanks a lot! – Pyungsu Han Jul 15 '16 at 04:31