Results 1 to 16 of 16

Thread: Always show QTreeview branches in the far left column

  1. #1
    Join Date
    May 2009
    Location
    Copenhagen
    Posts
    50
    Thanks
    6
    Thanked 2 Times in 2 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Always show QTreeview branches in the far left column

    I'm working with a Qtreeview and I'm facing some problems having the treview shown when either the first column is hidden or when I rearrange the tree.

    I'm using a custom model where I've tried to put in a 'branch column' (m_branchcolumn see below) to map the parent to the first visible column in the treeview but it doesn't work. I always see the treeview nodes (the plus and minus signs) in column zero. I'm using an internal record representation like the nodeitem from the simple treeview example shipped with Qt.

    Qt Code:
    1. QModelIndex ViewModel::parent(const QModelIndex &child) const
    2. {
    3. if (!child.isValid())
    4. return QModelIndex();
    5.  
    6. Record *rec = recordFromIndex(child);
    7. if (!rec)
    8. return QModelIndex();
    9.  
    10. Record *parentRecord = rec->parent;
    11. if (!parentRecord)
    12. return QModelIndex();
    13.  
    14. if(parentRecord == rootRecord)
    15. return QModelIndex();
    16.  
    17. Record *grandparentRecord = parentRecord->parent;
    18.  
    19. if (!grandparentRecord)
    20. return QModelIndex();
    21.  
    22. int row = grandparentRecord->children.indexOf(parentRecord);
    23. return createIndex(row, m_branchcolumn, parentRecord);
    24. }
    To copy to clipboard, switch view to plain text mode 

    How can I make sure always to show the tree branches in the far left visible column even after column change and with hidden columns?
    Attached Images Attached Images

  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: Always show QTreeview branches in the far left column

    By definition QTreeView displays branches in the column with logical index '0' (or the lowest non-hidden column probably but I'm not sure). To override that you have to either provide a proxy model that will rearrange your columns or reimplement QTreeView.
    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
    May 2009
    Location
    Copenhagen
    Posts
    50
    Thanks
    6
    Thanked 2 Times in 2 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Always show QTreeview branches in the far left column

    Thanks for your reply wysota

    Quote Originally Posted by wysota View Post
    By definition QTreeView displays branches in the column with logical index '0' (or the lowest non-hidden column probably but I'm not sure).
    Yes, QTreeview displays branches in the column with logical index '0' but if that column is hidden the tree nodes will not appear. Tree effect is preserved however as the user is still able to expand/subtract with plus and minus keys.

    Quote Originally Posted by wysota View Post
    To override that you have to either provide a proxy model that will rearrange your columns or reimplement QTreeView.
    Acctually I am using a proxymodel for the treeview already. How would I go about rearranging the columns to get the effect I want?

    Thanks

  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: Always show QTreeview branches in the far left column

    The easiest would be to reimplement data() and call the base class implementation of the proxy with a modified index (switched column numbers).
    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
    May 2009
    Location
    Copenhagen
    Posts
    50
    Thanks
    6
    Thanked 2 Times in 2 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Always show QTreeview branches in the far left column

    This is my reimplementation! I've tried to change the index but as it's a const function all my changes resolves in error. What would I need to change in this data function to swap say column 0 with column 1?

    Qt Code:
    1. QVariant MyProxyModel::data ( const QModelIndex & index, int role ) const
    2. {
    3. if (!index.isValid())
    4. return QVariant();
    5.  
    6. return QAbstractProxyModel::data(index, role);
    7. }
    To copy to clipboard, switch view to plain text mode 

    Thank you again for your help!

  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: Always show QTreeview branches in the far left column

    Create a new index, don't change the original one (it's const...).

    For example:
    Qt Code:
    1. QModelIndex changed = index.sibling(index.row(), (index.column()+1) % 10);
    To copy to clipboard, switch view to plain text mode 
    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.


  7. The following user says thank you to wysota for this useful post:

    Nightfox (13th January 2010)

  8. #7
    Join Date
    May 2009
    Location
    Copenhagen
    Posts
    50
    Thanks
    6
    Thanked 2 Times in 2 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Always show QTreeview branches in the far left column

    It definitely one way to go but it gets messy. If I make changes to the 0 column the changes will be saved in the 'swap' column. Eventually I'll have to accommodate this change in index, parent, mapToSource, mapFromSource aswell right?

    Below I'm substituting the branch column with 0 column and vica versa.

    This is my new implementation;
    Qt Code:
    1. QVariant MyProxyModel::data ( const QModelIndex & index, int role ) const
    2. {
    3. if (!index.isValid())
    4. return QVariant();
    5.  
    6. if(index.column() == m_branchcolumn)
    7. {
    8. QModelIndex changed = index.sibling(index.row(), 0);
    9. return QAbstractProxyModel::data(changed, role);
    10. }
    11. if(index.column() == 0)
    12. {
    13. QModelIndex changed = index.sibling(index.row(), m_branchcolumn);
    14. return QAbstractProxyModel::data(changed, role);
    15. }
    16. return QAbstractProxyModel::data(index, role);
    17. }
    To copy to clipboard, switch view to plain text mode 

    I haven't gotten it to work correctly yet but I think this might be the way forward. Thanks for you input.

  9. #8
    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: Always show QTreeview branches in the far left column

    Quote Originally Posted by Nightfox View Post
    It definitely one way to go but it gets messy. If I make changes to the 0 column the changes will be saved in the 'swap' column. Eventually I'll have to accommodate this change in index, parent, mapToSource, mapFromSource aswell right?
    It depends on your model.
    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.


  10. #9
    Join Date
    May 2009
    Location
    Copenhagen
    Posts
    50
    Thanks
    6
    Thanked 2 Times in 2 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Always show QTreeview branches in the far left column

    The model is a reimplemented QAbstractProxyModel. This shows you the functions I've reimplemented so far.

    Qt Code:
    1. virtual int columnCount (const QModelIndex& parent = QModelIndex()) const ;
    2. virtual int rowCount(const QModelIndex& parent) const ;
    3.  
    4. virtual QModelIndex index(int row, int column, const QModelIndex& parent = QModelIndex()) const ;
    5. virtual QModelIndex parent (const QModelIndex& index) const ;
    6.  
    7. virtual QModelIndex mapFromSource(const QModelIndex&) const ;
    8. virtual QModelIndex mapToSource(const QModelIndex&) const ;
    9. virtual bool hasChildren ( const QModelIndex & parent = QModelIndex() ) const;
    10. virtual QVariant data ( const QModelIndex & index, int role = Qt::DisplayRole ) const;
    11. virtual Qt::ItemFlags flags ( const QModelIndex & index ) const;
    To copy to clipboard, switch view to plain text mode 

    Surely I need to swao the index for all these functions?

  11. #10
    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: Always show QTreeview branches in the far left column

    If you are already implementing a proxy model then everything is just a matter of adjusting your mapFromSource() and mapToSource() methods. In the other methods you surely already use those two so everything should work fine.
    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.


  12. The following user says thank you to wysota for this useful post:

    Nightfox (19th January 2010)

  13. #11
    Join Date
    May 2009
    Location
    Copenhagen
    Posts
    50
    Thanks
    6
    Thanked 2 Times in 2 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Always show QTreeview branches in the far left column

    This gets more and more messy! I've implemented this to swap column 0 with the branch column in order to always have the branches in the far left column, even after user column rearrange.

    However after the change in mapFramSource and mapToSource no data is displayed in the tree.

    Qt Code:
    1. QModelIndex MyProxyModel::mapFromSource(const QModelIndex& sourceIndex) const
    2. {
    3. if (sourceIndex.isValid())
    4. {
    5. int key = sourceModel()->data(sourceModel()->index(sourceIndex.row(), m_sourcekeycolumn,QModelIndex()) ).toInt() ;
    6. Record *rec = internaltable->m_map.value(key);
    7. int row = 0;
    8.  
    9. if(rec->parent)
    10. row = rec->parent->children.indexOf(rec);
    11. const int brcol = getBranchColumn();
    12. if( sourceIndex.column() == brcol ) {
    13. QModelIndex changed = sourceIndex.sibling(row, 0); //new
    14. return changed;
    15. }
    16. if( sourceIndex.column() == 0 ){
    17. QModelIndex changed = sourceIndex.sibling(row, brcol ); //new
    18. return changed;
    19. }
    20. return createIndex(row,sourceIndex.column(),rec) ;
    21. }
    22. return QModelIndex();
    23. }
    24. //
    25. QModelIndex MyProxyModel::mapToSource(const QModelIndex& proxyIndex) const
    26. {
    27. if(proxyIndex.isValid())
    28. {
    29. Record *rec = recordFromIndex(proxyIndex);
    30. const int brcol = getBranchColumn();
    31. if(rec)
    32. {
    33. if( proxyIndex.column() == brcol ) {
    34. QModelIndex changed = proxyIndex.sibling(proxyIndex.row(), 0); //new
    35. return changed;
    36. }
    37. if( proxyIndex.column() == 0 ){
    38. QModelIndex changed = proxyIndex.sibling(proxyIndex.row(), brcol ); //new
    39. return changed;
    40. }
    41. }
    42. }
    43. return QModelIndex() ;
    44. }
    To copy to clipboard, switch view to plain text mode 

    My model hieracy is QStandarItemModel to QAbstractProxyModel to QSortFilterProxyModel so the source model for the treeview is QSortFilterProxyModel. Why can't I squeeze more functionality out of the two extra proxy models to archive the column swap? I had really hoped for more help from one of the proxies!

    What an I doing wrong?

  14. #12
    Join Date
    Mar 2006
    Posts
    10
    Thanked 7 Times in 6 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Always show QTreeview branches in the far left column

    I am not sure if I correctly understood the task but is it not be easier to manipulate QHeaderView?
    For example.
    Qt Code:
    1. QFileSystemModel *model = new QFileSystemModel(ui->m_tv);
    2. model->setRootPath("C:\\");
    3. ui->m_tv->setModel(model);
    4. int sectionCount = ui->m_tv->header()->count();
    5. qDebug() << "Section count:" << sectionCount;
    6. QHeaderView *hv = ui->m_tv->header();
    7. hv->moveSection(hv->visualIndex(0), hv->visualIndex(sectionCount - 1));
    8. hv->setSectionHidden(hv->logicalIndex(1), true);
    To copy to clipboard, switch view to plain text mode 

  15. #13
    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: Always show QTreeview branches in the far left column

    Quote Originally Posted by Rembobo View Post
    I am not sure if I correctly understood the task but is it not be easier to manipulate QHeaderView?
    No, because this causes tree branches to move.
    Last edited by wysota; 15th January 2010 at 10:25.
    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.


  16. #14
    Join Date
    May 2009
    Location
    Copenhagen
    Posts
    50
    Thanks
    6
    Thanked 2 Times in 2 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Always show QTreeview branches in the far left column

    So I just spend like five days figuring out that the indexes of the proxymodel get changed when I add an additional model on top of that. I've been debugging and debugging and debugging to I almost gave up. You out there who knew this please don't say I told you so!

    @wysota: I used you suggestion on changing the mapFromSouce and mapToSource functions and now it finally works! I'm able to have the tree branches in the m_branchcolumn column (see below). I dont know if you still follow the code but I'm using a hierarchical model like the Qt's simple treeview example but instead of a Node class I'm using a Record class - but essentially it's the same. The m_branchcolumn column is the column of which I wish to swap the 0 column. Thanks again for your input and help!

    So the following implementation will keep the branches in the m_branchcolumn.

    Qt Code:
    1. QModelIndex ViewModel::mapFromSource(const QModelIndex& sourceIndex) const
    2. {
    3. if (sourceIndex.isValid())
    4. {
    5. int key = sourceModel()->data(sourceModel()->index(sourceIndex.row(), m_sourcekeycolumn,QModelIndex()) ).toInt() ;
    6. Record *rec = internaltable->getRecord(key);
    7. int row = 0;
    8. int col = sourceIndex.column();
    9. if(rec->parent)
    10. row = rec->parent->children.indexOf(rec);
    11.  
    12. if(sourceIndex.column() == m_branchcolumn) col = 0;
    13. if(sourceIndex.column() == 0 ) col = m_branchcolumn;
    14. return createIndex(row,col,rec) ;
    15. }
    16. return QModelIndex();
    17. }
    18.  
    19. QModelIndex ViewModel::mapToSource(const QModelIndex& proxyIndex) const
    20. {
    21. if(proxyIndex.isValid())
    22. {
    23.  
    24. Record *rec = recordFromIndex(proxyIndex);
    25. if(rec) {
    26. int col = proxyIndex.column();
    27. if(proxyIndex.column() == m_branchcolumn) col = 0;
    28. if(proxyIndex.column() == 0 ) col = m_branchcolumn;
    29. return sourceModel()->index(rec->sourcerow,col,QModelIndex());
    30. }
    31. }
    32. return QModelIndex() ;
    33. }
    To copy to clipboard, switch view to plain text mode 

  17. The following user says thank you to Nightfox for this useful post:

    timohare (9th September 2010)

  18. #15
    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: Always show QTreeview branches in the far left column

    Great that you made it work. I was following the thread all the time - I'm very interested in every topic related to proxy models.

    BTW. "I told you so"
    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.


  19. #16
    Join Date
    Sep 2010
    Posts
    3
    Thanks
    1
    Qt products
    Qt4 Qt/Embedded
    Platforms
    Unix/X11 Windows

    Default Re: Always show QTreeview branches in the far left column

    Thanks wysota & Nightfox, this helped me immensely.
    There isn't much documentation on mapToSource or mapFromSource so here is the code I figured out.
    This is useful for changing the order of the columns without using moveSection.
    Next step is to patch in another model in to this proxyModel.

    Qt Code:
    1. QModelIndex RoadProxyModel::mapFromSource(const QModelIndex& sourceIndex) const
    2. {
    3. if (sourceIndex.isValid())
    4. {
    5. int col = sourceIndex.column();
    6. int row = sourceIndex.row();
    7. QModelIndex baseMapToSource = QSortFilterProxyModel::mapFromSource(sourceIndex);
    8. row = baseMapToSource.row();
    9. switch (col)
    10. {
    11. case WIShmemModel::ColTrkBat:
    12. return index(row, ColTrkBat);
    13. case WIShmemModel::ColExchgPad:
    14. return index(row, ColExchgPad);
    15. case WIShmemModel::ColLaneNo:
    16. return index(row, ColLane);
    17. ...
    18. default:
    19. LOG_DBG("Uknown column %d", col);
    20. return QModelIndex();
    21. }
    22. }
    23. return QModelIndex();
    24. }
    25.  
    26. QModelIndex RoadProxyModel::mapToSource(const QModelIndex& proxyIndex) const
    27. {
    28. if(proxyIndex.isValid())
    29. {
    30. int row = proxyIndex.row();
    31. QModelIndex baseMapToSource = QSortFilterProxyModel::mapToSource(proxyIndex);
    32. row = baseMapToSource.row();
    33. switch (proxyIndex.column())
    34. {
    35. case ColTrkBat:
    36. return sourceModel()->index(row, WIShmemModel::ColTrkBat);
    37. case ColExchgPad:
    38. return sourceModel()->index(row, WIShmemModel::ColExchgPad);
    39. case ColLane:
    40. return sourceModel()->index(row, WIShmemModel::ColLaneNo);
    41. ...
    42. default:
    43. LOG_DBG("Uknown column %d", proxyIndex.column());
    44. return QModelIndex();
    45. }
    46. }
    47.  
    48. return QModelIndex() ;
    49. }
    To copy to clipboard, switch view to plain text mode 

Similar Threads

  1. QTreeView/QHeaderView : resize handle on the left
    By Jeremy in forum Qt Programming
    Replies: 3
    Last Post: 14th May 2009, 22:43
  2. Replies: 1
    Last Post: 23rd November 2008, 14:11
  3. Fixed Column in QTreeview
    By ormonde in forum Qt Programming
    Replies: 3
    Last Post: 12th May 2008, 07:49
  4. No delegate for 1 column in QTreeView
    By mace in forum Qt Programming
    Replies: 1
    Last Post: 15th February 2007, 10:55
  5. Replies: 1
    Last Post: 12th November 2006, 16:56

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.