Results 1 to 12 of 12

Thread: TableView ProxyModel problem

  1. #1
    Join Date
    Aug 2010
    Posts
    107
    Thanks
    5
    Qt products
    Qt4
    Platforms
    Windows

    Question TableView ProxyModel problem

    I have a tableview controlled by a proxy. In the tableview, the highest and lowest values are highlighted through the data function in the proxy. I want the user to be able to delete a selected row (just from the view, not the source!) I have one method almost figured out. The problem is that when a row is deleted, the correct data is not highlighted. I think I need to use mapToSource and mapFromSource, but I haven't been able to get it to work properly.
    This is the method I use...when the user deletes a row, the row is hidden in the tableView, then when the tableview is iterated to find the highest and lowest numbers, the hidden row is skipped. Then the identified rows are sent to the proxy to highlight the correct cells.

    Is this the correct way or is there a better way? How do I get this to work?

    Here is the code for the tableView creation:
    testclass.cpp
    Qt Code:
    1. void TestClass::createTimerTable() // this is called in the constructor of the form
    2. {
    3. testModel= new QSqlRelationalTableModel(this);
    4. testModel->setEditStrategy(QSqlTableModel::OnRowChange);
    5. testModel->setTable("testtable");
    6. testModel->setRelation(2,QSqlRelation("student","id", "LName"));
    7. testModel->setRelation(3,QSqlRelation("testNum", "id","Test"));
    8. testModel->setHeaderData(1,Qt::Horizontal,"Section");
    9.  
    10. proxy = new MyProxyModel (this);
    11. proxy->setSourceModel(testModel);
    12. ui->tableView->setModel(proxy);
    13.  
    14. connect(this,SIGNAL(sendRows(int, int, int, int)),
    15. proxy, SLOT(getRows(int, int, int, int)));
    16.  
    17. //set up tableview
    18. ui->tableView->setItemDelegate(new QSqlRelationalDelegate(this));
    19. ui->tableView->setSelectionMode(QAbstractItemView::SingleSelection);
    20. ui->tableView->setSelectionBehavior(QAbstractItemView::SelectRows);
    21. ui->tableView->setColumnHidden(0,true); // id
    22. ui->tableView->resizeColumnsToContents();
    23. ui->tableView->horizontalHeader()->setStretchLastSection(true);
    24. }
    25.  
    26. void TestClass::updateTimeStats()
    27. {
    28. float totScore=0;
    29. float totReactTime=0;
    30. float lowScore=FLT_MAX;
    31. int rowLowScore=0;
    32. int rowHighScore =0;
    33. int rowSlowReact =0;
    34. int rowFastReact =0;
    35. float slowReactTime =FLT_MIN;
    36. float highScore=FLT_MIN;
    37. float fastReactTime=FLT_MAX;
    38. float currentScore=0;
    39. float currentReactTime =0;
    40. QString string;
    41. int totRows=proxy->rowCount();
    42. if (totRows >0)
    43. {
    44. for (int r=0; r<totRows; r++)
    45. {
    46. if (ui->printView->isRowHidden(r)) //Test if user deleted row
    47. continue;
    48. //QModelIndex sourceIndex=mapToSource(proxy->index(r,2));
    49. //QModelIndex sourceIndex2=mapToSource(proxy->index(r,3));
    50. //the above 2 lines gives a "mapToSource not declared" error
    51. // #include <QModelIndex> is declared
    52. currentScore=proxy->index(r,2).data(Qt::DisplayRole).toFloat();
    53. currentReactTime=proxy->index(r,3).data(Qt::DisplayRole).toFloat();
    54.  
    55. if (currentScore < lowScore)
    56. {
    57. lowScore=currentScore;
    58. rowLowScore=r;
    59. }
    60.  
    61. if (currentScore > highScore)
    62. {
    63. highScore=currentScore;
    64. rowHighScore =r;
    65. }
    66.  
    67. if (currentReactTime > slowReactTime)
    68. {
    69. slowReactTime=currentReactTime;
    70. rowSlowReact =r;
    71. }
    72.  
    73. if (currentReactTime<fastReactTime)
    74. {
    75. fastReactTime=currentReactTime;
    76. rowFastReact =r;
    77. }
    78.  
    79. totTime+=currentTime;
    80. totReactTime+=currentReactTime;
    81.  
    82. }
    83. startModel->select();
    84. }
    To copy to clipboard, switch view to plain text mode 
    myproxymodel.cpp
    Qt Code:
    1. #include "myproxymodel.h"
    2.  
    3. MyProxyModel::MyProxyModel (QObject *parent) :
    4. {
    5.  
    6. }
    7. MyProxyModel::~MyProxyModel()
    8. {
    9.  
    10. }
    11.  
    12. QVariant MyProxyModel::data ( const QModelIndex & index, int role ) const
    13. {
    14. QModelIndex sourceIndex = mapToSource(index);
    15.  
    16. if (!sourceIndex.isValid())
    17. return QVariant();
    18. if (m_slowReactRow<0)
    19. {
    20. if ( sourceIndex.row() == m_highScore && sourceIndex.column()== 2 && role == Qt::BackgroundRole )
    21. {
    22. return QVariant( Qt::yellow );
    23. }
    24. else if ( sourceIndex.row() == m_lowScore && sourceIndex.column()== 2 && role == Qt::BackgroundRole )
    25. {
    26. return QVariant( Qt::red );
    27. }
    28.  
    29. else
    30. {
    31. return QSortFilterProxyModel::data( index, role );
    32. }
    33.  
    34. }
    35. else
    36. {
    37. if ( sourceIndex.row() == m_highScore && sourceIndex.column()== 2 && role == Qt::BackgroundRole )
    38. {
    39. return QVariant( Qt::yellow );
    40. }
    41. else if ( sourceIndex.row() == m_lowScore && sourceIndex.column()== 2 && role == Qt::BackgroundRole )
    42. {
    43. return QVariant( Qt::red );
    44. }
    45. else if (sourceIndex.row()== m_fastReactRow && sourceIndex.column()==3 && role == Qt::BackgroundRole)
    46. {
    47. return QVariant( Qt::yellow );
    48. }
    49. else if ( sourceIndex.row() == m_slowReactRow && sourceIndex.column()== 3 && role == Qt::BackgroundRole )
    50. {
    51. return QVariant( Qt::red );
    52. }
    53. else
    54. {
    55. return QSortFilterProxyModel::data( index, role );
    56. }
    57. }
    58. }
    59. void MyProxyModel::getRows( int rowLow,int rowHigh, int rowSlowReact, int rowFastReact)
    60. {
    61. m_highScore=rowHigh;
    62. m_lowScore=rowLow;
    63. m_slowReactRow= rowSlowReact;
    64. m_fastReactRow= rowFastReact;
    65. }
    To copy to clipboard, switch view to plain text mode 

  2. #2
    Join Date
    Feb 2008
    Posts
    491
    Thanks
    12
    Thanked 142 Times in 135 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11

    Default Re: TableView ProxyModel problem

    I don't understand. Do you have two views? One view where the user hides a row and another that shows the highlighted cells. If so you need to hide the row in the view that displays the proxy also.

    Maybe something like this in your slot where you hide the row would work:
    Qt Code:
    1. QModelIndexList list = view->selectionModel()->selectedRows();
    2. foreach(QModelIndex index, list){
    3. view1->hideRow(index.row()); // view that displays the orgininal data
    4. view2->hideRow(proxy->mapFromSource(queryModel->index(index.row(),0)).row()); // view displaying proxy model
    5. }
    6. highlightCells();
    To copy to clipboard, switch view to plain text mode 

    Or is the user hiding rows in the view showing the proxy?

  3. #3
    Join Date
    Aug 2010
    Posts
    107
    Thanks
    5
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: TableView ProxyModel problem

    There is only one view. The highest and lowest value in a column is highlighted in the view. I want the user to be able to remove a row from the view (without removing it from the source) The problem isn't in hiding the row, it is in highlighting the correct row AFTER a row is hidden.
    I forgot to show the code for hiding the row;
    Qt Code:
    1. void DlgPrintPreview::on_btnDeleteRow_clicked()
    2. {
    3. QModelIndex index = ui->printView->currentIndex();
    4. if (!index.isValid())
    5. return;
    6. ui->printView->setRowHidden(index.row(),true);
    7. highlightCells();
    8.  
    9. }
    To copy to clipboard, switch view to plain text mode 

  4. #4
    Join Date
    Feb 2008
    Posts
    491
    Thanks
    12
    Thanked 142 Times in 135 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11

    Default Re: TableView ProxyModel problem

    What confused me was this in updateTimeStats():
    Qt Code:
    1. if (ui->printView->isRowHidden(r)) //Test if user deleted row
    To copy to clipboard, switch view to plain text mode 
    While in createTimerTable() you have:
    Qt Code:
    1. ui->tableView->setModel(proxy);
    To copy to clipboard, switch view to plain text mode 

    Edit: Attached is a simple app based on one of your earlier (April, I think) posts that demonstrates that what you are trying to do should work.
    Attached Files Attached Files
    Last edited by norobro; 17th August 2011 at 02:09.

  5. #5
    Join Date
    Aug 2010
    Posts
    107
    Thanks
    5
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: TableView ProxyModel problem

    The code you posted did not work properly If you hide the rows in different orders you get varied results from nothing being highlighted to one item not being highlighted until you click on the table. I think this is close. I have to go to work. I will look closer at your code to see if I can figure out why it isn't working quite right...at least when it is highlighting, it is highlighting the correct number!

  6. #6
    Join Date
    Feb 2008
    Posts
    491
    Thanks
    12
    Thanked 142 Times in 135 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11

    Default Re: TableView ProxyModel problem

    On my Linux box the only problem that I experienced was sometimes the highlight didn't show up until the mouse was over the view. Works well otherwise.

    See if this fixes things. Add this statement to the MainWindow constructor:
    Qt Code:
    1. ui->tableView->setSelectionBehavior(QAbstractItemView::SelectRows);
    To copy to clipboard, switch view to plain text mode 
    and add an update at the end of the slot:
    Qt Code:
    1. void MainWindow::pbClicked(){
    2. QModelIndexList list = ui->tableView->selectionModel()->selectedRows();
    3. foreach(QModelIndex index, list){
    4. ui->tableView->hideRow(index.row());
    5. }
    6. highlightCells();
    7. ui->tableView->update();
    8. }
    To copy to clipboard, switch view to plain text mode 

    Edit: Oops. I see what you mean. It doesn't work if the view is sorted by a different column
    Last edited by norobro; 17th August 2011 at 04:43. Reason: updated contents

  7. #7
    Join Date
    Feb 2008
    Posts
    491
    Thanks
    12
    Thanked 142 Times in 135 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11

    Default Re: TableView ProxyModel problem

    I think adding the following statement to the MainWindow ctor and making highlightCells() a slot makes it work properly. The row numbers change on a sort (duh) and need to be rehighlighted.
    Qt Code:
    1. connect(ui->tableView->horizontalHeader(),SIGNAL(sectionClicked(int)),this,SLOT(highlightCells()));
    To copy to clipboard, switch view to plain text mode 
    Attached Files Attached Files

  8. #8
    Join Date
    Aug 2010
    Posts
    107
    Thanks
    5
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: TableView ProxyModel problem

    Thanks....I will try it when I get back home this afternoon!

  9. #9
    Join Date
    Aug 2010
    Posts
    107
    Thanks
    5
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: TableView ProxyModel problem

    It is still not always highlighting the cells after rows are hidden. I tried a couple different things for ui->tableview but I am not sure why sometimes it doesn't work. I will look at it some more tonight.

  10. #10
    Join Date
    Feb 2008
    Posts
    491
    Thanks
    12
    Thanked 142 Times in 135 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11

    Default Re: TableView ProxyModel problem

    Maybe this will solve it:
    Qt Code:
    1. void MainWindow::pbClicked(){
    2. QModelIndexList list = ui->tableView->selectionModel()->selectedRows();
    3. foreach(QModelIndex index, list){
    4. ui->tableView->hideRow(index.row());
    5. }
    6. highlightCells();
    7. // ui->tableView->update();
    8. ui->tableView->setFocus(); // add this
    9. }
    To copy to clipboard, switch view to plain text mode 
    Last edited by norobro; 19th August 2011 at 02:43. Reason: comment out update() line

  11. #11
    Join Date
    Aug 2010
    Posts
    107
    Thanks
    5
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: TableView ProxyModel problem

    That looks like it works!!! I didn't think about setting the focus....Not sure why it needed that but it works. Now to get it to work in my code!

    Thanks a million!

  12. #12
    Join Date
    Aug 2010
    Posts
    107
    Thanks
    5
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: TableView ProxyModel problem

    Works great! I had to modify it a bit for my application, but you got me in the right direction!!! Many thanks!!!

Similar Threads

  1. Custom ProxyModel or Two Sync'd Models ?
    By SSurgnier in forum Qt Programming
    Replies: 2
    Last Post: 2nd August 2011, 18:44
  2. Dragging out of a QTreeView with a ProxyModel
    By jmichiel in forum Newbie
    Replies: 4
    Last Post: 19th June 2011, 19:04
  3. ProxyModel problem
    By waynew in forum Qt Programming
    Replies: 1
    Last Post: 14th February 2010, 06:40
  4. Replies: 2
    Last Post: 6th January 2009, 20:55
  5. tableView Problem
    By hrcariaga in forum Newbie
    Replies: 5
    Last Post: 7th February 2008, 08:29

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.