How to update progress bar in delegate?
-
I have a TreeViewDelegate that is derived from QStyledItemDelegate. In this view, in a specific row and column I have a progress bar that now appears but, I'm not clear on how to update the progress bar from outside the delegate.
Can anyone offer some advice?
void MyTreeViewDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const { QModelIndex parent = index.parent(); if (parent.row() < 0) { if (index.column() == 1 && index.row() == 1) { 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; progressBarOption.textAlignment = Qt::AlignCenter; progressBarOption.textVisible = true; bool is_number; int progress = index.data(Qt::DisplayRole).toInt(&is_number); if (is_number) progressBarOption.progress = progress < 0 ? 0 : progress; progressBarOption.text = QString::asprintf("%d%% Complete", progressBarOption.progress); QApplication::style()->drawControl(QStyle::CE_ProgressBar, &progressBarOption, painter); } } QStyledItemDelegate::paint(painter, option, index); return; }
-
Hi,
If you properly call dataChanged when modifying your model content, your progress bars should be updated automatically.
-
I guess I'm not clear on how that works. I now have the following ...
void MyTreeViewDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const { QModelIndex parent = index.parent(); if (parent.row() < 0) { if (index.column() == 1 && index.row() == 1) { 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; progressBarOption.textAlignment = Qt::AlignCenter; progressBarOption.textVisible = true; int progress = cars_processed; progressBarOption.progress = progress < 0 ? 0 : progress; progressBarOption.text = QString::asprintf("%d%% Complete", progressBarOption.progress); QApplication::style()->drawControl(QStyle::CE_ProgressBar, &progressBarOption, painter); } } QStyledItemDelegate::paint(painter, option, index); return; }
And say I have 100 cars. So in my MainWindow I have this ...
for (auto& car : cars) { ++cars_processed; }
As I increment the number of cars_processed, how do I immediately tell the paint function above to update the progress bar?
-
As already suggested: you have to update your model content and ensure that
dataChanged
is called.Then, if you are updating your model in a tight loop, you might now see updates on your GUI because you are blocking the event loop.