Results 1 to 6 of 6

Thread: QTableView, Model/View, QCheckBox

  1. #1
    Join Date
    Jan 2011
    Posts
    32
    Thanks
    6
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default QTableView, Model/View, QCheckBox

    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?

  2. #2
    Join Date
    Jan 2011
    Posts
    32
    Thanks
    6
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: QTableView, Model/View, QCheckBox

    Bump.

    Could someone verify that I am taking the "proper" approach with what I am doing here?

    I have experimented with moving the widget in the updateEditorGeometry call, but when I do, it seems that the coordinate system suddenly switches from the cell the item is in, to the table the item is in (i.e. if I move the widget in the third row to (10, 2) it does move, but to (10, 2) relative to the view window, down in cell 0, 0). I could set up to calculate the proper global position based on row/column, etc. But it seems to me that there ought to be a cleaner way.

  3. #3
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,230
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: QTableView, Model/View, QCheckBox

    Won't QAbstractItemView::visualRect( const QModelIndex & ) return you the rect you need, without having to compute the location yourself? The table cells themselves aren't widgets, and when the editor is created it is positioned relative to the table (likely using visualRect()).

  4. The following user says thank you to d_stranz for this useful post:

    lxman (6th July 2011)

  5. #4
    Join Date
    Jan 2011
    Posts
    32
    Thanks
    6
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: QTableView, Model/View, QCheckBox

    Yep, that did the trick! Thanks d_stranz. For the record, I couldn't call QAbstractItemView::visualRect(const QModelIndex &) as a static function (which I tried first). So in the constructor for the delegate, I am passing in the QTableView instance as parent, then I can call visualRect(const QModelIndex &) as I need to on it.

    Works beautifully!

  6. #5
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,230
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: QTableView, Model/View, QCheckBox

    I didn't mean to imply that QAbstractItemView::visualRect() was a static method; I gave the full declaration so you would know where it could be found in the class inheritance hierarchy.

  7. #6
    Join Date
    Jan 2011
    Posts
    32
    Thanks
    6
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: QTableView, Model/View, QCheckBox

    And my implication wasn't meant to imply that you were implying that QAbstractItemView::visualRect() was a static method. I was the one who misunderstood. I just put a note so that any other newbie's like myself might be able to avoid the same mistake. That's all.

    Again, thanks much for the help.

Similar Threads

  1. Replies: 1
    Last Post: 24th February 2011, 05:54
  2. Replies: 3
    Last Post: 23rd February 2011, 09:27
  3. QTableView - model / view pattern - layout, edit
    By vlastagf in forum Qt Programming
    Replies: 4
    Last Post: 1st August 2009, 22:42
  4. Model/View framework: streaming data in a QTableView
    By yannickt in forum Qt Programming
    Replies: 6
    Last Post: 24th October 2008, 00:06
  5. Replies: 9
    Last Post: 7th November 2006, 15:10

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.