dynamic qtreeview with custom delegates

南楼画角 提交于 2019-12-11 05:18:23

问题


I'm using Qt 5.6 and my goal is to develop a dynamic tree using QTreeView that needs to populate items such as combo boxes, edit box, checkbox, buttons..etc depending on the settings loaded and the tree data can change as new data is loaded. There will be many nodes to populate in the tree with parent and child nodes.

I've read about different options to implement this type of treeview such as populating a QTreeView and implementing my own delegate by inheriting from QITemDelegate or QStyledItemDelegate or using Qt Quick's QML treeview.

For my purposes I've chosen the first option to dynamically populate a tree and modify parameters but I'm having trouble setting the delegate i want for a selected cell only as the only options to set the delegate in the tree is to setItemDelegateForRow, setItemDelegateForColumn or setItemDelegate. The tree will look something like the below. How should i set a different delegate for each of the child nodes?

by (col, row)

Parent(cell 0,0)
  ->Child(cell 0,1) -combo box(1,1)
  ->Child(cell 0,2) -button(1,2)
  ->Child(cell 0,3) -check box(1,3)
 ...
 ...etc

Parent(cell 0,10)
  ->Child(cell 0,11) - edit box(1,11)
  ->Child(cell 0,12) - edit box(1,12)
  ->Child(cell 0,13) - check box(1,13)
 ...
 ...etc

Edit

This is a simplified version of how I have setup my tree view so far. Found out the answer to why my child node column 1 was not showing was because i did not set the column count of the model. I have updated the code below and it works now.

enum EditType
{
    TYPE_Text,
    TYPE_CheckBox,
    TYPE_ComboBox,
    TYPE_Button
};

QTreeView* tree = new QTreeView(this);
QStandardItemModel* model = new QStandardItemModel; 
model->setColumnCount(2);
tree->setModel(model);

//set custom delegate for column 1 of the tree 
CustomDelegate *customDelegate = new CustomDelegate(this);
tree->setItemDelegateForColumn(1, customDelegate); 

// Add parent nodes
QStandardItem* parent1 = new QStandardItem(tr("parent1"));
QStandardItem* parent2 = new QStandardItem(tr("parent2"));

model->appendRow(parent1);
model->appendRow(parent2);

// add a child
QList<QStandardItem*> childrow;
QStandardItem* child = new QStandardItem(tr("child1"));
childrow.append(child);
QStandardItem* child_value = new QStandardItem();
child_value->setData(TYPE_ComboBox, Qt::UserRole);
childrow.append(child_value);
parent1->appendRow(it_child);

回答1:


As you can see from QAbstractItemView documentation, there is only methods for set delegate for
whole view, for columns or for rows. As you noticed, this methods are: setItemDelegate, setItemDelegateForColumn, setItemDelegateForRow. That's why you can not set delegate for certain cell.

There is another way, you can use for showing different widgets in QTreeView - method SetIndexWidget of QAbstractItemView. But you must keep in mind that:

This function should only be used to display static content within the visible area corresponding to an item of data. If you want to display custom dynamic content or implement a custom editor widget, subclass QItemDelegate instead.

Use SetIndexWidget method is very "expensive" and if you have many rows in you QTreeView, you can see performance degradation.

Addition: If you need widgets in QTreeView only for edit data items from your model, the best way to solve you problem will be reimplement QStyledItemDelegate. Look for method createEditor.

Addition: Example of reimplement QStyledItemDelegate



来源:https://stackoverflow.com/questions/37972839/dynamic-qtreeview-with-custom-delegates

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!