1

I already have a tree model view that contains columns with a label, text edit, and a check button. What I am trying to add is a push button. Here is where I'm stuck:

  1. In the "flags" function which namespace will I use?
  2. In the "data" function what would be the role of the push button? (for example in the check button case I used the Qt::CheckStateRole)
  3. In the "data" function (which returns a QVariant) what should I return? The button created?

I have looked at other answers regarding this topic and the most popular answer suggested using a setIndexWidget however I am not sure how. Last note, I am attempting to do this programmatically not using the UI designer.

Thank you!

Isabel Inc
  • 1,871
  • 2
  • 21
  • 28
Donia Amer
  • 15
  • 9

1 Answers1

1

Before anything else, you seem a bit confused about how Qt's model/view Framework is working. I suggest you go check Qt documentation about it: http://doc.qt.io/qt-5/model-view-programming.html

The answers to your 3 questions:

  1. You do not need to use any namespaces in Qt::ItemFlags QAbstractItemModel::flags(const QModelIndex &index) const. Just return the particular Qt::ItemFlags (i.e combination of Qt::ItemFlag) which suits your index. This has nothing to do with the fact that you want a QPushButton in your view. I think your are confused by the Qt::ItemIsUserCheckable flag, which make the view display a check box. However that is not what this flag really does, actually it just tells the view to offer a mean for the user to change the Qt::CheckStateRole of the index. The default behaviour of the view is to do it by display a QCheckBox.

  2. There are no roles associated with push buttons. You can use Qt::CheckStateRole or Qt::EditRole, it depends on the method you choose to display the QPushButton.

  3. In QVariant QAbstractItemModel::data(const QModelIndex &index, int role = Qt::DisplayRole) const, when role is Qt::CheckStateRole or Qt::EditRole, you may return a boolean which will control the state of the QPushButton. However, you should NEVER return a QWidget (or derived), the model handles data, not how they are displayed.

A solution: Reimplement QAbstractItemDelegate (or QStyledItemDelegate). Rewrite:

  • createEditor(): create a QPushButton.
  • setEditorData(): set the QPushButton state using the index and the role you used in QAstractItemModel::data().
  • setModelData(): update the model according to the QPushButton state.

Set your delegate on your view (QTreeView::setItemDelegateForColumn()). At this point you will get a push button only when in edition. You can then call QAbstractItemView::openPersistentEditor() to make it always visible.

Benjamin T
  • 8,120
  • 20
  • 37
  • Since you mentioned that I should use the QAbstractItemModel, would I be able to implement it without rewriting my current MTreeModel? – Donia Amer Aug 09 '16 at 14:46
  • QAbstractItemModel is the base class for all model classes, so I'm pretty sure your MTreeModel inherits QAbstractItemModel and therefore everything I said for QAbstractItemModel applies to MTreeModel. – Benjamin T Aug 09 '16 at 15:32
  • Thank you I think I have a better understanding now. I'm not quite sure what the problem is in this error I'm receiving: return value type does not match the function type QWidget colorDelegate :: *createEditor(QWidget * parent, const QStyleOptionViewItem & option, const QModelIndex & index) { QPushButton *button = new QPushButton(const_cast(parent)); button->setText("Push"); return button; } – Donia Amer Aug 09 '16 at 19:05
  • Try `QWidget *colorDelegate::createEditor(QWidget * parent, const QStyleOptionViewItem & option, const QModelIndex & index) { QPushButton *button = new QPushButton(const_cast(parent)); button->setText("Push"); return button; }` – Benjamin T Aug 09 '16 at 19:34