Hi all,

I am a newbie using Qt and I am stuck with this problem. Let me resume ...

I am trying to display a tree containing nodes representing resource items.
Those items have several attributes (image id, ...) and booleans such as resourceVisible [true|false].

I am able to display the tree with icons representing my booleans (using a delegate). I also use a QSortFilterProxyModel to filter the rows.

Now I would like to update the model when the user click on the icon representing the boolean resourceVisible. But I can't have it work :-\

Here is my program

Structure defining a resource:

Qt Code:
  1. struct ResourceTreeItem {
  2.  
  3. ResourceTreeItem(std::string resourceID=""):m_resourceID(resourceID), m_resourceVisible(true), m_contentVisible(true),
  4. m_boundaryBoxVisible(true), m_mosaicked(true), m_IDVisible(true) {}
  5.  
  6. ResourceTreeItem(const ResourceTreeItem& copy): m_resourceID(copy.m_resourceID), m_resourceVisible(copy.m_resourceVisible), m_contentVisible(copy.m_contentVisible),
  7. m_boundaryBoxVisible(copy.m_boundaryBoxVisible), m_mosaicked(copy.m_mosaicked), m_IDVisible(copy.m_IDVisible) {}
  8.  
  9. std::string m_resourceID;
  10. bool m_resourceVisible;
  11. bool m_contentVisible;
  12. bool m_boundaryBoxVisible;
  13. bool m_mosaicked;
  14. bool m_IDVisible;
  15. };
To copy to clipboard, switch view to plain text mode 

A node (based on Editable Tree Model Example):

Qt Code:
  1. class ResourceTreeNode {
  2. public:
  3. ResourceTreeNode(const ResourceTreeItem& data, ResourceTreeNode* parent = 0);
  4. ~ResourceTreeNode();
  5.  
  6. QVariant data(int column) const;
  7. bool setData(int column, const QVariant& value);
  8. ResourceTreeNode* child(int number);
  9. ResourceTreeNode* parent();
  10.  
  11. int childCount() const;
  12. int childNumber() const;
  13. bool insertChildren(int position, int count, ResourceTreeItem resourceTreeItem);
  14. bool removeChildren(int position, int count);
  15.  
  16. private:
  17. ResourceTreeNode* m_parent;
  18. ResourceTreeItem m_resourceTreeItem;
  19. QList<ResourceTreeNode*> m_childrens;
  20.  
  21. };
To copy to clipboard, switch view to plain text mode 

A custom model (also based on Editable Tree Model Example):

Qt Code:
  1. class QResourceTreeModel : public QAbstractItemModel
  2. {
  3. Q_OBJECT
  4.  
  5. public slots:
  6. void itemClicked(const QModelIndex &index);
  7.  
  8. public:
  9. static const int NB_COLUMN = 6;
  10.  
  11. QResourceTreeModel(QObject *parent = 0) : QAbstractItemModel(parent), m_root(0) {}
  12. QResourceTreeModel(ResourceTreeNode* root, QObject *parent = 0) : QAbstractItemModel(parent), m_root(root) {}
  13.  
  14. void setRootNode(ResourceTreeNode* node);
  15.  
  16. QModelIndex index(int row, int column, const QModelIndex& parent = QModelIndex()) const;
  17. QModelIndex parent(const QModelIndex& index) const;
  18.  
  19.  
  20. int rowCount(const QModelIndex &parent = QModelIndex()) const;
  21. int columnCount(const QModelIndex &parent = QModelIndex()) const;
  22.  
  23. QVariant data(const QModelIndex &index, int role) const;
  24. QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
  25.  
  26. private:
  27. ResourceTreeNode* getNode(const QModelIndex& index) const;
  28. ResourceTreeNode* m_root;
  29. };
To copy to clipboard, switch view to plain text mode 

Basically I connect the signal clicked(const QModelIndex &) to my slot itemClicked(const QModelIndex &index) so I can update the corresponding cell in the tree.

Here is some key methods ...

Qt Code:
  1. QVariant ResourceTreeNode::data(int column) const
  2. {
  3. switch (column) {
  4. case 0:
  5. return QVariant(m_resourceTreeItem.m_resourceVisible);
  6. case 1:
  7. return QVariant(m_resourceTreeItem.m_resourceID.c_str());
  8. case 2:
  9. return QVariant(m_resourceTreeItem.m_contentVisible);
  10. case 3:
  11. return QVariant(m_resourceTreeItem.m_boundaryBoxVisible);
  12. case 4:
  13. return QVariant(m_resourceTreeItem.m_mosaicked);
  14. case 5:
  15. return QVariant(m_resourceTreeItem.m_IDVisible);
  16. default:
  17. return QVariant();
  18. }
  19.  
  20. return QVariant();
  21. }
To copy to clipboard, switch view to plain text mode 

Qt Code:
  1. bool ResourceTreeNode::setData(int column, const QVariant& value) {
  2.  
  3. if (column < 0 || column >= 5) {
  4. return false;
  5. }
  6.  
  7. switch (column) {
  8. case 0:
  9. m_resourceTreeItem.m_resourceVisible = value.toBool();
  10. case 1:
  11. m_resourceTreeItem.m_resourceID = value.toString().toStdString();
  12. case 2:
  13. m_resourceTreeItem.m_contentVisible = value.toBool();
  14. case 3:
  15. m_resourceTreeItem.m_boundaryBoxVisible = value.toBool();
  16. case 4:
  17. m_resourceTreeItem.m_mosaicked = value.toBool();
  18. case 5:
  19. m_resourceTreeItem.m_IDVisible = value.toBool();
  20. default:
  21. break;
  22. }
  23.  
  24. return true;
  25. }
To copy to clipboard, switch view to plain text mode 

Qt Code:
  1. void QResourceTreeModel::itemClicked(const QModelIndex &index) {
  2. if ((index.isValid()) && (index.column() != 1)) {
  3.  
  4. /* The idea is to store false if it was true or true if it was false */
  5.  
  6. ResourceTreeNode* node = getNode(index);
  7. bool result = node->setData(index.column(), QVariant(!node->data(index.column()).toBool()));
  8.  
  9. if (result) {
  10. emit dataChanged(index, index);
  11. }
  12. }
  13. }
To copy to clipboard, switch view to plain text mode 


My problem comes from the method ResourceTreeNode::getNode(index) in QResourceTreeModel::itemClicked(index). The returned node does not contain any ResourceTreeItem? I used a log in getNode() and the problem only happen when I call getNode() from my slot. Somebody have any hints?