Results 1 to 8 of 8

Thread: QTableWidget + setCellWidget - controlling tab order

  1. #1
    Join Date
    Sep 2009
    Posts
    13
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default QTableWidget + setCellWidget - controlling tab order

    I've been trying for some time now to make QTableWidget behave the way I want it.
    I have a few MyTableWidgets (which inherit from QTableWidget) on the one tab. I modified QTableWidget so it would display in the first (and as for now only) row QLineEdits (to be precise it displays my class inheriting from QLineEdit) using QTableWidget::setCellWidget().
    Now I would like to traverse through all MyTableWidgets on this tab.
    If I have only a one column (so it's also the only cell in MyTableWidget) when I press Tab it goes to the next MyTableWidget (and I've reimplemented focusInEvent so the first cell in this MyTableWidget gets the focus). When I press Tab again and again it loops through all cells in the only row in this MyTableWidget, but never leaves MyTableWidget and I don't know where to change this behavior.
    So my question is how to change QTableWidget so that after pressing Tab in the last cell it will go to the next widget not first cell (and shift+tab in the first cell to go to the previous widget)?

    From all I read it appears I should do something by reimplementing focusNextPrevChild( bool), but I just can't get it to work properly.

    edit:
    I think I found the solution:
    Qt Code:
    1. bool MyTableWidget::focusNextPrevChild( bool next )
    2. {
    3. std::cout << "focusNextPrev " << qPrintable(objectName()) << std::endl;
    4. if( next )
    5. {
    6. if( currentColumn() == m_model->columnCount() - 1 )
    7. return QWidget::focusNextPrevChild(next);
    8. return false;
    9. }
    10. else
    11. {
    12. if( currentColumn() == 0 )
    13. return QWidget::focusNextPrevChild(next);
    14. return false;
    15. }
    16.  
    17.  
    18. return QTableWidget::focusNextPrevChild(next);
    19. }
    20.  
    21.  
    22. void MyTableWidget::focusInEvent( QFocusEvent * e)
    23. {
    24. switch( e->reason() )
    25. {
    26. case Qt::BacktabFocusReason:
    27. cellWidget(0, m_model->columns().count()-1)->setFocus();
    28. break;
    29. case Qt::TabFocusReason:
    30. default:
    31. cellWidget(0,0)->setFocus();
    32. break;
    33. }
    34. }
    To copy to clipboard, switch view to plain text mode 
    As far as I checked it does work, though I'm not sure it's entirely correct.
    Last edited by elmo; 13th September 2009 at 14:00.

  2. #2
    Join Date
    Sep 2009
    Posts
    13
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QTableWidget + setCellWidget - controlling tab order

    So after some playing around it appears it doesn't work as it should.
    I have:

    main.cpp
    Qt Code:
    1. #include <QGroupBox>
    2. #include <QApplication>
    3. #include <QHBoxLayout>
    4. #include <QVBoxLayout>
    5.  
    6. #include <MyTable.h>
    7.  
    8. int main(int argc, char *argv[])
    9. {
    10. QApplication app(argc, argv);
    11.  
    12. QWidget *window = new QWidget();
    13. QVBoxLayout *layout = new QVBoxLayout();
    14.  
    15. {
    16. QGroupBox * box = new QGroupBox(window);
    17. QHBoxLayout * sublay = new QHBoxLayout();
    18. sublay->addWidget( new MyTable(box));
    19. box->setLayout(sublay);
    20.  
    21. layout->addWidget(box);
    22. }
    23.  
    24. { /* same as above */
    25. QGroupBox * box = new QGroupBox(window);
    26. QHBoxLayout * sublay = new QHBoxLayout();
    27. sublay->addWidget( new MyTable(box));
    28. box->setLayout(sublay);
    29.  
    30. layout->addWidget(box);
    31. }
    32.  
    33. { /* same as above */
    34. QGroupBox * box = new QGroupBox(window);
    35. QHBoxLayout * sublay = new QHBoxLayout();
    36. sublay->addWidget( new MyTable(box));
    37. box->setLayout(sublay);
    38.  
    39. layout->addWidget(box);
    40. }
    41.  
    42. window->setLayout(layout);
    43. window->show();
    44.  
    45. return app.exec();
    46. }
    To copy to clipboard, switch view to plain text mode 

    MyTable.h
    Qt Code:
    1. #include <QTableWidget>
    2. #include <QFocusEvent>
    3. #include <QEvent>
    4. #include <QLineEdit>
    5.  
    6. #include <iostream>
    7.  
    8. class MyTable : public QTableWidget
    9. {
    10. Q_OBJECT
    11.  
    12. public:
    13. MyTable( QWidget * parent = 0) : QTableWidget(parent)
    14. {
    15. setColumnCount(7);
    16. setRowCount(1);
    17.  
    18. for(unsigned int i = 0; i < columnCount(); ++i)
    19. {
    20. setCellWidget(0, i, new QLineEdit(this));
    21. }
    22. }
    23.  
    24. bool focusNextPrevChild( bool next )
    25. {
    26. QWidget::focusNextPrevChild(next);
    27. }
    28. };
    To copy to clipboard, switch view to plain text mode 

    The code above is compilable.
    To compile:
    Qt Code:
    1. moc MyTable.h -o MyTable.cpp
    2. g++ MyTable.cpp main.cpp `pkg-config QtGui --cflags --libs` -I . -o table
    To copy to clipboard, switch view to plain text mode 


    First question: shouldn't this work like this: when I press tab it goes to the next MyTable widget?
    Because I thought that if I call directly QWidget::focusNextPrevChild(bool) it will treat MyTable as any other QWidget which can have focus, so it should navigate through all three MyTables not going into cells.

  3. #3
    Join Date
    Sep 2009
    Posts
    13
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QTableWidget + setCellWidget - controlling tab order

    Another attempt:

    MyTable.h:
    Qt Code:
    1. #include <QTableWidget>
    2. #include <QFocusEvent>
    3. #include <QEvent>
    4. #include <QLineEdit>
    5.  
    6. #include <iostream>
    7.  
    8. class MyTable : public QTableWidget
    9. {
    10. Q_OBJECT
    11.  
    12. public:
    13. MyTable( QWidget * parent = 0) : QTableWidget(parent)
    14. {
    15. setColumnCount(7);
    16. setRowCount(1);
    17.  
    18. for(unsigned int i = 0; i < columnCount(); ++i)
    19. {
    20. QWidget * e = new QLineEdit(this);
    21. setCellWidget(0, i, e);
    22. e->setFocusPolicy( Qt::ClickFocus );
    23. }
    24. }
    25.  
    26. bool event( QEvent * e )
    27. {
    28. switch( e->type() )
    29. {
    30. case QEvent::KeyPress:
    31. e->accept();
    32. QKeyEvent *ke = (QKeyEvent *) e;
    33. QObject *p = parent();
    34. bool res = true;
    35.  
    36. switch( ke->key() )
    37. {
    38. case Qt::Key_Backtab:
    39. res = focusNextPrevChild(false);
    40. break;
    41. case Qt::Key_Tab:
    42. res = focusNextPrevChild(true);
    43. break;
    44. }
    45. return res;
    46. }
    47.  
    48. return QTableWidget::event(e);
    49. }
    50.  
    51. void focusInEvent( QFocusEvent *e )
    52. {
    53. switch( e->reason() )
    54. {
    55. case Qt::BacktabFocusReason:
    56. setCurrentCell(0, columnCount()-1);
    57. break;
    58. case Qt::TabFocusReason:
    59. default:
    60. setCurrentCell(0,0);
    61. break;
    62. }
    63. }
    64.  
    65. bool focusNextPrevChild( bool next )
    66. {
    67. if( next )
    68. {
    69. if( currentColumn() < columnCount() - 1 )
    70. {
    71. setCurrentCell( 0, currentColumn() + 1);
    72. return true;
    73. }
    74. }
    75. else if( currentColumn() > 0 )
    76. {
    77. setCurrentCell( 0, currentColumn() - 1);
    78. return true;
    79. }
    80.  
    81. return false;
    82. }
    83.  
    84. };
    To copy to clipboard, switch view to plain text mode 

    I don't know why this works only one way: when pressing tab it loops as it should. But when I press Shift+Tab ( = Key_Backtab) it loops inside one MyTable. Why does it behave like that?

  4. #4
    Join Date
    Jan 2008
    Location
    Poland
    Posts
    687
    Thanks
    4
    Thanked 140 Times in 132 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: QTableWidget + setCellWidget - controlling tab order

    ANd why do you need QTableWidget? If you want to place several QLineEdits in a row use QHBoxLayout. In more than one row use QGridLayout.
    I would like to be a "Guru"

    Useful hints (try them before asking):
    1. Use Qt Assistant
    2. Search the forum

    If you haven't found solution yet then create new topic with smart question.

  5. #5
    Join Date
    Sep 2009
    Posts
    13
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QTableWidget + setCellWidget - controlling tab order

    Quote Originally Posted by faldżip View Post
    ANd why do you need QTableWidget? If you want to place several QLineEdits in a row use QHBoxLayout. In more than one row use QGridLayout.
    1. I would like it to look like a grid ( possibly with vertical header, but horizontal header is a must) and user has to have the ability to resize columns when "grabbing" in between two header cells.
    2. I would like to know what's going on and how to control tab traversal order (as I can't find anything in the docs and I can't google anything useful).

  6. #6
    Join Date
    Jan 2008
    Location
    Poland
    Posts
    687
    Thanks
    4
    Thanked 140 Times in 132 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: QTableWidget + setCellWidget - controlling tab order

    QLabels with QSplitters and QLineEdits could be your header and a whole view. You can even make it in Designer when you can easily set the tab order
    I would like to be a "Guru"

    Useful hints (try them before asking):
    1. Use Qt Assistant
    2. Search the forum

    If you haven't found solution yet then create new topic with smart question.

  7. #7
    Join Date
    Sep 2009
    Posts
    13
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QTableWidget + setCellWidget - controlling tab order

    Quote Originally Posted by faldżip View Post
    QLabels with QSplitters and QLineEdits could be your header and a whole view. You can even make it in Designer when you can easily set the tab order
    Hm... QSpliters. Haven't noticed that. I think I will go with that idea, but still I would like to know how the heck can I control tab traversal order.

  8. #8
    Join Date
    Sep 2009
    Posts
    13
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QTableWidget + setCellWidget - controlling tab order

    Quote Originally Posted by elmo View Post
    still I would like to know how the heck can I control tab traversal order.
    Bump. Really noone has a clue on how to control tab order with QTableWidget/View?

Similar Threads

  1. set Tab Order in a QTableWidget
    By jfe in forum Qt Programming
    Replies: 1
    Last Post: 18th January 2008, 12:55
  2. Replies: 10
    Last Post: 9th July 2007, 22:02
  3. Replies: 1
    Last Post: 26th February 2006, 05:52

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.