Unsolved want to add a graphic to a table
-
@mzimmers Hi,
If you want only to color the background, just return the color from the
data()
method of your model using theQt::BackgroundRole
, and the percentage value usingQt::DisplayRole
. -
@mzimmers
Here is an example of reimplementation of a QStyledItemDelegate drawing a progress bar usingQStyleOptionProgressBar
. It may help you to make your own custom delegate. I think this is pretty close to what you are trying to achieve//.h #ifndef PROGRESSBARITEMDELEGATE_H #define PROGRESSBARITEMDELEGATE_H #include <QStyledItemDelegate> class ABSTRACTTASK_SHARED_EXPORT ProgressBarItemDelegate : public QStyledItemDelegate { public: ProgressBarItemDelegate(QObject *parent = 0); ~ProgressBarItemDelegate(); QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const; protected: virtual void paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const; }; #endif // PROGRESSBARITEMDELEGATE_H //.cpp #include "progressbaritemdelegate.h" #include "taskfuturemodel.h" #include <QAbstractItemView> #include <QApplication> #include <QDebug> #include <QFontMetrics> ProgressBarItemDelegate::ProgressBarItemDelegate(QObject *parent) : QStyledItemDelegate(parent){} ProgressBarItemDelegate::~ProgressBarItemDelegate() {} QSize ProgressBarItemDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const { QSize sizeHint = QStyledItemDelegate::sizeHint(option, index); QFont font; QFontMetrics fm(font); int width = qMax(20, fm.width(index.data(MyModel::ProgressTextRole).toString())); //qDebug() << "ProgressBarItemDelegate::sizeHint: " << sizeHint; sizeHint.setWidth(width); //qDebug() << "ProgressBarItemDelegate::sizeHint updated: " << sizeHint; return sizeHint; } void ProgressBarItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const { //Possible alternative using stylesheet //https://stackoverflow.com/questions/10630360/customized-color-on-progressbar-delegate if (index.column() == MyModel::COL_PROGRESS_VALUE) { int progress = index.data().toInt(); bool failed = progress == -2; int min = 0; //Set undeterminate progress in case of -1 value int max = progress == -1 ? 0 : 100; QString result; //Get min & max values from the model data const QAbstractItemModel *model = view->model(); if(model){ min = index.data(MyModel::ProgressMinRole).toInt(); max = index.data(MyModel::ProgressMaxRole).toInt(); result = index.data(MyModel::ResultRole).toString(); } if(result == "Failed") failed = true; QString progressText = index.data(TaskFutureModel::ProgressTextRole).toString(); QStyleOptionProgressBar progressBarOption; progressBarOption.rect = option.rect; progressBarOption.minimum = min; progressBarOption.maximum = max; progressBarOption.progress = qMin(progress, progressBarOption.maximum); progressBarOption.text = progressText; progressBarOption.textVisible = true; progressBarOption.textAlignment = Qt::AlignCenter; if(failed || result == "Failed"){ progressBarOption.palette.setColor(QPalette::Highlight, QColor("red")); } else if(result == "Aborted"){ progressBarOption.palette.setColor(QPalette::Highlight, QColor("orange")); } else { progressBarOption.palette.setColor(QPalette::Highlight, QColor("#blue")); } if((min == 0 && max == 0 )|| progress == -1){ progressBarOption.palette.setColor(QPalette::HighlightedText, QColor("white")); progressBarOption.palette.setColor(QPalette::WindowText, QColor("white")); } QApplication::style()->drawControl(QStyle::CE_ProgressBar, &progressBarOption, painter); } else QStyledItemDelegate::paint(painter, option, index); }
Usage:
ui->tvTasks->setItemDelegateForColumn(<Column_Index>, new ProgressBarItemDelegate(myTableView));
-
@Gojir4 thank you so much for the example. I've copied your code into my project. I'm getting an error about ABSTRACTTASK_SHARED_EXPORT, and I can't find anything online about that keyword. Can you tell me what it's used for?
-
Hi,
It's a custom macro based on the Creating Shared Libraries chapter in Qt's documentation.
-
Oh, OK, so I can probably skip it, then?
-
If you have that class directly in your application project, yes.
-
@mzimmers Sorry I forgot to remove this keyword from my code.
-
@mzimmers
Just as a note.
Very small small sample of delegate here.
https://forum.qt.io/topic/96545/insert-fill-circle-into-cell-of-qtablewidget/8
notice VRonin comment. -
One more note: This
QAbstractItemView *view = qobject_cast<QAbstractItemView *>(parent());
is unsafe as hell. Nothing says the delegate should be a child of the view. in fact you can use the same delegate in multiple views. the correct way to get the model isindex.model()
without passing from the view -
@VRonin said in want to add a graphic to a table:
in fact you can use the same delegate in multiple views.
You shouldn't though. There's a warning in the docs about it. I second your parent warning, however, it's quite correct as the view does not take ownership of the delegate.
-
@VRonin said in want to add a graphic to a table:
One more note: This
QAbstractItemView *view = qobject_cast<QAbstractItemView *>(parent());
is unsafe as hell. Nothing says the delegate should be a child of the view. in fact you can use the same delegate in multiple views. the correct way to get the model isindex.model()
without passing from the viewThanks for signaling the issue. I have fixed my sample code above.