@SRaD
Look, think in a tree model setted up as below example:
Item A (0,0,0)
Item 1 (0,0,1)
Item P1 (0,0,2)
Item P2 (1,0,2)
Item P3 (2,0,2)
Item 2 (1,0,1)
Item P1 (0,0,2)
Item P2 (1,0,2)
Item P3 (2,0,2)
Item 3 (2,0,1)
Item P1 (0,0,2)
Item P2 (1,0,2)
Item P3 (2,0,2)
Note: Each child has a Z Level depending of their parent but the value of (X,Y) is reseted for each append.
To set the Progressbar if the element is grandchild, you could to calculate the Z Level using the Parent of this element.
Example:
void ProgressDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
const QModelIndex &index ) const // override
{
int z = 0;
for(QModelIndex parentIndex = index.parent(); parentIndex.isValid(); z++){
parentIndex = parentIndex.parent();
}
if (index.column() == 0 && z==2)
{
QStyleOptionProgressBar progressBarOption;
progressBarOption.state = QStyle::State_Enabled;
progressBarOption.direction = QApplication::layoutDirection();
progressBarOption.rect = option.rect;
progressBarOption.fontMetrics = QApplication::fontMetrics();
progressBarOption.minimum = 0;
progressBarOption.maximum = 100;
bool isNumber;
int number = index.data(Qt::DisplayRole).toInt(&isNumber);
if(isNumber){
progressBarOption.progress = number;
}
progressBarOption.textAlignment = Qt::AlignCenter;
progressBarOption.textVisible = true;
QApplication::style()->drawControl(QStyle::CE_ProgressBar,
&progressBarOption, painter);
}
else
QStyledItemDelegate::paint(painter, option, index);
}
QStandardItemModel *model = new QStandardItemModel(0,1,this);
model->setHorizontalHeaderItem(0, new QStandardItem("Main Column"));
ProgressDelegate *delegate = new ProgressDelegate(this);
ui->treeView->setItemDelegate(delegate);
ui->treeView->setModel(model);
QStandardItem *ia;
QStandardItem *i1,*i2,*i3;
QStandardItem *p1,*p2,*p3;
// (Row , Column , Z Level)
ia = new QStandardItem("Item A"); // (0,0,0)
i1 = new QStandardItem("Item 1"); // (0,0,1)
p1 = new QStandardItem("15"); // (0,0,2)
p2 = new QStandardItem("30"); // (1,0,2)
p3 = new QStandardItem("12"); // (2,0,2)
i1->appendRow(p1);
i1->appendRow(p2);
i1->appendRow(p3);
ia->appendRow(i1);
i2 = new QStandardItem("Item 2"); // (1,0,1)
p1 = new QStandardItem("35"); // (0,0,2)
p2 = new QStandardItem("77"); // (1,0,2)
p3 = new QStandardItem("12"); // (2,0,2)
i2->appendRow(p1);
i2->appendRow(p2);
i2->appendRow(p3);
ia->appendRow(i2);
i3 = new QStandardItem("Item 3"); // (2,0,1)
p1 = new QStandardItem("7"); // (0,0,2)
p2 = new QStandardItem("22"); // (1,0,2)
p3 = new QStandardItem("85");// (2,0,2)
i3->appendRow(p1);
i3->appendRow(p2);
i3->appendRow(p3);
ia->appendRow(i3);
model->appendRow(ia); // (0,0,0)
Result
[image: a58c7a44-9830-483c-80d6-72c49aaede3a.png]
But this solution has a processing overhead to calculate the Z Level using the For Loop each time that paint event is called, so, seriously, the best solution is calculate the Z Level when the Data is appended on Model.
Pseudo-code - when insert the data or changing the root:
if has parent then
Data[Z_Role] := parent_z_level + 1
else
Data[Z_Role] := 0
You could easily get the Z Level on Delegate with this functionality
// Z_Role = Qt::UserRole+1
int zLevel = index.data(Qt::UserRole+1).toInt()