Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

QItemDelegate impossible to change text color



  • Trying to make a custom ItemView for a QTreeView. So I subclassed QItemDelegate overrode QItemDelegate::paint and NOTHING!! seems to work I can not change text color as I want it to be at ALL!! Bit if I draw text alone it works. So what do I do not understand?

    void MyItemViewDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const
    {
        painter->save();
    
        QStyleOptionViewItem voptCopy(option);
        voptCopy.features |= QStyleOptionViewItemV2::HasDisplay;
        voptCopy.text = index.data(Qt::DisplayRole).toString();
    
        auto color = index.data(Qt::TextColorRole).value<QColor>();
        painter->setPen(QColor("#FF0000"));
        voptCopy.palette.setColor(QPalette::All, QPalette::Text, QColor("#FF0000"));
    
        if (m_functor->operator ()(index))
        {
            voptCopy.rect.adjust(-m_indentation, 0, 0, 0);
        }
        else
        {
            voptCopy.rect.adjust(0, 0, 0, 0);
        }
    
        //painter->drawText(QPoint(voptCopy.rect.x(), voptCopy.rect.y()), voptCopy.text);
        theApp->style()->drawControl(QStyle::CE_ItemViewItem, &voptCopy, painter, static_cast<QWidget*>(parent()));
    
        painter->restore();
    }
    


  • @MikhailG Did you tell to your view to use the delegate ? by calling QAbstractItemView::setItemDelegate() or QAbstractItemView::setItemDelegateForColumn() ?



  • @Gojir4 yep! I Did I can see that it draws the ItemView but with a default color.


  • Qt Champions 2019

    @MikhailG said in QItemDelegate impossible to change text color:

    I can see that it draws the ItemView but with a default color.

    It will also draw when you did not set the delegate... please make sure paint() is really called by e.g. setting a breakpoint or with debug output.



  • @Christian-Ehrlicher yes it stops in paint func under debug



  • @MikhailG I have tested your code and it works well on my side. I have made few modifications but it's globally the same. I have also tested with a custom model to be able to have different color for each row. This is working well. That's strange it's not working on your side.

    Here is my code for testing:

    void MyItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
    {
        painter->save();
    
        QStyleOptionViewItem itemOpt(option);
        itemOpt.features |= QStyleOptionViewItemV2::HasDisplay;
        itemOpt.text = index.data(Qt::DisplayRole).toString();
    
        //Color given by model
        itemOpt.palette.setColor(QPalette::Text, index.data(Qt::TextColorRole).value<QColor>());
    
        //Red only (For QStringListModel)
        //itemOpt.palette.setColor(QPalette::Text, QColor("#FF0000"));
    
        //painter->drawText(QPoint(voptCopy.rect.x(), voptCopy.rect.y()), voptCopy.text);
        QApplication::style()->drawControl(QStyle::CE_ItemViewItem, &itemOpt, painter);
    
        painter->restore();
    }
    

    My Model used for testing:
    coloredstringlistmodel.h

    #ifndef MYSTRINGLISTMODEL_H
    #define MYSTRINGLISTMODEL_H
    
    #include <QAbstractListModel>
    #include <QColor>
    
    struct ColoredString{
        ColoredString(const QString &s, const QColor &c):
            string(s), color(c)
        {}
    
        QString string;
        QColor color;
    };
    
    typedef QList<ColoredString> ColoredStringList;
    
    class MyColoredStringListModel : public QAbstractListModel
    {
        Q_OBJECT
    
    public:
        explicit MyColoredStringListModel(QObject *parent = nullptr);
    
        // Basic functionality:
        int rowCount(const QModelIndex &parent = QModelIndex()) const override;
    
        QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
    
    
        ColoredStringList coloredStringList() const;
        void setColoredStringList(const ColoredStringList &coloredStringList);
    
    private:
    
        ColoredStringList m_coloredStringList;
    };
    
    #endif // MYSTRINGLISTMODEL_H
    

    mystringlistmodel.cpp

    #include "mycoloredstringlistmodel.h"
    
    MyColoredStringListModel::MyColoredStringListModel(QObject *parent)
        : QAbstractListModel(parent)
    {
    }
    
    int MyColoredStringListModel::rowCount(const QModelIndex &parent) const
    {
        // For list models only the root node (an invalid parent) should return the list's size. For all
        // other (valid) parents, rowCount() should return 0 so that it does not become a tree model.
        if (parent.isValid())
            return 0;
    
        return m_coloredStringList.count();
    }
    
    QVariant MyColoredStringListModel::data(const QModelIndex &index, int role) const
    {
        if (!index.isValid())
            return QVariant();
    
    
        switch(role){
            case Qt::DisplayRole:
            case Qt::EditRole:
                return m_coloredStringList.at(index.row()).string;
    
            case Qt::TextColorRole:
                return m_coloredStringList.at(index.row()).color;
    
    
        }
        // FIXME: Implement me!
        return QVariant();
    }
    
    ColoredStringList MyColoredStringListModel::coloredStringList() const
    {
        return m_coloredStringList;
    }
    
    void MyColoredStringListModel::setColoredStringList(const ColoredStringList &coloredStringList)
    {
        m_coloredStringList = coloredStringList;
    }
    

    Usage in a simple widget with a QListView and a QTreeView

    Widget::Widget(QWidget *parent) :
        QWidget(parent),
        ui(new Ui::Widget)
    {
        ui->setupUi(this);
    
        //Test custom model
        ColoredStringList list;
        list << ColoredString("String 1", Qt::red);
        list << ColoredString("String 2", Qt::green);
        list << ColoredString("String 3", Qt::blue);
        list << ColoredString("String 4", Qt::cyan);
        list << ColoredString("String 5", Qt::magenta);
        list << ColoredString("String 6", Qt::yellow);
        m_coloredModel.setColoredStringList(list);
    
        //Test QStringListModel
        //m_model.setStringList(QStringList() << "Data 1" << "Data 2" << "Data 3" << "Data 4" << "Data 5" << "Data 6" << "Data 7" << "Data 8");
    
        ui->listView->setItemDelegate(new MyItemDelegate(ui->listView));
        ui->treeView->setItemDelegateForColumn(0, new MyItemDelegate(ui->treeView));
    
        /*
        ui->listView->setModel(&m_model);
        ui->treeView->setModel(&m_model);
        /*/
        ui->listView->setModel(&m_coloredModel);
        ui->treeView->setModel(&m_coloredModel);
        //*/
    }
    


  • @Gojir4 thanks bro but I got the solution



  • @MikhailG Nice, thanks for sharing your solution


Log in to reply