How to draw styled text in QStyledItemDelegate
-
Hi,
I need to reimplement
QStyledItemDelegate
'spaint
method due to specific reasons of drawing different item parts based on index data, which may affect decoration and text rectangle position, but with ability of using stylesheet if itemDataRoles are not set.Everything is working well, due to using
QStyleCommon
'sdrawPrimitive
in most of cases. But the text field and it's colors seems to be impossible to implement for me.QPalette
stored inoption
or inQTreeView
widget (stored inoption.widget
) does not include style colors for the item. Is there way how to "get palette for QTreeView item?" or "draw styled text with entering text value, rectangle and states?".Thanks for reading, happy for answer.
-
You can just use
QStyle::drawItemText
. Below I show 2 examples, one just fixes the text and usesdrawControl
, the other manually writes the text usingdrawItemText
(ignore thesizeHint
implementations)#include <QApplication> #include <QStyledItemDelegate> #include <QStandardItemModel> #include <QStylePainter> #include <QListView> #include <QFontMetrics> class FixTextDelegate : public QStyledItemDelegate{ Q_DISABLE_COPY(FixTextDelegate) public: using QStyledItemDelegate::QStyledItemDelegate; void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override { Q_ASSERT(index.isValid()); QStyleOptionViewItem opt = option; initStyleOption(&opt, index); opt.text = opt.text + QChar(' ') + index.data(Qt::UserRole).toString(); const QWidget *widget = option.widget; QStyle *style = widget ? widget->style() : QApplication::style(); style->drawControl(QStyle::CE_ItemViewItem, &opt, painter, widget); } QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override { QVariant value = index.data(Qt::SizeHintRole); if (value.isValid()) return qvariant_cast<QSize>(value); QStyleOptionViewItem opt = option; initStyleOption(&opt, index); opt.text = opt.text + QChar(' ') + index.data(Qt::UserRole).toString(); const QWidget *widget = option.widget; QStyle *style = widget ? widget->style() : QApplication::style(); return style->sizeFromContents(QStyle::CT_ItemViewItem, &opt, QSize(), widget); } }; class ManualTextDelegate : public QStyledItemDelegate{ Q_DISABLE_COPY(ManualTextDelegate) public: using QStyledItemDelegate::QStyledItemDelegate; void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override { Q_ASSERT(index.isValid()); QStyleOptionViewItem opt = option; initStyleOption(&opt, index); opt.text.clear(); const QWidget *widget = option.widget; QStyle *style = widget ? widget->style() : QApplication::style(); style->drawControl(QStyle::CE_ItemViewItem, &opt, painter, widget); opt.text = index.data().toString() + QChar(' ') + index.data(Qt::UserRole).toString(); style->drawItemText(painter,opt.rect,Qt::AlignCenter,opt.palette,opt.state & QStyle::State_Enabled,opt.text); } QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override { QVariant value = index.data(Qt::SizeHintRole); if (value.isValid()) return qvariant_cast<QSize>(value); QStyleOptionViewItem opt = option; initStyleOption(&opt, index); opt.text = opt.text + QChar(' ') + index.data(Qt::UserRole).toString(); const QWidget *widget = option.widget; QStyle *style = widget ? widget->style() : QApplication::style(); return style->sizeFromContents(QStyle::CT_ItemViewItem, &opt, QSize(), widget); } }; int main(int argc, char *argv[]) { QApplication app(argc,argv); QListView wid; wid.setStyleSheet(QStringLiteral("color: red")); QStandardItemModel model(2,1); model.setData(model.index(0,0),QStringLiteral("Somebody")); model.setData(model.index(0,0),QStringLiteral("once Told Me"), Qt::UserRole); model.setData(model.index(1,0),QStringLiteral("The world")); model.setData(model.index(1,0),QStringLiteral("is gonna roll me"), Qt::UserRole); wid.setModel(&model); wid.setItemDelegateForRow(0, new FixTextDelegate(&wid)); wid.setItemDelegateForRow(1, new ManualTextDelegate(&wid)); wid.show(); return app.exec(); }
-
@VRonin said in How to draw styled text in QStyledItemDelegate:
You can just use QStyle::drawItemText. Below I show 2 examples, one just fixes the text and uses drawControl, the other manually writes the text using drawItemText (ignore the sizeHint implementations)
I apologize but this is not good answer for me, both examples don't do what I expect, because both require to execute:
style->drawControl(QStyle::CE_ItemViewItem, &opt, painter, widget);
.There is no way how to do it without that line?