I have been trying to use proxy models with a QFileSystemModel for a while and I have not been very successful.
The idea is to use a QFileSystemModel for my entire application and several layers of proxies on top of it to display the data different ways in different views. One of these views is a selection view that allows me to select folders and files. The selection of any folder would automatically select all its subfolders and files.
I have been successful designing that selection mechanism by directly subclassing the QFileSystemModel class, but I was not able to implement it in a proxy that would be used in series with other proxies on the QFileSystemModel.

Here is the Selection_Proxy code: (might not be necessary to understand the overall issue)
Qt Code:
  1. class SelectItemProxyModel : public IdentityFileSystemProxyModel
  2. {
  3. Q_OBJECT
  4. protected:
  5.  
  6. QSet<QPersistentModelIndex> m_checkTable;
  7. QVariant m_noData;
  8. QVariant m_checkValueToUpdate;
  9.  
  10. QModelIndex m_loadAllDataUnderIndex;
  11. bool m_dataFetchingInProgress;
  12. std::vector<QPersistentModelIndex> m_indexesToBeFetched;
  13. void loadAllDataUnder(const QModelIndex &index);
  14. void loadAllDataUnder_itteration(const QString &currentPath);
  15.  
  16. public:
  17. SelectItemProxyModel(QObject *parent = 0);
  18.  
  19. //re-arranged relays.
  20. QVariant data(const QModelIndex &index, int role) const;
  21. virtual Qt::ItemFlags flags(const QModelIndex &index) const;
  22. virtual bool setData(const QModelIndex &index, const QVariant &value, int role);
  23.  
  24. signals:
  25. void allDataFetchingStart(const QModelIndex &index);
  26. void allDataFetchingStop(const QModelIndex &index);
  27.  
  28. public slots:
  29. void dataReady(const QString &currentPath);
  30. };
To copy to clipboard, switch view to plain text mode 
Qt Code:
  1. #include "SelectItemProxyModel.h"
  2.  
  3. SelectItemProxyModel::SelectItemProxyModel(QObject *parent) : IdentityFileSystemProxyModel(parent),
  4. m_dataFetchingInProgress(false),
  5. m_loadAllDataUnderIndex(QModelIndex())
  6. {
  7. QObject::connect(this,SIGNAL(directoryLoaded(QString)),this,SLOT(dataReady(QString)));
  8. }
  9.  
  10. QVariant SelectItemProxyModel::data(const QModelIndex &index, int role) const
  11. {
  12. //Returns data from the source model.
  13. if (role == Qt::CheckStateRole) return m_checkTable.contains(index)? Qt::Checked : Qt::Unchecked;
  14. //Removes all decoration are removed from the source model.
  15. if (role == Qt::DecorationRole) return m_noData;
  16. //Returns data from the source model.
  17. return m_model->data(mapToSource(index), role);
  18. }
  19.  
  20. Qt::ItemFlags SelectItemProxyModel::flags(const QModelIndex &index) const
  21. {
  22. if (m_dataFetchingInProgress == true)
  23. {
  24. // Prevents the data to be modified by the user when it is being updated by loadAllDataUnder()
  25. return Qt::NoItemFlags;
  26. }
  27. else
  28. {
  29. //Sets all elements as user checkable.
  30. return m_model->flags(mapToSource(index)) | Qt::ItemIsUserCheckable;
  31. }
  32. }
  33.  
  34. bool SelectItemProxyModel::setData(const QModelIndex &index, const QVariant &value, int role)
  35. {
  36. //Sets check state (checked or unchecked) on the specified proxy's item and all items under.
  37. if (role == Qt::CheckStateRole)
  38. {
  39. //Sets check state (checked or unchecked) of the specified proxy's item.
  40. if(value == Qt::Checked) m_checkTable.insert(index); else m_checkTable.remove(index);
  41. emit dataChanged(index, index);
  42. //Sets check state (checked or unchecked) of all the items under.
  43. loadAllDataUnder(index);
  44. return true;
  45. }
  46. // regular QFileSystemModel case.
  47. return m_model->setData(mapToSource(index), value, role);
  48. }
  49.  
  50. void SelectItemProxyModel::loadAllDataUnder(const QModelIndex &index)
  51. {
  52. m_loadAllDataUnderIndex = index;
  53. //If the specifed index does not have children if a "data loading process" is already running, do not
  54. //start a new one.
  55. if ((hasChildren(index))||(m_dataFetchingInProgress == false))
  56. {
  57. m_checkValueToUpdate = data(index, Qt::CheckStateRole);
  58. m_dataFetchingInProgress = true;
  59. emit allDataFetchingStart(index);
  60. m_indexesToBeFetched.push_back(QPersistentModelIndex(index));
  61. if (canFetchMore(index))
  62. {
  63. fetchMore(index);
  64. }
  65. else
  66. {
  67. // If the data of the current index has alreday been loaded, send a directoryLoaded signal so the item can
  68. // still be processed in loadAllDataUnder_itteration().
  69. emit directoryLoaded(filePath(m_loadAllDataUnderIndex));
  70. }
  71. }
  72. }
  73.  
  74. // Processes the data of the last elmt of m_indexesToBeFetched and feeds m_indexesToBeFetched with the next items to be fetched until
  75. // m_indexesToBeFetched is empty.
  76. void SelectItemProxyModel::loadAllDataUnder_itteration(const QString &currentPath)
  77. {
  78. //Check if the loaded data is relevant for loadAllDataUnder_itteration()
  79. if(m_dataFetchingInProgress == false)return;
  80. QModelIndex currentIndex = m_indexesToBeFetched[m_indexesToBeFetched.size()-1];
  81. if(filePath(currentIndex) != currentPath) return;
  82.  
  83. //Remove currentIndex from the m_indexesToBeFetched queue.
  84. m_indexesToBeFetched.pop_back();
  85. int elmtCount = rowCount(currentIndex);
  86. QModelIndex indexFirst = index(0,0,currentIndex);
  87. QModelIndex indexLast = index(elmtCount-1,0,currentIndex);
  88. //Examine the children of the current index.
  89. for (int i(0); i < elmtCount; i++)
  90. {
  91. QModelIndex currentChildIndex = index(i,0,currentIndex);
  92. //Check or uncheck elmts depending on m_checkValueToUpdate value. (value of the top parent set by the user)
  93. if (m_checkValueToUpdate == Qt::Checked) m_checkTable.insert(currentChildIndex); else m_checkTable.remove(currentChildIndex);
  94. //Queue the elmts that have chidren (directories) in m_indexesToBeFetched for next rounds.
  95. if (hasChildren(currentChildIndex))m_indexesToBeFetched.push_back(currentChildIndex);
  96. }
  97. emit dataChanged(indexFirst, indexLast);
  98.  
  99. if (m_indexesToBeFetched.empty())
  100. {
  101. //All the nodes and branches branches have been explored. All the data has been loaded into the view.
  102. m_dataFetchingInProgress = false;
  103. emit allDataFetchingStop(m_loadAllDataUnderIndex);
  104. }
  105. else
  106. {
  107. // Fetch the data of the last element in m_indexesToBeFetched.
  108. currentIndex = m_indexesToBeFetched[m_indexesToBeFetched.size()-1];
  109. if(canFetchMore(currentIndex))
  110. {
  111. fetchMore(currentIndex);
  112. }
  113. else
  114. {
  115. // If the data of the current index has alreday been loaded, send a directoryLoaded signal so the next item in the process
  116. // can be processed else fetch data of the current index.
  117. emit directoryLoaded(filePath(currentIndex));
  118. }
  119. }
  120. }
  121.  
  122. //Slot called when the model has finished loading data under an index.
  123. void SelectItemProxyModel::dataReady(const QString &currentPath)
  124. {
  125. loadAllDataUnder_itteration(currentPath);
  126. }
