Results 1 to 6 of 6

Thread: Model/View, Delegates for my Data

  1. #1
    Join Date
    Feb 2016
    Posts
    7
    Thanks
    1
    Qt products
    Qt5
    Platforms
    Windows

    Default Model/View, Delegates for my Data

    Hi,

    I am quite new tho Model/View approach and I need your help. I am reading a text file and want to display data in a tableview. I already looked at example codes but they are very basic and my requirements are very different.

    Text from file looks like:
    Qt Code:
    1. Page Address Name
    2. ....
    3. 1 0000abda _CpuTimer1
    4. 1 0000abe2 _CpuTimer2
    5. 1 0000abea _CpuTimer0
    6. 1 0000abf2 _msg
    7. 1 0000abf4 _res
    8. ....
    To copy to clipboard, switch view to plain text mode 
    I store those information to a QVector of following typedef:
    Qt Code:
    1. typedef struct St_Register
    2. {
    3. QString name;
    4. quint16 page;
    5. quint16 address;
    6. quint32 currValue;
    7. quint32 wrValue;
    8. bool wrProtect;
    9. } Register;
    10. ...
    11. QVector<Register *> Registers;
    To copy to clipboard, switch view to plain text mode 
    But as soon as I store the data into Registers vector, It should update the table automatically.
    I want to show Name, Page, Address, currValue information in the table as not editable strings. I want to show wrProtect as editable checkbox and wrValue as editable spinbox.
    When I check the checkbox, the wrValue should be editable, otherwise not editable.
    So, Is my data-model only this QVector? QVector<Register *> Registers;
    Do I need customized checkbox delegate and spinbox delegate? If yes, how? How can I "connect" those specialized delegates to tableView (or to model)?
    I need a step-by-step instruction for implementing of creating all required classes (pseude-code is enough).

    Thanks.

  2. #2
    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: Model/View, Delegates for my Data

    First, unless you have some specific need, do not use QVector< pointer to thing >. If you do, it means you are responsible for maunally creating and deleting the items in your vector each time the vector content changes. Simply use QVector< thing > (in other words, QVector< Register >) and the Register instances will automatically be created, copied, and go in and out of scope without you having to worry about memory leaks.

    You can use Qt::CheckStateRole to return an enum (as a QVariant) indicating whether the item should be checked or not. If you want the user to be able to edit the check state, then implement the QAbstractItemModel::flags() method to return Qt:ItemFlags that have the Qt::ItemIsUserCheckable bit set.

    For the spin box, you will have to create a custom delegate. The Qt documentation contains an example. You may have to modify this example to support hexadecimal and to disable the ability for a user to type into it, although you could also set it up to allow typing, but then also implement a QValidator to prohibit any non-hex input. See here and QRegularExpressionValidator.

    You will also need to implement QAbstractItemModel::setData() so that these changes are put back into your model.
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

  3. #3
    Join Date
    Feb 2016
    Posts
    7
    Thanks
    1
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Model/View, Delegates for my Data

    Thanks for reply.
    I try checkbox column without a delegate. The column is shown with checkbox but with "true" "false" text as well, as you can see in the attachment. It is only double-clickable.
    I also want to edit chekcbox with only one click. If I click double, it turns to false as in the attachment.
    What I want is: Single-clickable checkbox without true-false text.
    cb.PNG
    cb2.PNG


    Registermodel.cpp
    Qt Code:
    1. .....
    2. QVariant RegisterModel::data(const QModelIndex &index, int role) const
    3. {
    4. int row = index.row();
    5. int col = index.column();
    6.  
    7. switch (role) {
    8. case Qt::DisplayRole:
    9.  
    10. switch (col) {
    11. case 0:
    12. return Registers[row].name; // QString
    13. break;
    14. case 1:
    15. return Registers[row].page; // quint16
    16. break;
    17. case 2:
    18. return QString("%1").arg(Registers[row].address, 8, 16, QChar('0')).toUpper(); // quint32
    19. break;
    20. case 3:
    21. return QString("%1").arg(Registers[row].currValue, 8, 16, QChar('0')).toUpper(); // quint32
    22. break;
    23. case 4:
    24. return Registers[row].wrProtect; // bool
    25. break;
    26. case 5:
    27. return QString("%1").arg(Registers[row].wrValue, 8, 16, QChar('0')).toUpper(); // quint32
    28. break;
    29. default:
    30. return QVariant();
    31. break;
    32. }
    33.  
    34. break;
    35.  
    36. case Qt::TextAlignmentRole:
    37. if(col == 0)
    38. return Qt::AlignLeft;
    39. else
    40. return Qt::AlignRight;
    41. break;
    42.  
    43. case Qt::CheckStateRole:
    44.  
    45. if(col == 4)
    46. {
    47. if(Registers[row].wrProtect == true)
    48. return Qt::Checked;
    49. else
    50. return Qt::Unchecked;
    51. }
    52.  
    53. break;
    54.  
    55. case Qt::FontRole:
    56. if(col != 0)
    57. return QFont("Courier New", 10, QFont::Normal);
    58. break;
    59. default:
    60. return QVariant();
    61. break;
    62. }
    63.  
    64. return QVariant();
    65. }
    66.  
    67. bool RegisterModel::setData(const QModelIndex &index, const QVariant &value, int role)
    68. {
    69. if(role == Qt::EditRole)
    70. {
    71. setElement(index.row(), index.column(), value);
    72. }
    73.  
    74. else if (role == Qt::CheckStateRole)
    75. {
    76.  
    77. if((Qt::CheckState)value.toInt() == Qt::Checked)
    78. {
    79. setElement(index.row(), index.column(), value);
    80. }
    81. }
    82. return true;
    83.  
    84. }
    85.  
    86. Qt::ItemFlags RegisterModel::flags(const QModelIndex &index) const
    87. {
    88. int col = index.column();
    89. if (col == 5)
    90. return Qt::ItemIsEditable | QAbstractTableModel::flags(index);
    91. else if (col == 4)
    92. return Qt::ItemIsUserCheckable | Qt::ItemIsEditable | QAbstractTableModel::flags(index);
    93. else
    94. return QAbstractTableModel::flags(index);
    95. }
    96.  
    97. ....
    To copy to clipboard, switch view to plain text mode 

    Do I need custom delegate? If yes how?

  4. #4
    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: Model/View, Delegates for my Data

    If you don't want the words "true" or "false", then you need to return QVariant() for the column 4 DisplayRole instead of "wrProtect", which the table will convert to "true" or "false".

    The reason a double-click is needed is that for the table, the first click selects the item and activates the editor, the second click changes its state. You might be able to change this behavior by retrieving the QItemSelectionModel for the table view and connecting a slot to the QItemSelectionModel::currentChanged() signal. If the new current index is for column 4, change the state of the check box by changing the model and emitting dataChanged().
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

  5. #5
    Join Date
    Feb 2016
    Posts
    7
    Thanks
    1
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Model/View, Delegates for my Data

    I added QVariant to the code but the table still displays boolean as ture or false.

    Qt Code:
    1. QVariant RegisterModel::data(const QModelIndex &index, int role) const
    2. {
    3. ...
    4. case 4:
    5. return QVariant(Registers[row].wrProtect); // bool
    6. break;
    7. ...
    8.  
    9. case Qt::CheckStateRole:
    10.  
    11. if(col == 4)
    12. {
    13.  
    14. if(Registers[row].wrProtect == true)
    15. {
    16. return QVariant(Qt::Checked);
    17. }
    18. else
    19. {
    20. return QVariant(Qt::Unchecked);
    21. }
    22. }
    23. ...
    24. }
    To copy to clipboard, switch view to plain text mode 

    I want to use delegate. When I double-click the cell a new checkbox appers on the left in the cell. Checkbox is not displayed when I don't click.

    checkboxdelegate.h

    Qt Code:
    1. #ifndef CHECKBOXDELEGATE_H
    2. #define CHECKBOXDELEGATE_H
    3.  
    4. #include <QStyledItemDelegate>
    5. #include <QTableView>
    6. #include <QObject>
    7. #include <QDebug>
    8. #include <QCheckBox>
    9.  
    10. #define DEB qDebug().noquote() <<
    11.  
    12. class CheckBoxDelegate : public QStyledItemDelegate
    13. {
    14. Q_OBJECT
    15. public:
    16. explicit CheckBoxDelegate(QObject *parent = 0);
    17. QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const;
    18. void setEditorData(QWidget *editor, const QModelIndex &index) const;
    19. void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const;
    20. QRect CheckBoxRect(const QStyleOptionViewItem &view_item_style_options) const;
    21. void updateEditorGeometry(QWidget *editor,
    22. const QStyleOptionViewItem &option,
    23. const QModelIndex &index) const;
    24. void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
    25.  
    26. mutable QCheckBox *checkBox;
    27.  
    28. private slots:
    29. void setData(bool value);
    30. };
    31.  
    32. #endif // CHECKBOXDELEGATE_H
    To copy to clipboard, switch view to plain text mode 

    checkboxdelegate.cpp
    Qt Code:
    1. #include "checkboxdelegate.h"
    2. #include <QComboBox>
    3. #include <QCheckBox>
    4. #include <QRect>
    5. #include <QPainter>
    6. #include <QSpinBox>
    7. #include <QApplication>
    8. #include <QSignalMapper>
    9. #include "booleanwidget.h"
    10.  
    11. CheckBoxDelegate::CheckBoxDelegate(QObject *parent) :
    12. QStyledItemDelegate(parent)
    13. {
    14. }
    15.  
    16.  
    17. QWidget* CheckBoxDelegate::createEditor( QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index ) const
    18. {
    19.  
    20. checkBox = new QCheckBox(parent);
    21. QObject::connect(checkBox, SIGNAL(toggled(bool)), this, SLOT(setData(bool)));
    22. return checkBox;
    23. }
    24.  
    25. void CheckBoxDelegate::setEditorData ( QWidget *editor, const QModelIndex &index ) const
    26. {
    27.  
    28. if(QCheckBox *cb = static_cast<QCheckBox *>(editor)) {
    29.  
    30. bool checked = index.model()->data(index, Qt::DisplayRole /* Qt::EditRole */).toBool();
    31. DEB "Checked: " << checked;
    32. cb->setChecked(checked);
    33. }
    34. }
    35.  
    36. void CheckBoxDelegate::setModelData ( QWidget *editor, QAbstractItemModel *model, const QModelIndex &index ) const
    37. {
    38.  
    39. if(QCheckBox *cb = static_cast<QCheckBox *>(editor))
    40. // save the current text of the combo box as the current value of the item
    41. model->setData(index, cb->isChecked());
    42. else
    43. QStyledItemDelegate::setModelData(editor, model, index);
    44. }
    45.  
    46.  
    47. void CheckBoxDelegate::updateEditorGeometry(QWidget *editor,
    48. const QStyleOptionViewItem &option,
    49. const QModelIndex &index) const {
    50.  
    51. editor->setGeometry(option.rect);
    52. }
    53.  
    54. void CheckBoxDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const {
    55. }
    56.  
    57. void CheckBoxDelegate::setData(bool value)
    58. {
    59. emit commitData(checkBox);
    60. }
    To copy to clipboard, switch view to plain text mode 

    What am I missing?

  6. #6
    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: Model/View, Delegates for my Data

    I added QVariant to the code but the table still displays boolean as ture or false.
    No, I meant return literally "QVariant()" (an empty QVariant instance). Returning QVariant( Qt::Checked ) still results in the table seeing a Boolean value instead of nothing.

    Checkbox is not displayed when I don't click.
    I think you are misunderstanding what a delegate does. Delegates are -only- used when editing an item in a table or tree view. When the editing is finished, the editor is destroyed and the model is updated. So if you create a checkbox delegate, it will be displayed only when you are actually editing the cell with the Boolean item, otherwise it will not be visible.

    If you want something to be visible all of the time, you will have to implement the paint() method to draw the checkbox -image-.

    Personally, I think you are chasing this too far. You don't need a delegate for checkboxes, since QTableView already provides one. Did you try my suggestion of connecting a slot to the QItemSelectionModel?
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

Similar Threads

  1. Replies: 8
    Last Post: 16th July 2015, 19:44
  2. Replies: 1
    Last Post: 24th February 2011, 05:54
  3. Model / View and data structures
    By laszlo.gosztola in forum Newbie
    Replies: 0
    Last Post: 2nd December 2010, 05:13
  4. How to identify data from the model in the view?
    By csmithmaui in forum Qt Programming
    Replies: 8
    Last Post: 17th April 2010, 08:52
  5. data, model and tree view
    By larry104 in forum Qt Programming
    Replies: 17
    Last Post: 3rd July 2006, 14:43

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.