Results 1 to 12 of 12

Thread: QTableView sorting

  1. #1
    Join Date
    Feb 2006
    Posts
    3
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default QTableView sorting

    Hi,

    I use Qt v4.0.1 (OpenSource) on the Win XP.
    My app query some rows from the mysql server and show it into the QTableView.
    What I want is to sort the QTableView when the header column is clicked.
    I tried to use this slot but it didn't work :

    void QTableView::sortByColumn ( int column ) [slot]
    ( Sorts the model by the values in the given column.)

    Can anybody help me or give me some suggestions, please?
    Thanks,
    Gabriel S

    These are parts of my code :
    .............

    QTableView *tableView = new QTableView(WindMaincall);
    QSqlQueryModel *model = new QSqlQueryModel(tableView);

    connect(tableView->horizontalHeader(),SIGNAL(sectionClicked(int)), tableView, SLOT(sortByColumn(int)));
    ...................
    model->setQuery( "SELECT field1,field2 FROM table1" );
    tableView->setModel(model);

  2. #2
    Join Date
    Jan 2006
    Location
    Scandinavia
    Posts
    62
    Thanks
    5
    Thanked 2 Times in 1 Post
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QTableView sorting

    What do you mean that it didn't work? Can you provide some more info?

    --- I haven't tried that function on QTableView, but I've tried it's 'cousin' function on QTableWidget
    void QTableWidget::sortItems ( int column, Qt::SortOrder order = Qt::AscendingOrder )
    Sorts all the rows in the table widget based on column and order.


    And that worked w/out any problems (similar to your code)

  3. #3
    Join Date
    Jan 2006
    Location
    Belgium
    Posts
    99
    Thanks
    1
    Thanked 3 Times in 3 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows Symbian S60 Maemo/MeeGo

    Default Re: QTableView sorting

    have you used
    setClickable(true) on your QHeaderView?

    cheers

  4. #4
    Join Date
    Feb 2006
    Posts
    3
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QTableView sorting

    Thanks to KjellKod and Everal,

    The problem is that when the header of the QTableView is clicked, the slot sortByColumn which is
    the receiver from the signal "sectionClicked" it doesn't do anything.

    I can't use the QTableWidget instead of QTableView, because I must use the QSqlQueryModel as a "data source " for the QTableView.

    After I have take a loock on the Qt sorces I think that I found the problems:
    On the qtableview.cpp I found this :

    void QTableView::sortByColumn(int column)
    {
    Q_D(QTableView);

    if (!d->model)
    return;
    bool ascending = (horizontalHeader()->sortIndicatorSection() == column
    && horizontalHeader()->sortIndicatorOrder() == Qt:escendingOrder);
    Qt::SortOrder order = ascending ? Qt::AscendingOrder : Qt:escendingOrder;
    horizontalHeader()->setSortIndicator(column, order);
    d->model->sort(column, order);
    }


    So, this metod call the model->sort(column,order) of the QSqlQUeryModel (in my case).
    Loocking on the documentation from the QSqlQueryModel::sort (...), I found this :

    *!
    Sorts the model by \a column in the given \a order.

    The base class implementation does nothing.
    */
    void QAbstractItemModel::sort(int column, Qt::SortOrder order)
    {
    Q_UNUSED(column);
    Q_UNUSED(order);
    // do nothing
    }

    It seems than I must subclassing the sort method...but I don't beleive than to sort a QTableView can be so complicated ..

    Thanks ,
    Gabriel Strimtu

  5. #5
    Join Date
    Jan 2006
    Location
    Belgium
    Posts
    99
    Thanks
    1
    Thanked 3 Times in 3 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows Symbian S60 Maemo/MeeGo

    Default Re: QTableView sorting

    Qt Code:
    1. model->setQuery( "SELECT field1,field2 FROM table1" );
    To copy to clipboard, switch view to plain text mode 
    You are using not more than 1 table so QSqlTableModel fits your needs?

    instead of
    QSqlQueryModel *model = new QSqlQueryModel(tableView);
    you could use
    QSqlTableModel *model = new QSqlTableModel(tableView);
    which has
    void QSqlTableModel::sort ( int column, Qt::SortOrder order ) [virtual]
    implemented

    Cheers

  6. #6
    Join Date
    Feb 2006
    Posts
    3
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QTableView sorting

    Qt Code:
    1. model->setQuery( "SELECT field1,field2 FROM table1" );
    To copy to clipboard, switch view to plain text mode 

    Thanks Everall,

    No, I 'must to use 3 tables on my sql query and for this reason I can't use the QSQlTableModel.Sorry for my wrong SELECT, was just an bad example.
    I solve the problem using now the QTableWidget insted of QTableView but I should write code to populate it.
    The good news is that in order to sort the QTableWidget I just call :
    Qt Code:
    1. void setSortingEnabled ( bool enable )
    To copy to clipboard, switch view to plain text mode 
    and it is sorted. No more code is necessary

    I'm sorry for the unimplemented sort metod of the QSqlQueryModel..I think that is a gap .

    Regards,
    Gabriel Strimtu

  7. #7
    Join Date
    Mar 2006
    Posts
    1
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QTableView sorting

    Hi

    Using Qt 4.1.3 (release, linux)

    The actual problem is in QTableView.
    It is not possible to enable sorting in QTableView as the actual connect to sortByColumn is made in QTableWidget and not in QtableView.
    If you compare this with QTreeView, you'll notice that these connects are moved to QTreeView.
    This should be done by Trolltech guys as well for QTableView.
    Just compare code difference in qt source where they connect sortByColumn and you'll understand.

    BTW: When using sort function in your widget you'll notice that the sort works fine in QTableView. Only the connections when clicking the header are made at the wrong place (In QTableWidget instead of in QTableView).

    I hope this explains the original problem in this topic.
    And I hope they come with a fix. By the way I did not check snapshot code to see if it is already fixed.

    Greetzzzzzz

    Bart

  8. #8
    Join Date
    Apr 2010
    Location
    Denmark
    Posts
    3
    Qt products
    Qt3 Qt4
    Platforms
    Windows

    Default Re: QTableView sorting

    No it is not that complicated, but the name of the class states it is an abstract type as in QAbstractItemModel.

    I guess that is the reason why most of the methods have empty implementations or left as pure abstracts.
    Alternatively tried to subclass from QStandardItemModel or another more appropriate model if such exists.

    Please take a look at the following url

    http://cep.xor.aps.anl.gov/software/...c86413b4fa648e

    Qt Code:
    1. {
    2. QVector<QPair<QTableWidgetItem*, int> > sortable;
    3. QVector<int> unsortable;
    4.  
    5. sortable.reserve(rowCount());
    6. unsortable.reserve(rowCount());
    7.  
    8. for (int row = 0; row < rowCount(); ++row) {
    9. if (QTableWidgetItem *itm = item(row, column))
    10. sortable.append(QPair<QTableWidgetItem*,int>(itm, row));
    11. else
    12. unsortable.append(row);
    13. }
    14.  
    15. LessThan compare = (order == Qt::AscendingOrder ? &itemLessThan : &itemGreaterThan);
    16. qStableSort(sortable.begin(), sortable.end(), compare);
    17.  
    18. emit layoutAboutToBeChanged();
    19.  
    20. QVector<QTableWidgetItem*> sorted_table(tableItems.count());
    21. QModelIndexList from;
    22. QModelIndexList to;
    23. for (int i = 0; i < rowCount(); ++i) {
    24. int r = (i < sortable.count()
    25. ? sortable.at(i).second
    26. : unsortable.at(i - sortable.count()));
    27. for (int c = 0; c < columnCount(); ++c) {
    28. QTableWidgetItem *itm = item(r, c);
    29. sorted_table[tableIndex(i, c)] = itm;
    30. from << createIndex(r, c, 0);
    31. to << createIndex(i, c, 0);
    32. }
    33. }
    34.  
    35. tableItems = sorted_table;
    36. changePersistentIndexList(from, to); // ### slow
    37.  
    38. emit layoutChanged();
    39. }
    To copy to clipboard, switch view to plain text mode 

    Please notice the text snippet below taken from the API description.

    Important signals Code:
    1. ** void QAbstractItemModel::layoutAboutToBeChanged() [signal]
    2. Since: 4.2
    3. This signal is emitted just before the layout of a model is changed.
    4. Components connected to this signal use it to adapt to changes in the model's layout.
    5.  
    6. Subclasses should update any persistent model indexes after emitting layoutAboutToBeChanged().
    7.  
    8. ** void QAbstractItemModel::layoutChanged() [signal]
    9. This signal is emitted whenever the layout of items exposed by the model has changed;
    10. for example, when the model has been sorted. When this signal is received by a view,
    11. it should update the layout of items to reflect this change. When subclassing
    12. QAbstractItemModel or QAbstractProxyModel, ensure that you emit layoutAboutToBeChanged()
    13. before changing the order of items or altering the structure of the data you expose to
    14. views, and emit layoutChanged() after changing the layout.
    15.  
    16. Subclasses should update any persistent model indexes before emitting layoutChanged().
    To copy to clipboard, switch view to plain text mode 

    Hth
    Last edited by jessn; 27th April 2010 at 13:43. Reason: missing [code] tags, added example
    Jess Nielsen
    Technical Architect

  9. #9

    Default Re: QTableView sorting

    How to visualize model data in different way in QTableView

    Hi All. I have a model containing in one column floats (ex: 22.7). Now, I want that in QTableView, it will be visualized together with the unit (MB): 22.7 MB. The reason I am doing so is because I want that sorting is based on floats, but the visualization is as I said with units. I created a Model, a Filter and a View. But it does not work. Here is a piece of my code:

    QStandardItemModel* model = new QStandardItemModel(this);
    QSortFilterProxyModel *filterModel = new QSortFilterProxyModel(0);
    filterModel->setSourceModel(model);

    QStandardItem* vSItem6 = new QStandardItem();
    vSItem6->setData(22.7, Qt:isplayRole);
    model->setItem(1, 7, vSItem6);
    QModelIndex index = model->index(1, 7, QModelIndex());
    QString itext = model->data(index, Qt:isplayRole).toString();
    filterModel->setData(index, itext + " MB", Qt:isplayRole);

    mUi.tableView->setModel(filterModel);
    mUi.tableView->setSortingEnabled(true);
    mUi.tableView->show();

    Everything seems to be fine, but in QTableView, only the float number is visualized (without the unit MB). In internet everybody is saying to use proxy models, delegates, ... but nobody shows how to do it.
    The only way seems to be to write own proxy models and delegates, but I want avoid it. There should be for sure a simple way.
    Can anybody please help me? Thanks

  10. #10
    Join Date
    Jan 2009
    Posts
    31
    Thanks
    8
    Qt products
    Qt4
    Platforms
    MacOS X Windows

    Default Re: QTableView sorting

    Have a look at QSortFilterProxyModel, add's a wrapper onto standard models that allows sorting.

  11. #11
    Join Date
    Oct 2010
    Location
    Grenoble, France
    Posts
    3
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QTableView sorting

    Hi QTBeginner.

    You can do that without a filter model.
    Just use Qt:isplayRole AND Qt::UserRole.

    Try that :

    QStandardItemModel* model = new QStandardItemModel(this);
    model->setSortRole(Qt::UserRole);

    QStandardItem* vSItem6 = new QStandardItem();
    vSItem6->setData("22.7 MB", QtisplayRole); // To be seen in the view
    vSItem6->setData(22.7, Qt:UserRole); // To be use in sorting model
    model->setItem(1, 7, vSItem6);

    mUi.tableView->setModel(model);
    mUi.tableView->setSortingEnabled(true);
    mUi.tableView->show();

    Bye
    Last edited by Davton; 6th October 2010 at 16:12.

  12. #12
    Join Date
    Aug 2009
    Location
    Belgium
    Posts
    310
    Thanks
    10
    Thanked 31 Times in 25 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: QTableView sorting

    Hi gabriels,

    I use a tableview on a sqlquery, and I add a SORT statement to my SQL clause when the user presses a column header. It's a lot of work, because you have to see what column header is pressed, what field this relates to, modify the SQL statement, requery the query, ...

    But it works. Also I remember the 3 last columns pressed, so a user can sort first by column 1, then column 2, ... etc.

    Regards,
    Marc

Similar Threads

  1. Refresh QTableView after sorting
    By araglin in forum Newbie
    Replies: 4
    Last Post: 18th December 2008, 23:13
  2. QTableView sorting when using a model
    By steg90 in forum Qt Programming
    Replies: 2
    Last Post: 12th June 2008, 14:13
  3. QTableView sorting problem
    By noktus in forum Newbie
    Replies: 11
    Last Post: 23rd April 2008, 11:20
  4. QSqlTableModel and QTableView and sorting
    By JeanC in forum Qt Programming
    Replies: 1
    Last Post: 5th April 2008, 14:22
  5. Sorting QTableView
    By Jimmy2775 in forum Qt Programming
    Replies: 7
    Last Post: 9th February 2006, 17:47

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.