Results 1 to 4 of 4

Thread: QAbstractProxyModel to do a Tree

  1. #1
    Join Date
    Jul 2006
    Posts
    126
    Thanks
    17
    Thanked 4 Times in 3 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default QAbstractProxyModel to do a Tree

    Hi,

    I have this code:

    Qt Code:
    1. #include <QAbstractProxyModel> #include <QMap>
    2. class ImageLandmarkTableModel;
    3. class ImageLandmarkProxyModel : public QAbstractProxyModel
    4. {
    5. Q_OBJECT
    6. public:
    7. ImageLandmarkProxyModel(QObject *parent=0);
    8. virtual QModelIndex index(int row, int column,
    9. const QModelIndex &parent=QModelIndex()) const;
    10. virtual QModelIndex parent(const QModelIndex &index) const;
    11. virtual int rowCount(const QModelIndex &parent=QModelIndex()) const;
    12. virtual int columnCount(const QModelIndex &parent=QModelIndex()) const;
    13. virtual QModelIndex mapToSource(const QModelIndex &proxyIndex) const;
    14. virtual QModelIndex mapFromSource(const QModelIndex &sourceIndex) const;
    15. virtual void setSourceModel(ImageLandmarkTableModel *sourceModel);
    16. ImageLandmarkTableModel* sourceModel() const;
    17. QVariant data(const QModelIndex &index, int role) const;
    18. protected slots:
    19. void countRowsInserted(const QModelIndex &parent, int srcStart, int srcEnd);
    20. void countRowsRemoved(const QModelIndex &parent, int srcStart, int srcEnd);
    21. private:
    22. struct ProxyLink {
    23. int sourceRow; // Source row
    24. QList<int> points; // List of source rows from the childs
    25. };
    26. typedef QMap<int,ProxyLink> MappingData;
    27. MappingData m_mapping;
    28. };
    To copy to clipboard, switch view to plain text mode 
    Qt Code:
    1. #include "imagelandmarkproxymodel.h" #include <QtSql>
    2. #include "imagelandmarktablemodel.h"
    3. ImageLandmarkProxyModel::ImageLandmarkProxyModel(QObject *parent)
    4. {
    5. }
    6. QModelIndex ImageLandmarkProxyModel::index(int row, int column,
    7. const QModelIndex &parent) const
    8. {
    9. if(!parent.isValid()) // Root
    10. return createIndex(row, column);
    11. int id=m_mapping.keys().at(parent.row());
    12. const ProxyLink &link=m_mapping[id];
    13. return createIndex(link.points.at(row), column);
    14. }
    15. QModelIndex ImageLandmarkProxyModel::parent(const QModelIndex &index) const
    16. {
    17. return QModelIndex();
    18. }
    19. int ImageLandmarkProxyModel::rowCount(const QModelIndex &parent) const
    20. {
    21. const MappingData &m=m_mapping;
    22. if(parent.isValid())
    23. {
    24. bool ok;
    25. int id=parent.data().toInt(&ok); Q_ASSERT(ok);
    26. return m[id].points.count();
    27. }
    28. return m.count();
    29. }
    30. int ImageLandmarkProxyModel::columnCount(const QModelIndex &parent) const
    31. {
    32. return 1;
    33. }
    34. QModelIndex ImageLandmarkProxyModel::mapToSource(const QModelIndex &proxyIndex) const
    35. {
    36. QModelIndex parent=proxyIndex.parent();
    37. if(parent.isValid()){
    38. int parentRow=parent.row();
    39. int id=m_mapping.keys().at(parentRow);
    40. const QList<int> &points=m_mapping[id].points;
    41. return sourceModel()->index(points.at(proxyIndex.row()), 1);
    42. }
    43. int row=proxyIndex.row();
    44. int id=m_mapping.keys().at(row);
    45. const ProxyLink &link=m_mapping[id];
    46. return sourceModel()->index(link.sourceRow, 0);
    47. }
    48. QModelIndex ImageLandmarkProxyModel::mapFromSource(
    49. const QModelIndex &sourceIndex) const
    50. {
    51. return index(sourceIndex.row(), sourceIndex.column());
    52. }
    53. void ImageLandmarkProxyModel::setSourceModel(
    54. ImageLandmarkTableModel *sourceModel)
    55. {
    56. disconnect();
    57. QAbstractProxyModel::setSourceModel(sourceModel);
    58. connect(sourceModel, SIGNAL(rowsInserted(QModelIndex,int,int)),
    59. SLOT(countRowsInserted(QModelIndex,int,int)));
    60. connect(sourceModel, SIGNAL(rowsRemoved(QModelIndex,int,int)),
    61. SLOT(countRowsRemoved(QModelIndex,int,int)));
    62. }
    63. ImageLandmarkTableModel* ImageLandmarkProxyModel::sourceModel() const
    64. {
    65. return static_cast<ImageLandmarkTableModel*>(ptr);
    66. }
    67. QVariant ImageLandmarkProxyModel::data(const QModelIndex &index, int role)
    68. const
    69. {
    70. if(!index.isValid()) return QVariant();
    71. QModelIndex parent=index.parent();
    72. if(parent.isValid())
    73. return mapToSource(index).data(role);
    74. }
    75. void ImageLandmarkProxyModel::countRowsInserted(const QModelIndex &parent,
    76. int srcStart, int srcEnd)
    77. {
    78. const int idImageColumn=sourceModel()->column(
    79. ImageLandmarkTableModel::IdImage);
    80. const int idPointColumn=sourceModel()->column(
    81. ImageLandmarkTableModel::IdPoint);
    82. MappingData &m=m_mapping;
    83. for(int i=srcStart;i<=srcEnd;i++)
    84. {
    85. QModelIndex col1=sourceModel()->index(i, idImageColumn);
    86. QModelIndex col2=sourceModel()->index(i, idPointColumn);
    87. bool ok;
    88. int id=col1.data().toInt(&ok);
    89. MappingData::iterator it=m.find(id);
    90. Q_ASSERT(ok);
    91. if(it!=m.end()) it->points.append(i);
    92. else if(!col2.data().isNull()){
    93. ProxyLink proxyLink;
    94. proxyLink.sourceRow=i;
    95. proxyLink.points.append(i);
    96. m.insert(id, proxyLink);
    97. }
    98. else{
    99. ProxyLink proxyLink;
    100. proxyLink.sourceRow=i;
    101. m.insert(id, proxyLink);
    102. }
    103. }
    104. }
    105. void ImageLandmarkProxyModel::countRowsRemoved(const QModelIndex &parent, int srcStart, int srcEnd)
    106. {
    107. // TODO: Do this slot
    108. qCritical()<<"ImageLandmarkProxyModel::countRowsRemoved"<<"Unimplemented slot";
    109. }
    To copy to clipboard, switch view to plain text mode 


    I can't solve this problem, I think the childs are pointing to the parents or something else.
    Someone can help me?

  2. #2
    Join Date
    Jul 2006
    Posts
    126
    Thanks
    17
    Thanked 4 Times in 3 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: QAbstractProxyModel to do a Tree

    I think that the problem is with the QAbstractItemView:: parent, I don't know how to implement it.

  3. #3
    Join Date
    Dec 2006
    Posts
    849
    Thanks
    6
    Thanked 163 Times in 151 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: QAbstractProxyModel to do a Tree

    If you describe what the code should do (rather than let us guess what your buggy code should be doing...) we would better be able to help.

    You have to encode enough information when creating an index so you can find the information in your model.
    In index() you have to encode the information about the parent. The parent() function basically is the inverse function to that. Given a node, unwrap the index and determine the parent.
    There are several ways to do that. These differ in complexity and speed. It depends on the model which can be used. (E.g. for models with root-node-child but no grandchildren this is easy. It is not as simple for arbitrary hierarchies.) If we know what you want to achieve, we shall be able to advise you.

  4. #4
    Join Date
    Jul 2006
    Posts
    126
    Thanks
    17
    Thanked 4 Times in 3 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: QAbstractProxyModel to do a Tree

    I want to convert a plain QSqlTableModel that loads this view:

    Qt Code:
    1. CREATE VIEW [dbo].[ImageLandmark] AS
    2. SELECT [i].[Id] AS [IdImage], [l].[Id] AS [IdPoint],
    3. [l].[X], [l].[Y], [l].[Size], [i].[Name], [i].[Thumbnail]
    4. FROM [Image] AS [i]
    5. LEFT JOIN [Landmark] AS [l] ON [i].[Id]=[l].[IdImage]
    6. LEFT JOIN [User] AS [u] ON [u].[Id]=[l].[IdUser];
    To copy to clipboard, switch view to plain text mode 

    Into a tree view where the parent will be the IdImage and the childs the diferent Points.

    Thanks

Similar Threads

  1. creating a Tree
    By mickey in forum General Programming
    Replies: 0
    Last Post: 20th April 2008, 17:57
  2. QAbstractProxyModel and QTreeView
    By niko in forum Qt Programming
    Replies: 5
    Last Post: 18th January 2008, 21:17
  3. Drag from tree widget
    By EricF in forum Qt Programming
    Replies: 9
    Last Post: 17th December 2007, 23:09
  4. Replies: 3
    Last Post: 19th April 2007, 11:42
  5. Optimizing filterAcceptsRow() to filter a tree
    By vfernandez in forum Qt Programming
    Replies: 1
    Last Post: 4th January 2007, 12:50

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.