Results 1 to 6 of 6

Thread: Transparent QAbstractProxyModel for tree models

  1. #1
    Join Date
    Mar 2010
    Location
    Gdynia, Poland
    Posts
    12
    Thanked 3 Times in 1 Post
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Transparent QAbstractProxyModel for tree models

    Hi everybody.

    I know that similar posts were here on the forum but as I saw usually threads were finished with the conclusion that maybe different model should be used instead of QAbstractProxyModel.

    The problem :
    Right now I've a tree model based on QAbstractItemModel which is used to hold objects of TreeModelItem type ( obvious isn't it ? ). There is no problem to create such a model here is the model and item code.

    BaseTreeModel.cpp
    Qt Code:
    1. #include "BaseTreeModel.h"
    2. #include "TreeModelItem.h"
    3. #include <QDebug>
    4.  
    5. BaseTreeModel::BaseTreeModel() {
    6. // fake structure
    7. QList<QVariant *> fakeData1;
    8. fakeData1.push_back(new QVariant("fakeData11"));
    9. fakeData1.push_back(new QVariant("fakeData22"));
    10.  
    11.  
    12. QList<QVariant *> fakeData2;
    13. fakeData2.push_back(new QVariant(1111));
    14. fakeData2.push_back(new QVariant(2222));
    15.  
    16.  
    17. rootItem = new TreeModelItem(fakeData1, 0);
    18.  
    19. for (int i = 0;i<1;i++){
    20. TreeModelItem *item = new TreeModelItem(fakeData1, rootItem);
    21. rootItem->appendChild(item);
    22. for (int j=0;j<1;j++)
    23. item->appendChild( new TreeModelItem(fakeData2, item) );
    24. }
    25.  
    26. }
    27.  
    28. BaseTreeModel::~BaseTreeModel() {
    29. }
    30.  
    31. // Minimum implementation for ReadOnly model
    32. QModelIndex BaseTreeModel::index ( int row, int column, const QModelIndex & parent ) const {
    33. if (!hasIndex(row, column, parent))
    34. return QModelIndex();
    35.  
    36. TreeModelItem *parent_item;
    37. if (!parent.isValid()){
    38. parent_item = rootItem;
    39. } else {
    40. parent_item = static_cast<TreeModelItem*>(parent.internalPointer());
    41. }
    42.  
    43. TreeModelItem *child_item = parent_item->childAt(row);
    44.  
    45. if (child_item) {
    46. return createIndex(row, column, child_item);
    47. } else {
    48. return QModelIndex();
    49. }
    50. }
    51.  
    52. QModelIndex BaseTreeModel::parent ( const QModelIndex & index ) const {
    53. if (!index.isValid())
    54. return QModelIndex();
    55.  
    56. TreeModelItem* child_item = static_cast<TreeModelItem*>(index.internalPointer());
    57. TreeModelItem* parent_item = child_item->parent();
    58.  
    59. if (parent_item == rootItem)
    60. return QModelIndex();
    61.  
    62. return createIndex(parent_item->row(), 0, parent_item);
    63. }
    64.  
    65. QVariant BaseTreeModel::data ( const QModelIndex & index, int role) const {
    66. if (!index.isValid())
    67. return QVariant();
    68.  
    69. if (role != Qt::DisplayRole)
    70. return QVariant();
    71.  
    72. TreeModelItem* item = static_cast<TreeModelItem*>(index.internalPointer());
    73. QModelIndex p = index.parent();
    74.  
    75. if( item->childCount() && index.column() != 0)
    76. return QVariant();
    77. else
    78. return item->data( index.column() );
    79.  
    80. }
    81.  
    82. int BaseTreeModel::columnCount ( const QModelIndex & parent) const {
    83. if ( parent.isValid() ) {
    84. return static_cast<TreeModelItem*>(parent.internalPointer())->columnCount();
    85. } else {
    86. return rootItem ? rootItem->columnCount(): 0;
    87. }
    88.  
    89.  
    90. }
    91.  
    92. QVariant BaseTreeModel::headerData ( int section, Qt::Orientation orientation, int role ) const {
    93. if ( orientation == Qt::Horizontal && role == Qt::DisplayRole) {
    94. return rootItem->data(section);
    95. }
    96. return QVariant();
    97. }
    98.  
    99. int BaseTreeModel::rowCount ( const QModelIndex & parent ) const {
    100. TreeModelItem* parent_item;
    101. if (parent.column() > 0)
    102. return 0;
    103.  
    104. if (!parent.isValid())
    105. parent_item = rootItem;
    106. else
    107. parent_item = static_cast<TreeModelItem*>(parent.internalPointer());
    108.  
    109. return parent_item->childCount();
    110. }
    111.  
    112. bool BaseTreeModel::hasChildren ( const QModelIndex & parent ) const {
    113. if ( parent.isValid() ) {
    114. bool retVal = static_cast<TreeModelItem*>(parent.internalPointer())->childCount();
    115. return retVal;
    116. } else {
    117. return (bool)(rootItem->childCount());
    118. }
    119. }
    120.  
    121. Qt::ItemFlags BaseTreeModel::flags ( const QModelIndex & index ) const {
    122. if (!index.isValid())
    123. return 0;
    124. return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
    125. }
    To copy to clipboard, switch view to plain text mode 

    BaseTreeModel.h
    Qt Code:
    1. class TreeModelItem;
    2.  
    3. #ifndef BASETREEMODEL_H
    4. #define BASETREEMODEL_H
    5.  
    6. #include <QAbstractItemModel>
    7.  
    8. class BaseTreeModel : public QAbstractItemModel {
    9. public :
    10. BaseTreeModel();
    11. ~BaseTreeModel();
    12.  
    13. // Minimum implementation for ReadOnly model
    14. virtual QModelIndex index ( int row, int column, const QModelIndex & parent = QModelIndex() ) const;
    15. virtual QModelIndex parent ( const QModelIndex & index ) const ;
    16. virtual QVariant data ( const QModelIndex & index, int role = Qt::DisplayRole ) const ;
    17. virtual QVariant headerData ( int section, Qt::Orientation orientation, int role = Qt::DisplayRole ) const ;
    18. virtual int rowCount ( const QModelIndex & parent = QModelIndex() ) const;
    19. virtual int columnCount ( const QModelIndex & parent = QModelIndex() ) const ;
    20. virtual bool hasChildren ( const QModelIndex & parent = QModelIndex() ) const ;
    21. virtual Qt::ItemFlags flags ( const QModelIndex & index ) const ;
    22.  
    23. private :
    24. // internal model structure let's name it cache :)
    25. TreeModelItem *rootItem;
    26.  
    27. };
    28.  
    29. #endif // BASETREEMODEL_H
    To copy to clipboard, switch view to plain text mode 

    And the model item that is stored internally
    TreeModelItem.cpp
    Qt Code:
    1. #include "TreeModelItem.h"
    2. #include <QDebug>
    3.  
    4. TreeModelItem::TreeModelItem(QList<QVariant *> data, TreeModelItem *parent) : itemData(data), parentItem(parent) {
    5.  
    6. }
    7.  
    8. TreeModelItem::~TreeModelItem(){
    9.  
    10. }
    11.  
    12. void TreeModelItem::appendChild(TreeModelItem * child){
    13. childItems.append(child);
    14. }
    15.  
    16. void TreeModelItem::removeChild(TreeModelItem * child){
    17. childItems.removeOne( child );
    18. }
    19.  
    20. TreeModelItem * TreeModelItem::childAt(int row){
    21. if ( childItems.count() > row )
    22. return childItems.at( row );
    23. else
    24. return NULL;
    25. }
    26.  
    27. int TreeModelItem::childCount() const {
    28. return childItems.count();
    29. }
    30.  
    31. int TreeModelItem::columnCount() const {
    32. return itemData.count();
    33. }
    34.  
    35. QVariant TreeModelItem::data(int column) const {
    36. return *itemData.at( column );
    37. }
    38.  
    39. int TreeModelItem::row() const {
    40. if (parentItem)
    41. return parentItem->childItems.indexOf(const_cast<TreeModelItem*>(this));
    42.  
    43. return 0;
    44. }
    45.  
    46. TreeModelItem * TreeModelItem::parent(){
    47. return parentItem;
    48. }
    49.  
    50. void TreeModelItem::clear(){
    51. this->itemData.clear();
    52. }
    To copy to clipboard, switch view to plain text mode 

    TreeModelItem.h
    Qt Code:
    1. #ifndef TREEMODELITEM_H
    2. #define TREEMODELITEM_H
    3.  
    4. #include <QList>
    5. #include <QVariant>
    6.  
    7. class TreeModelItem {
    8. public:
    9. TreeModelItem(QList<QVariant *> data, TreeModelItem *parent = 0);
    10. ~TreeModelItem();
    11. void appendChild(TreeModelItem * child);
    12. void removeChild(TreeModelItem * child);
    13.  
    14. TreeModelItem *childAt(int row);
    15.  
    16. int childCount() const;
    17. int columnCount() const;
    18. QVariant data(int column) const;
    19. int row() const;
    20.  
    21. TreeModelItem *parent();
    22. void updateColumn(int column, QVariant *data);
    23. void updateItem( const QMap<int, QVariant *> &data);
    24. void clear();
    25.  
    26. private:
    27. QList<TreeModelItem *> childItems;
    28. QList<QVariant *> itemData;
    29. TreeModelItem *parentItem;
    30. };
    31.  
    32. #endif // TREEMODELITEM_H
    To copy to clipboard, switch view to plain text mode 

    This tree is working. The structure right now is build in the constructor but only for the test purposes.

    I want to create the base proxy model which will be transparent. I don't to have any fancy things inside at the firs step. If I've take QSortFilterProxyModel everything is Ok. But with QAbstractProxyModel it wan't work. I've implemented all the necessary virtual methods but I think that I'm doing this wrong. So the first step is to create transparent proxy based on QAbstaractProxyModel to understand the concept of source <-> proxy mapping.
    Then later I want to create proxy for different aggregation/grouping, model flatten to table, adding a virtual columns etc..

    Could somebody can help me with this issue to guide how to implement mapToSource, mapFromSource and index, parent etc... in this proxy on my model arch.

  2. #2
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Transparent QAbstractProxyModel for tree models

    For tree models these two methods are quite complex so it is really easier to base your proxy model on QSortFilterProxyModel. If you really want to implement your own mapping then you have to come up with a mapping algorithm. You will probably need some internal map that will contain enough information to map between source and target models and you would have to update this map every time anything changes in the base model. But since QSortFilterProxyModel already does that I don't see a point in repeating it especially that it's really not something you can implement in 5 minutes.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  3. #3
    Join Date
    Mar 2010
    Location
    Gdynia, Poland
    Posts
    12
    Thanked 3 Times in 1 Post
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Transparent QAbstractProxyModel for tree models

    Yes I know that.

    The first issue that I want to fix is a behaviour of the branch column. It looks strange when you've a branch column somewhere in the middle in view. So my idea is to create a proxy which will be able to hole branch column always on the most left side and if the user will want to swap the column with this particular one the proxy should change the indexes in the way that data that was before in the branch column should be shown in the swapped column and the data from this column which is dropped to the branch should be presented with with column zero.

    I don't know that I'm clear enough ?

    Theoretically it should be possible with QSortFilterProxyModel when we reimplement index and data an I right ? Maybe this is the right way ?

  4. #4
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Transparent QAbstractProxyModel for tree models

    I would do it by reimplementing the view that is responsible for drawing the branches but what do I know...
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  5. #5
    Join Date
    Mar 2010
    Location
    Gdynia, Poland
    Posts
    12
    Thanked 3 Times in 1 Post
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Transparent QAbstractProxyModel for tree models

    Yes maybe this is the god idea, but it's even less described in doc than models sub classing It should be rather a combination of proxy and view. Where in view column moving policy should be changed. To not allow of the most left column moving. But only the other column will be allowed to drop in to it. Ill try.

    By the way have you read a priv. message that I've sent to you this morning (this one written in Polish) ?

  6. #6
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Transparent QAbstractProxyModel for tree models

    Quote Originally Posted by adzajac View Post
    Yes maybe this is the god idea, but it's even less described in doc than models sub classing It should be rather a combination of proxy and view. Where in view column moving policy should be changed. To not allow of the most left column moving. But only the other column will be allowed to drop in to it. Ill try.
    If you want to prevent a column from being moved then do just that. It's enough to subclass QHeaderView and prevent the first column from being moved.

    By the way have you read a priv. message that I've sent to you this morning (this one written in Polish) ?
    It's a visitor message and not a private message. I'll read it in a moment.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


Similar Threads

  1. Replies: 0
    Last Post: 25th August 2010, 17:39
  2. Replies: 0
    Last Post: 1st July 2010, 21:55
  3. Replies: 1
    Last Post: 11th June 2010, 08:14
  4. QAbstractProxyModel to do a Tree
    By xgoan in forum Qt Programming
    Replies: 3
    Last Post: 18th November 2008, 17:31
  5. Proxy models and slection models
    By amunitz in forum The Model-View Framework
    Replies: 1
    Last Post: 23rd September 2008, 14:35

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.