Results 1 to 15 of 15

Thread: QListView sorting

  1. #1
    Join Date
    Mar 2007
    Posts
    31
    Thanks
    2
    Qt products
    Qt3
    Platforms
    Unix/X11

    Question QListView sorting

    I'd like to subclass QListView in the way it will only emit some signal when user makes sort request (click on header's column). I cannot turn off sorting with setSorting(-1) because then I also lose sort indicator. I have native method in my collection that takes care of sorting so QListView should only emit signal, native method will sort items and finally QListView will be cleared and filled with new items in new order. I've tried to reimplement QListView::sort(), QListView::enforceSortOrder() and QListViewItem::sortChildItems(int, bool). Despite the fact I was browsing qlistview.cpp carefully I still don't know what method actually sorts QListViewItems when user changes sort order by clicking header's column.

  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: QListView sorting

    How about reimplementing QListView::sort() and do the sorting there (or forward it elsewhere)? What went wrong when you tried to use it?

  3. #3
    Join Date
    Mar 2007
    Posts
    31
    Thanks
    2
    Qt products
    Qt3
    Platforms
    Unix/X11

    Default Re: QListView sorting

    Quote Originally Posted by wysota View Post
    How about reimplementing QListView::sort() and do the sorting there (or forward it elsewhere)? What went wrong when you tried to use it?
    Simply these methods are NOT (except QListViewItem::sortChildItems(int, bool) - but it sorts childs of every QListViewItem not QListViewItems) called when user clicks header's column.

    Qt Code:
    1. void QListViewItem::sort()
    2. {
    3. if ( !listView() )
    4. return;
    5. lsc = Unsorted;
    6. enforceSortOrder();
    7. listView()->triggerUpdate();
    8. }
    9.  
    10. void QListViewItem::enforceSortOrder() const
    11. {
    12. QListView *lv = listView();
    13. if ( !lv || lv && (lv->d->clearing || lv->d->sortcolumn == Unsorted) )
    14. return;
    15. if ( parentItem &&
    16. (parentItem->lsc != lsc || parentItem->lso != lso) )
    17. ((QListViewItem *)this)->sortChildItems( (int)parentItem->lsc,
    18. (bool)parentItem->lso );
    19. else if ( !parentItem &&
    20. ( (int)lsc != lv->d->sortcolumn || (bool)lso != lv->d->ascending ) )
    21. ((QListViewItem *)this)->sortChildItems( lv->d->sortcolumn, lv->d->ascending );
    22. }
    23.  
    24. void QListViewItem::sortChildItems( int column, bool ascending )
    25. {
    26. // we try HARD not to sort. if we're already sorted, don't.
    27. if ( column == (int)lsc && ascending == (bool)lso )
    28. return;
    29.  
    30. if ( column < 0 )
    31. return;
    32.  
    33. lsc = column;
    34. lso = ascending;
    35.  
    36. const int nColumns = ( listView() ? listView()->columns() : 0 );
    37.  
    38. // only sort if the item have more than one child.
    39. if ( column > nColumns || childItem == 0 || (childItem->siblingItem == 0 && childItem->childItem == 0))
    40. return;
    41.  
    42. // make an array for qHeapSort()
    43. QListViewPrivate::SortableItem * siblings
    44. = new QListViewPrivate::SortableItem[nChildren];
    45. QListViewItem * s = childItem;
    46. int i = 0;
    47. while ( s && i < nChildren ) {
    48. siblings[i].numCols = nColumns;
    49. siblings[i].col = column;
    50. siblings[i].asc = ascending;
    51. siblings[i].item = s;
    52. s = s->siblingItem;
    53. i++;
    54. }
    55.  
    56. // and sort it.
    57. qHeapSort( siblings, siblings + nChildren );
    58.  
    59. // build the linked list of siblings, in the appropriate
    60. // direction, and finally set this->childItem to the new top
    61. // child.
    62. if ( ascending ) {
    63. for( i = 0; i < nChildren - 1; i++ )
    64. siblings[i].item->siblingItem = siblings[i+1].item;
    65. siblings[nChildren-1].item->siblingItem = 0;
    66. childItem = siblings[0].item;
    67. } else {
    68. for( i = nChildren - 1; i > 0; i-- )
    69. siblings[i].item->siblingItem = siblings[i-1].item;
    70. siblings[0].item->siblingItem = 0;
    71. childItem = siblings[nChildren-1].item;
    72. }
    73. for ( i = 0; i < nChildren; i++ ) {
    74. if ( siblings[i].item->isOpen() )
    75. siblings[i].item->sort();
    76. }
    77. delete[] siblings;
    78. }
    To copy to clipboard, switch view to plain text mode 

    In fact only last method does real sorting. Items were sorted desipte the fact I've reimplemented it.

  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: QListView sorting

    sort() is a method of the LISTVIEW, not of the ITEM.

  5. #5
    Join Date
    Mar 2007
    Posts
    31
    Thanks
    2
    Qt products
    Qt3
    Platforms
    Unix/X11

    Default Re: QListView sorting

    Quote Originally Posted by wysota View Post
    sort() is a method of the LISTVIEW, not of the ITEM.
    I reimplemented it in subclass of QListView.

    Qt Code:
    1. class KMListView : public KListView
    2. {
    3. Q_OBJECT
    4.  
    5. public:
    6. KMListView(QWidget * parent = 0, const char * name = 0);
    7. ~KMListView();
    8.  
    9. void setSelected(QListViewItem * item, bool selected);
    10. void clearSelection();
    11. QListViewItem * selectedItem() const;
    12. void sort();
    13.  
    14. public slots:
    15. void selectAll();
    16.  
    17. signals:
    18. void mouseButtonReleased(const QPoint &);
    19. void keyPressed(QKeyEvent * e);
    20. void rightMouseButtonClicked(const QPoint &);
    21. void sortRequested(const int, const SortOrder);
    22.  
    23. protected:
    24. bool acceptDrag(QDropEvent * event) const;
    25. void contentsMousePressEvent(QMouseEvent * e);
    26. void contentsMouseReleaseEvent(QMouseEvent * e);
    27. void contentsMouseMoveEvent(QMouseEvent * e);
    28. void keyPressEvent(QKeyEvent * e);
    29. void enforceSortOrder() const;
    30.  
    31. private:
    32. bool dndPerm;
    33. };
    To copy to clipboard, switch view to plain text mode 

    Qt Code:
    1. void KMListView::sort()
    2. {
    3. qDebug("sort");
    4.  
    5. emit sortRequested(sortColumn(), sortOrder());
    6. }
    To copy to clipboard, switch view to plain text mode 

    sort() is executed only when I call it:

    Qt Code:
    1. KMListView * lv = new KMListView(this);
    2. lv->sort();
    To copy to clipboard, switch view to plain text mode 

  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: QListView sorting

    Did you enable sorting on the list view? As far as I remember you have to access the header and make it click enabled (I'm not sure though).

  7. #7
    Join Date
    Mar 2007
    Posts
    31
    Thanks
    2
    Qt products
    Qt3
    Platforms
    Unix/X11

    Default Re: QListView sorting

    My settings:

    Qt Code:
    1. lvi->setSelectionMode(QListView::Extended);
    2. lvi->setShowSortIndicator(true);
    3. lvi->setShadeSortColumn(true);
    4. lvi->setResizeMode(QListView::NoColumn);
    5. lvi->setDropVisualizer(false);
    6. lvi->setAllColumnsShowFocus(true);
    To copy to clipboard, switch view to plain text mode 

    Problem is I don't know what actually sorts items! As I mentioned sort() is not called (but QListViewItems are sorted!).

  8. #8
    Join Date
    Jan 2006
    Location
    Somewhere in the middle of the State of New York
    Posts
    7
    Thanks
    4
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QListView sorting

    I think What you want to do is overload the < operator in the List Item.

    This example is from a QT 4.1 QTreeWidgetItem I had to implement sorting on when the TreeView Headers were Clicked, but the Idea should be the Same for the QT3 QListViewItem:

    Qt Code:
    1. bool operator<(const QTreeWidgetItem & other) const
    2. {
    3. int column = treeWidget()->sortColumn();
    4. if ( column == 0 || column == 2 )
    5. {
    6. int thisInt = text(column).toInt();
    7. int otherInt = other.text(column).toInt();
    8. return thisInt < otherInt;
    9. }
    10. // sort date and time columns as one
    11. else if ( column == 3 || column == 4 )
    12. {
    13. QDate thisDate = QDate::fromString(text(3), "yyyy/MM/dd");
    14. QDate otherDate = QDate::fromString(other.text(3), "yyyy/MM/dd");
    15. if ( thisDate == otherDate )
    16. {
    17. QTime thisTime = QTime::fromString(text(4));
    18. QTime otherTime = QTime::fromString(other.text(4));
    19. return thisTime < otherTime;
    20. }
    21. else
    22. {
    23. return thisDate < otherDate;
    24. }
    25. }
    26. else if ( column == 5 )
    27. {
    28. QTime thisTime = QTime::fromString(text(column), "h:mm:ss");
    29. QTime otherTime = QTime::fromString(other.text(column), "h:mm:ss");
    30. return thisTime < otherTime;
    31. }
    32.  
    33.  
    34. return QTreeWidgetItem::operator <(other); //otherwise use base class
    35.  
    36. }//end operator < overload
    To copy to clipboard, switch view to plain text mode 
    "Power, The only Thing Better than Toast" -- Blitzen The Evil Reindeer

  9. #9
    Join Date
    Mar 2007
    Posts
    31
    Thanks
    2
    Qt products
    Qt3
    Platforms
    Unix/X11

    Default Re: QListView sorting

    I can't do it because operator< is part of SortableItem class.

  10. #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: QListView sorting

    At worst you can reimplement compare() from QListViewItem.

  11. #11
    Join Date
    Jan 2006
    Location
    Somewhere in the middle of the State of New York
    Posts
    7
    Thanks
    4
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QListView sorting

    Right,
    Sorry About that, havent used QT3 in a while or QT4, I'm getting rusty
    in QT3 QListView you need to reimplement compare()
    see this thread
    "Power, The only Thing Better than Toast" -- Blitzen The Evil Reindeer

  12. #12
    Join Date
    Mar 2007
    Posts
    31
    Thanks
    2
    Qt products
    Qt3
    Platforms
    Unix/X11

    Default Re: QListView sorting

    I've reimplemented compare in this way:

    Qt Code:
    1. int KMListViewItem::compare(QListViewItem * i, int col, bool ascending) const
    2. {
    3. qDebug("compare()");
    4.  
    5. Q_UNUSED(i);
    6. Q_UNUSED(col);
    7. Q_UNUSED(ascending);
    8.  
    9. return 0;
    10. }
    To copy to clipboard, switch view to plain text mode 

    It should work but it doesn't (items are moved). I think the only solution is to use setSorting(-1) and then use QHeader's setSortIndicator.

  13. #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: QListView sorting

    Try implementing a real compare function. This one is not valid.

  14. #14
    Join Date
    Mar 2007
    Posts
    31
    Thanks
    2
    Qt products
    Qt3
    Platforms
    Unix/X11

    Default Re: QListView sorting

    Quote Originally Posted by fear View Post
    I think the only solution is to use setSorting(-1) and then use QHeader's setSortIndicator.
    I made it this way and now it works! Reimplementing compare() isn't good idea because list view will still iterate over items.

  15. #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

Similar Threads

  1. QListView word wrap
    By serega in forum Qt Programming
    Replies: 17
    Last Post: 30th August 2007, 03:13
  2. Subclass QListView to show two colums in one
    By Mookie in forum Qt Programming
    Replies: 2
    Last Post: 23rd June 2007, 02:12
  3. Items in QListView should sort on Header Click
    By vinnu in forum Qt Programming
    Replies: 14
    Last Post: 10th November 2006, 12:49
  4. How can I disable the QListView Sorting?
    By darpan in forum Qt Programming
    Replies: 3
    Last Post: 27th June 2006, 10:36
  5. [QT4] QTreeView, QAbstractItemModel and sorting
    By KShots in forum Qt Programming
    Replies: 3
    Last Post: 24th March 2006, 20:16

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.