To copy to clipboard, switch view to plain text mode 
If I use that proxy alone between the QFileSystemModel and my view (such as Model->Selection_Proxy->View), it works.
If I use it with other proxies (like these Model->Proxy1->Proxy2->Selection_Proxy->View) then the Selection_Proxy acts weird. It doesn't select some of the subfolders and some of the files. it always misses the same ones.
One important thing is that all my Proxies are subclassed from the IdentityFileSystemProxyModel Class, which is subclassed itself from the QIdentityProxyModel class.

Here is the IdentityFileSystemProxyModel code:
Qt Code:
  1. class IdentityFileSystemProxyModel : public QIdentityProxyModel
  2. {
  3. Q_OBJECT
  4.  
  5. protected:
  6. QAbstractItemModel * m_model;
  7.  
  8. public:
  9. IdentityFileSystemProxyModel(QObject *parent = 0);
  10. void setSourceModel(QAbstractItemModel * sourceModel);
  11. virtual int columnCount(const QModelIndex & parent) const;
  12. virtual QString filePath(const QModelIndex & index) const;
  13.  
  14. signals:
  15. void directoryLoaded(const QString &path);
  16.  
  17. public slots:
  18. void directoryLoadedSlot(const QString &path);
  19. };
To copy to clipboard, switch view to plain text mode 
Qt Code:
  1. #include "IdentityFileSystemProxyModel.h"
  2.  
  3. IdentityFileSystemProxyModel::IdentityFileSystemProxyModel(QObject *parent) : QIdentityProxyModel(parent)
  4. {
  5. }
  6.  
  7. void IdentityFileSystemProxyModel::setSourceModel(QAbstractItemModel * sourceModel)
  8. {
  9. m_model = sourceModel;
  10. QIdentityProxyModel::setSourceModel(m_model);
  11. QObject::connect(m_model,SIGNAL(directoryLoaded(QString)),this,SLOT(directoryLoadedSlot(QString)));
  12. }
  13.  
  14. int IdentityFileSystemProxyModel::columnCount(const QModelIndex & parent) const
  15. {
  16. return 1;
  17. }
  18.  
  19. QString IdentityFileSystemProxyModel::filePath(const QModelIndex & index) const
  20. {
  21. return QIdentityProxyModel::data(index, Qt::UserRole + 1).toString();
  22. }
  23.  
  24. void IdentityFileSystemProxyModel::directoryLoadedSlot(const QString &path)
  25. {
  26. emit directoryLoaded(path);
  27. }
To copy to clipboard, switch view to plain text mode 
The reason for the IdentityFileSystemProxyModel class is that I have to deal with the fact that a QFileSystemModel model populates incrementally and its loading process is asynchronous. Therefore, I have to relay the QFileSystemModel’s directoryLoaded() signal throughout the proxy chain because some of the proxies call fectchMore() and have to “wait” until the data is loaded to use them. (That is the case with my Selection_Proxy)
I tried to narrow down the problem and I figured out that the problem was still the same when I did this:
Model->IdentityFileSystemProxyModel->Selection_Proxy->View.
Therefore, I really think that the problem has to do with the IdentityFileSystemProxyModel class and the way I relay the QFileSystemModel specific information throughout the he proxy chain.

I would really appreciate some help! Thanks