Results 1 to 18 of 18

Thread: QTableView with a checkbox

  1. #1
    Join Date
    Oct 2006
    Posts
    60
    Thanks
    9
    Thanked 3 Times in 3 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11

    Default QTableView with a checkbox

    Is it possible for a QTableView showing a model from a MySQL DB to have a column with checkboxes that get turned into text (Y,N) in the DB? In other words, I would like a column that contains checkboxes instead of having the user have to enter Y or N.

    mAx

  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: QTableView with a checkbox

    Yes. You need to implement a custom delegate which will handle that.

  3. #3
    Join Date
    Oct 2006
    Posts
    3
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QTableView with a checkbox

    You don't need a new delegate for that. In your model, simply react to the Qt::CheckStateRole (in data() and setData() for the appropiate columns).

  4. #4
    Join Date
    Oct 2006
    Posts
    60
    Thanks
    9
    Thanked 3 Times in 3 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11

    Default Re: QTableView with a checkbox

    What do you mean by "react to ...?" I have tried this:

    model->setData(model->index(0, 7), "Y", Qt::CheckStateRole)

    to no avail. I want the checkbox in column 7 which is recorded in the DB as Y or N. Is the above sorta right or do I have to subclass QSqlTableModel and reimplement the data and setdata functions?

    Thanks
    mAx

  5. #5
    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: QTableView with a checkbox

    I'd stick with the delegate thing. Otherwise you'll have to reimplement the model without really needing it. The delegate will give you much more flexibility.

  6. #6
    Join Date
    Oct 2006
    Posts
    60
    Thanks
    9
    Thanked 3 Times in 3 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11

    Default Re: QTableView with a checkbox

    Okay, so I see in the docs how to subclass ItemDelegate and make my own. However, it appears you assign the delegate for the whole view. I only want to change the delegate for one column. How is this accomplished?

    mAx

  7. #7
    Join Date
    Feb 2006
    Location
    Oslo, Norway
    Posts
    6,264
    Thanks
    36
    Thanked 1,519 Times in 1,389 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows Symbian S60 Maemo/MeeGo

    Default Re: QTableView with a checkbox

    Qt 4.2 introduces new functions:


    In Qt 4.1 you'll just have to check the column of the passed model index:
    Qt Code:
    1. void MyItemDelegate::delegateFunction(const QModelIndex& index, ...)
    2. {
    3. if (index.isValid() && index.column() == INTERESTING_COLUMN)
    4. {
    5. // appropriate column in question, do the custom thing
    6. }
    7. else
    8. {
    9. // pass to the base class implementation
    10. QItemDelegate::delegateFunction(index, ...);
    11. }
    12. }
    To copy to clipboard, switch view to plain text mode 
    J-P Nurmi

  8. #8
    Join Date
    Oct 2006
    Posts
    60
    Thanks
    9
    Thanked 3 Times in 3 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11

    Default Re: QTableView with a checkbox

    Okay, thanks for the help I am getting close now. I converted the included exmaple for the sponbox delegate to a checkbox delegate and compiled it and it worked great. However, once I changed the code fome setItemDelegate to setItemDelegateForColumn, it no longer worked at all. Do I need to change something in the example code for the custom delegate to work with just one column? I am using 4.2.

    Thanks
    mAx

  9. #9
    Join Date
    Oct 2006
    Posts
    60
    Thanks
    9
    Thanked 3 Times in 3 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11

    Default Re: QTableView with a checkbox

    Anybody have an idea? I just tried 4.2.1 but no love there either.

    mAx

  10. #10
    Join Date
    Feb 2006
    Location
    Oslo, Norway
    Posts
    6,264
    Thanks
    36
    Thanked 1,519 Times in 1,389 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows Symbian S60 Maemo/MeeGo

    Default Re: QTableView with a checkbox

    Looks like QAbstractItemView::itemDelegateForRow/Column are not used pretty much for anything (yet?)... Anyway, I already gave you a solution which works with old good "normal" delegates.. and it has been discussed earlier..
    J-P Nurmi

  11. #11
    Join Date
    Oct 2006
    Posts
    60
    Thanks
    9
    Thanked 3 Times in 3 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11

    Default Re: QTableView with a checkbox

    Okay, I edited the spinbox example again and with your code it properly displays a checkbox in the first column. However, I tried to use the exact same code in my program and it doesn't work. The column and row headers are present but there is no data, nor checkboxes or even grid lines. What did i do wring?

    Thanks
    mAx

  12. #12
    Join Date
    Feb 2006
    Location
    Oslo, Norway
    Posts
    6,264
    Thanks
    36
    Thanked 1,519 Times in 1,389 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows Symbian S60 Maemo/MeeGo

    Default Re: QTableView with a checkbox

    Does everything work correctly without the custom delegate? Which QItemDelegate functions have you actaully overridden? Did you by any chance override QItemDelegate::paint()?
    J-P Nurmi

  13. #13
    Join Date
    Oct 2006
    Posts
    60
    Thanks
    9
    Thanked 3 Times in 3 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11

    Default Re: QTableView with a checkbox

    Yes, everything works fine if I do not use setItemDelegate. I overrode createEditor, setEditor, setModelData, and updateModelGeometry. As I said before, my code works fine by itself, just not inside my db program.

    Applying the delegate:
    Qt Code:
    1. if(viewInit)
    2. {
    3. model->submitAll();
    4. delete model;
    5. }
    6. int rowCount = 0;
    7. model = new QSqlTableModel();
    8. model->setTable(tableName);
    9. model->setEditStrategy(QSqlTableModel::OnManualSubmit);
    10. model->select();
    11. model->removeColumn(8);
    12. rowCount = model->rowCount();
    13. ui.tableTV->setModel(model);
    14. checkboxDelegate delegate;
    15. ui.tableTV->setItemDelegate(&delegate);
    16. ui.tableTV->resizeColumnToContents(2);
    17. ui.tableTV->hideColumn(0);
    18. ui.tableTV->setEditTriggers(QAbstractItemView::CurrentChanged);
    19. ui.tableTV->setAlternatingRowColors(true);
    20. ui.tableTV->scrollToBottom();
    To copy to clipboard, switch view to plain text mode 

    The delegate:
    Qt Code:
    1. checkboxDelegate::checkboxDelegate(QObject *parent)
    2. : QItemDelegate(parent)
    3. {
    4. }
    5.  
    6. QWidget *checkboxDelegate::createEditor(QWidget *parent,
    7. const QStyleOptionViewItem &option,
    8. const QModelIndex &index) const
    9. {
    10. if(index.isValid() && index.column() == checkboxCol)
    11. {
    12. QCheckBox *editor = new QCheckBox(parent);
    13. editor->installEventFilter(const_cast<checkboxDelegate*>(this));
    14. return editor;
    15. }
    16. else
    17. {
    18. return QItemDelegate::createEditor(parent, option, index);
    19. }
    20. }
    21.  
    22. void checkboxDelegate::setEditorData(QWidget *editor,
    23. const QModelIndex &index) const
    24. {
    25. if(index.isValid() && index.column() == checkboxCol)
    26. {
    27. QString value = index.model()->data(index, Qt::DisplayRole).toString();
    28.  
    29. QCheckBox *checkBox = static_cast<QCheckBox*>(editor);
    30. if(value == "Y")
    31. checkBox->setCheckState(Qt::Checked);
    32. else
    33. checkBox->setCheckState(Qt::Unchecked);
    34. }
    35. else
    36. {
    37. QItemDelegate::setEditorData(editor, index);
    38. }
    39. }
    40.  
    41. void checkboxDelegate::setModelData(QWidget *editor, QAbstractItemModel *model,
    42. const QModelIndex &index) const
    43. {
    44. if(index.isValid() && index.column() == checkboxCol)
    45. {
    46. QCheckBox *checkBox = static_cast<QCheckBox*>(editor);
    47. QString value;
    48. if(checkBox->checkState() == Qt::Checked)
    49. value = "Y";
    50. else
    51. value = "N";
    52.  
    53. model->setData(index, value);
    54. }
    55. else
    56. {
    57. QItemDelegate::setModelData(editor, model, index);
    58. }
    59. }
    60.  
    61. void checkboxDelegate::updateEditorGeometry(QWidget *editor,
    62. const QStyleOptionViewItem &option, const QModelIndex &index) const
    63. {
    64. if(index.isValid() && index.column() == checkboxCol)
    65. editor->setGeometry(option.rect);
    66. else
    67. QItemDelegate::updateEditorGeometry(editor, option, index);
    68.  
    69. }
    To copy to clipboard, switch view to plain text mode 

  14. #14
    Join Date
    Feb 2006
    Location
    Oslo, Norway
    Posts
    6,264
    Thanks
    36
    Thanked 1,519 Times in 1,389 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows Symbian S60 Maemo/MeeGo

    Default Re: QTableView with a checkbox

    Allocate the delegate object on the heap so it won't get destroyed as soon as it gets out of scope:
    Qt Code:
    1. checkboxDelegate* delegate = new checkboxDelegate(this);
    2. ui.tableTV->setItemDelegate(delegate);
    To copy to clipboard, switch view to plain text mode 

    Edit: oops, forgot the important keyword new
    Last edited by jpn; 1st November 2006 at 19:18.
    J-P Nurmi

  15. #15
    Join Date
    Oct 2006
    Posts
    60
    Thanks
    9
    Thanked 3 Times in 3 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11

    Default Re: QTableView with a checkbox

    That did it, thanks alot!!!!

    mAx

  16. #16
    Join Date
    Feb 2007
    Posts
    7
    Thanked 3 Times in 1 Post
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QTableView with a checkbox

    Quote Originally Posted by maxpower View Post
    Is it possible for a QTableView showing a model from a MySQL DB to have a column with checkboxes that get turned into text (Y,N) in the DB? In other words, I would like a column that contains checkboxes instead of having the user have to enter Y or N.

    mAx
    Without delegates:

    Qt Code:
    1. class MyModel : public QSqlQueryModel {
    2. Q_OBJECT
    3. public:
    4. MyModel(QObject *parent = 0);
    5. Qt::ItemFlags flags(const QModelIndex &index) const;
    6. QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
    7. ........
    8. };
    9.  
    10. Qt::ItemFlags MyModel::flags(const QModelIndex &index) const {
    11. Qt::ItemFlags flags = QSqlQueryModel::flags(index);
    12. if (index.column() == aColWithCheckbox)
    13. flags |= Qt::ItemIsUserCheckable;
    14. else
    15. flags |= Qt::ItemIsEditable;
    16. return flags;
    17. }
    18.  
    19. QVariant MyModel::data(const QModelIndex &index, int role) const {
    20. QVariant value = QSqlQueryModel::data(index, role);
    21. if (role == Qt::CheckStateRole && index.column() == aColWithCheckbox)
    22. return (QSqlQueryModel::data(index).toInt() != 0) ? Qt::Checked : Qt::Unchecked;
    23. else
    24. return value;
    25. }
    To copy to clipboard, switch view to plain text mode 

  17. #17
    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: QTableView with a checkbox

    You're changing the model here which is... well... at least controversial when it comes to the MVC paradigm.

    BTW. The model is to be editable so you should subclass QSqlTableModel and also reimplement setData(). Now imagine someone wants to have another view (or access the database through the model) without the checkboxes... Or the column might allow NULLs

    Of course I don't say that you can't do it this way, I only say you should do it with a delegate, as you'll be modifying only the user interaction this way. I wrote about it earlier in the thread.

    Just for completeness - a third way would be to use a proxy model that would translate between the bool and the checkstate role. That would be my second best suggestion (as it doesn't change the source model).

  18. #18
    Join Date
    Feb 2007
    Posts
    7
    Thanked 3 Times in 1 Post
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QTableView with a checkbox

    The bounds between View and Model are the conventionalities... Qt4 provides for changing font, color, alignment in model, so it can be useful.

    For NULLs there is Qt::ItemIsTristate.

    setData needs to be reimplemented of course:
    Qt Code:
    1. bool MyModel::setData(const QModelIndex &index, const QVariant &value, int /* role */) {
    2. if (index.column() ......)
    3. return false;
    4.  
    5. QModelIndex primaryKeyIndex = QSqlQueryModel::index(index.row(), 0);
    6. int id = QSqlQueryModel::data(primaryKeyIndex).toInt();
    7. //clear();
    8. bool ok;
    9. QSqlQuery query;
    10. if (index.column() == 1) {
    11. query.prepare("update employee set name = ? where id = ?");
    12. query.addBindValue(value.toString());
    13. query.addBindValue(id);
    14. .......
    15. }else if(index.column() == aColWithCheck) {
    16. query.prepare("update employee set married = ? where id = ?");
    17. query.addBindValue(value.toInt());
    18. query.addBindValue(id);
    19. }
    20. ok = query.exec();
    21. refresh();
    22. return ok;
    23. }
    To copy to clipboard, switch view to plain text mode 

    ItemIsUserCheckable in flags() and CheckStateRole in data() achieve the interesting feature: checkbox is clicked -> text label is changed in cell.

    Proxy model 'Bool to CheckStateRole' is realy the best i think

    What about 'Qt Cookbook'?

Similar Threads

  1. QTableView sorting
    By gabriels in forum Qt Programming
    Replies: 11
    Last Post: 6th October 2010, 17:13
  2. checkbox
    By nErnie in forum Qt Programming
    Replies: 1
    Last Post: 25th September 2006, 21:59
  3. CheckBox and selection in QTableView
    By Mike Krus in forum Qt Programming
    Replies: 1
    Last Post: 21st September 2006, 20:31
  4. QTableView paints too much
    By Jimmy2775 in forum Qt Programming
    Replies: 2
    Last Post: 26th July 2006, 18:42
  5. Multi-line messages in QTableView
    By Conel in forum Qt Programming
    Replies: 6
    Last Post: 13th April 2006, 13:49

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.