Problems with QSytyledItemDelegate and QStyleOptionProgressBar on macOS
-
Hi All,
the following short application demonstrates the problem (occurs on at least Qt v5.12.10):
#include <QtWidgets> #include <QTimer> class Delegate final : public QStyledItemDelegate { public: explicit Delegate (QObject * parent = nullptr) : QStyledItemDelegate {parent} { } void paint (QPainter * painter, QStyleOptionViewItem const& option , QModelIndex const& index) const { QStyleOptionProgressBar progress_bar_option; progress_bar_option.rect = option.rect; progress_bar_option.state = QStyle::State_Enabled; progress_bar_option.direction = QApplication::layoutDirection (); progress_bar_option.fontMetrics = QApplication::fontMetrics (); progress_bar_option.minimum = 0; progress_bar_option.maximum = 100; auto progress = index.data ().toLongLong (); auto percent = int (progress * 100 / index.data (Qt::UserRole).toLongLong ()); progress_bar_option.progress = percent; progress_bar_option.text = QString::number (percent) + '%'; progress_bar_option.textVisible = true; progress_bar_option.textAlignment = Qt::AlignCenter; QApplication::style ()->drawControl (QStyle::CE_ProgressBar, &progress_bar_option, painter); } }; int main (int argc, char * argv[]) { QApplication a {argc, argv}; QListWidget w; Delegate d; w.setItemDelegate (&d); QListWidgetItem i1 {"Item 1"}; i1.setData (Qt::UserRole, 100); w.addItem (&i1); QListWidgetItem i2 {"Item 2"}; w.addItem (&i2); i2.setData (Qt::UserRole, 100); w.show (); QTimer t; qint64 n1 {0}; qint64 n2 {0}; t.callOnTimeout ([&] { i1.setData (Qt::DisplayRole, (n1 += 2)); i2.setData (Qt::DisplayRole, (n2 += 10)); }); t.start (1000); QObject::connect (&a, &QApplication::lastWindowClosed, &a, &QApplication::quit); return a.exec (); }
On Windows (MinGW) an Linux this works as intended with QProgressBars being used as QListWidgetitem delegates, but on macOS the progress bars get piled on top of each other at the top left of the list widget.
I am looking for a way use progress bar item delegates that look similar on all platforms.
TIA
Bill. -
Hi,
Please try with a more recent version, I remember a fix for drawing in item views.
-
@bsomervi said in Problems with QSytyledItemDelegate and QStyleOptionProgressBar on macOS:
I would expect bug fixes to be back ported
It depends on it's priority and a drawing bug in a style delegate for macos is not very critical I would guess.
-
No, rather the latest 5.15.
-
While waiting for a better solution, you can negate the y value of the
progress_bar_option.rect
. -
Good News!!!
You can just call "QPainter::translate(const QPoint&)" to make it work!if(index.isValid()) { int progress = 50;// 从模型中获取进度值 QStyleOptionProgressBar progress_bar_option; progress_bar_option.rect = option.rect; progress_bar_option.direction = QApplication::layoutDirection(); progress_bar_option.minimum = 0; progress_bar_option.maximum = 100; progress_bar_option.progress = progress; progress_bar_option.text = QString::number(progress) + "%"; progress_bar_option.textAlignment = Qt::AlignCenter; progress_bar_option.textVisible = true; painter->save(); painter->translate(option.rect.topLeft());//change the coordinate system here qobject_cast<QWidget*>(option.styleObject)->style()->drawControl(QStyle::CE_ProgressBar,&progress_bar_option,painter); painter->restore(); }