Results 1 to 7 of 7

Thread: QTableView switching currentIndex not performing as expected

  1. #1
    Join Date
    Aug 2008
    Posts
    38
    Thanks
    15
    Qt products
    Qt4
    Platforms
    Windows

    Default QTableView switching currentIndex not performing as expected

    Hello all,
    I have composed a simple compilable example to demonstrate the following issue.
    When I click in the tableView, if I am in column 0 I want it to switch selection to column 1 ->This works ok
    I installed an EventFilter on the tableView and check for certain keys (Left, Right, Up, and Down) for table navigation, I catch them and emit a signal, which calls the same slot as table->SIGNAL(clicked(QModelIndex)) and this appears to get in the spot to move the selection, but it doesn't actually set the true currentIndex (at least not from what I see).

    Wondering if anyone out there could give me a hand with this, as it seems it should be very straightforward...
    file:main.cpp
    Qt Code:
    1. #include <QtGui/QApplication>
    2. #include "mainwindow.h"
    3.  
    4. int main(int argc, char *argv[])
    5. {
    6. QApplication a(argc, argv);
    7. MainWindow w;
    8. w.show();
    9.  
    10. return a.exec();
    11. }
    To copy to clipboard, switch view to plain text mode 
    file: mainwindow.cpp
    Qt Code:
    1. #include "mainwindow.h"
    2.  
    3. MainWindow::MainWindow(QWidget *parent)
    4. : QMainWindow(parent)
    5. {
    6. table = new QTableView(this);
    7. model = new QStandardItemModel(this);
    8. table->setModel(model);
    9. table->installEventFilter(this);
    10.  
    11. //populate model with data...
    12. for(int i=0;i<5; i++)
    13. {
    14. for(int j=0; j<2; j++)
    15. {
    16. QString text = "row: "+QString::number(i) + "/col: "+QString::number(j);
    17. QStandardItem *item = new QStandardItem(QString(text));
    18. model->setItem(i,j,item);
    19. }
    20. }
    21. table->resizeRowsToContents();
    22. table->resizeColumnsToContents();
    23. table->setFixedSize(300,400);
    24. QVBoxLayout *vbl = new QVBoxLayout(this);
    25. vbl->addWidget(table,1);
    26. setLayout(vbl);
    27. setFixedSize(800,600);
    28. connect(table,SIGNAL(activated(QModelIndex)),this,SLOT(updateDesc(QModelIndex)));
    29. connect(table,SIGNAL(clicked(QModelIndex)),this,SLOT(updateDesc(QModelIndex)));
    30. connect(this,SIGNAL(updateFromArrow(QModelIndex)),this,SLOT(updateDesc(QModelIndex)));
    31. }
    32. bool MainWindow::eventFilter(QObject *o, QEvent *e)
    33. {
    34. if(o == table && e->type() == QEvent::KeyPress)
    35. {
    36. //key was pressed on param detail selection...
    37. int row = table->currentIndex().row();
    38. int col = table->currentIndex().column();
    39. int rowCnt = model->rowCount()-1;
    40. int colCnt = model->columnCount()-1;
    41. QKeyEvent *keyEv = static_cast <QKeyEvent*> (e);
    42. if(keyEv->key() == Qt::Key_Left)
    43. {
    44. qDebug()<<"Key LEFT";
    45. if(col != 0)
    46. emit updateFromArrow(model->index(row,col-1));
    47. else
    48. emit updateFromArrow(model->index(row,col));
    49. }//end if key left
    50. else if(keyEv->key() == Qt::Key_Right)
    51. {
    52. if(col != colCnt)
    53. emit updateFromArrow(model->index(row,col+1));
    54. else
    55. emit updateFromArrow(model->index(row,col));
    56. }//end keyright
    57. else if(keyEv->key() == Qt::Key_Up)
    58. {
    59. if(row != 0)
    60. emit updateFromArrow(model->index(row-1,col));
    61. else
    62. emit updateFromArrow(model->index(row,col));
    63. }//end if key up
    64. else if(keyEv->key() == Qt::Key_Down)
    65. {
    66. if(row != rowCnt)
    67. emit updateFromArrow(model->index(row+1,col));
    68. else
    69. emit updateFromArrow(model->index(row,col));
    70. }//end if key down
    71. }
    72. return false;
    73.  
    74. }
    75. void MainWindow::updateDesc(QModelIndex mi)
    76. {
    77. qDebug()<<"tree Clicked: row:"<<mi.row()<<"col:"<<mi.column()<<"curindxCol:"<<table->currentIndex().column();
    78. QModelIndex m = model->index(mi.row(),mi.column());
    79. if(mi.column() == 0) //if we are in first column, then jump to 2nd column <-works on clicking, not on keypress from eventFilter
    80. {
    81. qDebug()<<"Changing index, in col 0 for param";
    82. m = model->index(mi.row(),1);
    83. //table->selectionModel()->select(table->model()->index(mi.row(),1), QItemSelectionModel::ClearAndSelect);
    84. table->setCurrentIndex(m);
    85.  
    86. }
    87.  
    88. }
    89.  
    90. MainWindow::~MainWindow()
    91. {
    92.  
    93. }
    To copy to clipboard, switch view to plain text mode 
    finally file: mainwindow.h
    Qt Code:
    1. #ifndef MAINWINDOW_H
    2. #define MAINWINDOW_H
    3.  
    4. #include <QtGui/QMainWindow>
    5. #include <QtGui>
    6.  
    7.  
    8. class MainWindow : public QMainWindow
    9. {
    10. Q_OBJECT
    11.  
    12. public:
    13. MainWindow(QWidget *parent = 0);
    14. ~MainWindow();
    15. QTableView *table;
    16. signals:
    17. void updateFromArrow(QModelIndex);
    18. public slots:
    19. void updateDesc(QModelIndex);
    20.  
    21. protected:
    22. bool eventFilter(QObject *o, QEvent *e);
    23. };
    24.  
    25. #endif // MAINWINDOW_H
    To copy to clipboard, switch view to plain text mode 

    Thanks to all who can help with this!
    AlphaWolfXV - and Have a happy new year!
    Attached Files Attached Files

  2. #2
    Join Date
    Mar 2009
    Location
    Brisbane, Australia
    Posts
    7,534
    Thanks
    13
    Thanked 1,576 Times in 1,505 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows
    Wiki edits
    17

    Default Re: QTableView switching currentIndex not performing as expected

    Is this suitable?
    Qt Code:
    1. class TableView: public QTableView {
    2. Q_OBJECT
    3. public:
    4. explicit TableView(QWidget *p = 0): QTableView(p) { }
    5.  
    6. protected slots:
    7. void currentChanged(const QModelIndex &current, const QModelIndex &previous) {
    8. QTableView::currentChanged(current, previous);
    9. if (current.isValid() && current.column() == 0) {
    10. QModelIndex index = current.sibling(current.row(), 1);
    11. setCurrentIndex(index);
    12. // Or, to move the current item without changing the selected items
    13. // selectionModel()->setCurrentIndex(index, QItemSelectionModel::NoUpdate);
    14. }
    15. }
    16. };
    To copy to clipboard, switch view to plain text mode 

    You might want to make the column zero items not selectable in the model also.
    Last edited by ChrisW67; 30th December 2013 at 23:22. Reason: Forgot to call superclass implementation

  3. The following user says thank you to ChrisW67 for this useful post:

    AlphaWolfXV (31st December 2013)

  4. #3
    Join Date
    Aug 2008
    Posts
    38
    Thanks
    15
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: QTableView switching currentIndex not performing as expected

    Hello,
    Thank you so much for the response. I think I must be confusing something, this works for mouse clicking, it forces back to column 1. However, still on the arrow key behavior I get a dotted line surrounding the column 1 but the selection is still on column 0. Either way this gives me a lot of information to go on. Thank you for that, I missed that I had to implement the superclass to get the desired behavior.
    Thank you so much!
    AlphaWolfXV


    Added after 11 minutes:


    I made a qDebug to illustrate the behavior is working like it should, just the selection is not updating - I believe the index is correct, just the cell selected is not correct with the key events...
    Qt Code:
    1. void currentChanged(const QModelIndex &current, const QModelIndex &previous) {
    2. qDebug()<<"cR:"<<current.row()<<"cC:"<<current.column()<<"pR:"<<previous.row()<<"pC:"<<previous.column();
    3. QTableView::currentChanged(current, previous);
    4. if (current.isValid() && current.column() == 0) {
    5. qDebug()<<"wow, we need to change it..."<<current.row()<<current.column();
    6. QModelIndex index = current.sibling(current.row(), 1);
    7. setCurrentIndex(index);
    8.  
    9. // Or, to move the current item without changing the selected items
    10. //selectionModel()->setCurrentIndex(index, QItemSelectionModel::NoUpdate);
    11. }
    12. }
    13. };
    To copy to clipboard, switch view to plain text mode 
    Capture5.jpg
    Last edited by AlphaWolfXV; 31st December 2013 at 02:56.

  5. #4
    Join Date
    Mar 2009
    Location
    Brisbane, Australia
    Posts
    7,534
    Thanks
    13
    Thanked 1,576 Times in 1,505 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows
    Wiki edits
    17

    Default Re: QTableView switching currentIndex not performing as expected

    The current item and the selection are two different things. Depending on the selectionMode() and selectionBehavior() set on the view you might get this behaviour regarding the state of the selection after setting the current item, and you might not. That is why I suggested you might want to make the column zero items not selectable in the model to avoid any possibility of them getting into the selection.


    If your requirement is that clicking on column 0 sets the currentIndex() but adds the item in column1 to the selection then you have to code that slightly differently.

  6. The following user says thank you to ChrisW67 for this useful post:

    AlphaWolfXV (31st December 2013)

  7. #5
    Join Date
    Aug 2008
    Posts
    38
    Thanks
    15
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: QTableView switching currentIndex not performing as expected

    Hello again,
    Thank you for your help. I will review the docs with the different selection modes/behaviors to see what I can come up with. I appreciate all the help, and the push in the right direction.
    Just to be clear, to make the column 0 non selectable, we use the item->setSelectable() correct? In other words, make all the items in col 0 not selectable?

    Finally just to clarify the end goal, i wanted the view to only select values(items) in column 1. If they click in column 0, the code supplied above works wonderfully. If they arrow key over (Left) to column 0, the selection box stays in col 0 even though I can tell it updates the current index as it is supposed to. I was hoping that when the user hits "left" arrow on keyboard it would "bounce" to col 0 and immediately back to col 1... Not a huge deal, I will continue looking into it.

    Again, thank you for all your kind help!
    AlphaWolfXV

  8. #6
    Join Date
    Mar 2009
    Location
    Brisbane, Australia
    Posts
    7,534
    Thanks
    13
    Thanked 1,576 Times in 1,505 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows
    Wiki edits
    17

    Default Re: QTableView switching currentIndex not performing as expected

    With an underlying QStandardItemModel yes, you would use item->setSelectable(false) on every item in column zero. In your own QAbstractItemModel subclass you would arrange the equivalent in your QAbstractItemModel::flags() implementation.

  9. The following user says thank you to ChrisW67 for this useful post:

    AlphaWolfXV (31st December 2013)

  10. #7
    Join Date
    Aug 2008
    Posts
    38
    Thanks
    15
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: QTableView switching currentIndex not performing as expected

    Perfect, I will give that a try. Thank you again for your help,
    AlphaWolfXV

Similar Threads

  1. Invalid QSqlRecord after performing another query to DB
    By crew4ok in forum Qt Programming
    Replies: 2
    Last Post: 27th April 2012, 01:18
  2. Replies: 6
    Last Post: 5th May 2010, 23:25
  3. Replies: 3
    Last Post: 12th December 2009, 08:51
  4. QDir entryList performing slowly
    By bunjee in forum Qt Programming
    Replies: 3
    Last Post: 8th October 2009, 16:21
  5. QTableView not working as expected.
    By junxuan in forum Qt Programming
    Replies: 7
    Last Post: 30th July 2009, 08:17

Tags for this Thread

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.