I have been re-writing this project from the bottom up to "correctly" use the Model/View framework. I have a database with several tables. I have set up two views in a QMainWindow, along with a QSqlTableModel for each table I need, and when I need, I just swap a view to a different model and reconfigure columns, etc. That is all working out nicely. I have also managed to subclass QStyledItem to create a combobox to present a list of text entries, display the chosen text entry in the cell, but store its corresponding "id" number in the backend table/database.

I am now attempting to set up some columns with QCheckBox for boolean values, and I am close, but not quite there.

Here's what I have.

cbitemdelegate.h

Qt Code:
  1. #ifndef CBITEMDELEGATE_H
  2. #define CBITEMDELEGATE_H
  3.  
  4. #include <QItemDelegate>
  5.  
  6. class CBItemDelegate : public QItemDelegate
  7. {
  8. Q_OBJECT
  9. public:
  10. explicit CBItemDelegate(QObject *parent = 0);
  11. QWidget *createEditor(QWidget *parent,
  12. const QStyleOptionViewItem &option,
  13. const QModelIndex &index) const;
  14. void setEditorData(QWidget *editor,
  15. const QModelIndex &index) const;
  16. void setModelData(QWidget *editor,
  17. const QModelIndex &index) const;
  18. void updateEditorGeometry(QWidget *editor,
  19. const QStyleOptionViewItem &option,
  20. const QModelIndex &index) const;
  21. void paint(QPainter *painter,
  22. const QStyleOptionViewItem &option,
  23. const QModelIndex &index) const;
  24. };
  25.  
  26. #endif //CBITEMDELEGATE_H
To copy to clipboard, switch view to plain text mode 

cbitemdelegate.cpp

Qt Code:
  1. #include "cbitemdelegate.h"
  2. #include <QApplication>
  3. #include <QtGui>
  4.  
  5. CBItemDelegate::CBItemDelegate(QObject *parent)
  6. : QItemDelegate(parent)
  7. {
  8. }
  9.  
  10. QWidget *CBItemDelegate::createEditor(QWidget *parent,
  11. const QStyleOptionViewItem &option,
  12. const QModelIndex &index) const {
  13. QCheckBox *editor = new QCheckBox(parent);
  14. editor->installEventFilter(const_cast<CBItemDelegate*>(this));
  15. return editor;
  16. }
  17.  
  18. void CBItemDelegate::setEditorData(QWidget *editor,
  19. const QModelIndex &index) const {
  20. int value = index.model()->data(index, Qt::DisplayRole).toInt();
  21.  
  22. QCheckBox *checkBox = static_cast<QCheckBox*>(editor);
  23. if(value == 1)
  24. checkBox->setCheckState(Qt::Checked);
  25. else
  26. checkBox->setCheckState(Qt::Unchecked);
  27. }
  28.  
  29. void CBItemDelegate::setModelData(QWidget *editor,
  30. const QModelIndex &index) const {
  31. QCheckBox *checkBox = static_cast<QCheckBox*>(editor);
  32. int value;
  33. if(checkBox->checkState() == Qt::Checked)
  34. value = 1;
  35. else
  36. value = 0;
  37.  
  38. model->setData(index, value);
  39. }
  40.  
  41. void CBItemDelegate::updateEditorGeometry(QWidget *editor,
  42. const QStyleOptionViewItem &option,
  43. const QModelIndex &index) const {
  44. editor->setGeometry(option.rect);
  45. }
  46.  
  47. void CBItemDelegate::paint(QPainter *painter,
  48. const QStyleOptionViewItem &option,
  49. const QModelIndex &index) const {
  50. bool data = index.model()->data(index, Qt::DisplayRole).toBool();
  51. QStyleOptionButton checkboxstyle;
  52. QRect checkbox_rect = QApplication::style()->subElementRect(QStyle::SE_CheckBoxIndicator, &checkboxstyle);
  53. checkboxstyle.rect = option.rect;
  54. checkboxstyle.rect.setLeft(option.rect.x() + option.rect.width()/2 - checkbox_rect.width()/2);
  55. if(data)
  56. checkboxstyle.state = QStyle::State_On|QStyle::State_Enabled;
  57. else
  58. checkboxstyle.state = QStyle::State_Off|QStyle::State_Enabled;
  59.  
  60. QApplication::style()->drawControl(QStyle::CE_CheckBox, &checkboxstyle, painter);
  61. }
To copy to clipboard, switch view to plain text mode 

I then create an instance to a CBItemDelegate, and use setItemDelegateForColumn to install it to the view.

When I first bring the table up, it looks wonderful, all of the checkboxes are checked/unchecked appropriately, and they are all centered horizontally and vertically in their cells, thanks to the paint procedure.

Then when I click to edit the cells things start to go wrong. The checkbox jumps to the side of the cell, it responds, it is just on the side. I presume it is because in the createEditor function I am creating an actual QCheckBox with its attached (blank) QLabel, and that throws things off. Could somebody please help me past this point?