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

Icon in corner of QStandardItem



  • Hey guys,
    is it possible to show a small icon in the corner of a QStandardItem that already has ->setIcon set with another icon?



  • sure, call something like item->setData(Qt::UserRole + Qt::DecorationRole, secondIcon); and then implement a custom QStyledItemDelegate subclass that reimplements paint() calling the base implementation an then painting the second icon



  • Thanks for your answer!
    But i don't quite catch the 2nd part.

    "and then implement a custom QStyledItemDelegate subclass that reimplements paint() calling the base implementation an then painting the second icon"

    could you explain that part a little bit more detailed please ?

    Do you mean something like this http://doc.qt.io/qt-5/qtwidgets-itemviews-stardelegate-example.html ?


  • Lifetime Qt Champion

    @Neko
    Hi
    First read
    http://doc.qt.io/qt-5/qstyleditemdelegate.html

    bascially its a subclass like ( psudo code. didnt compile it )

    class SmallIconDelegate : public QStyledItemDelegate {
      Q_OBJECT
     public:
      paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const {
        QStyledItemDelegate::paint(painter, option, index); // call base
        // grab icon from data role
        // paint it where u want
      }
    }
    

    update:: yes its like star example :)



  • class SmallIconDelegate : public QStyledItemDelegate {
        Q_OBJECT
        Q_DISABLE_COPY(SmallIconDelegate)
    public:
        explicit SmallIconDelegate(QObject* parent = Q_NULLPTR)
            : QStyledItemDelegate(parent)
        {}
        void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const Q_DECL_OVERRIDE {
            QStyledItemDelegate::paint(painter, option, index); // call base
            // grab icon from data role
            const QVariant value = index.data(Qt::DecorationRole + Qt::UserRole);
            if (value.isValid() && !value.isNull()) {
                QPixmap cornerPixmap;
                const QSize decorationSize(option.rect.height()/4,option.rect.height()/4);
                switch (value.type()) {
                case QVariant::Icon: {
                    QIcon tempIcon = qvariant_cast<QIcon>(value);
                    QIcon::Mode mode;
                    if (!(option.state & QStyle::State_Enabled))
                        mode = QIcon::Disabled;
                    else if (option.state & QStyle::State_Selected)
                        mode = QIcon::Selected;
                    else
                        mode = QIcon::Normal;
                    const QIcon::State state = option.state & QStyle::State_Open ? QIcon::On : QIcon::Off;
                    cornerPixmap = tempIcon.pixmap(decorationSize,mode,state);
                }
                    break;
                case QVariant::Color:
                    cornerPixmap = QPixmap(decorationSize);
                    cornerPixmap.fill(qvariant_cast<QColor>(value));
                    break;
                case QVariant::Image:
                    cornerPixmap = QPixmap::fromImage(qvariant_cast<QImage>(value)).scaled(decorationSize);
                    break;
                case QVariant::Pixmap:
                    cornerPixmap   = qvariant_cast<QPixmap>(value).scaled(decorationSize);
                    break;
                default:
                    break;
                }
                // paint it where u want
                if(!cornerPixmap.isNull()){
                    const QWidget *widget = option.widget;
                    QStyle *style = widget ? widget->style() : QApplication::style();
                    style->drawItemPixmap(painter,option.rect,Qt::AlignTop|Qt::AlignLeft,cornerPixmap);
                }
            }
        }
    };
    


  • Will check it out. Thank you very much guys :)



  • Okay, i'm testing it and it is working!
    Thank you guys!
    Now i just need to figure out how to get it on the bottom right corner. Already tried using

    style->drawItemPixmap(painter, QRect(option.rect.topLeft(), decorationSize), Qt::AlignBottom | Qt::AlignRight, cornerPixmap);

    but it's not working.
    Can't be that hard huh? Thanks again guys, you saved my day

    Edit: got it :)
    style->drawItemPixmap(painter, QRect(option.rect.topLeft(), option.rect.bottomRight()), Qt::AlignBottom | Qt::AlignRight, cornerPixmap);



  • This post is deleted!


  • @Neko said in Icon in corner of QStandardItem:

    QRect(option.rect.topLeft(), option.rect.bottomRight())

    You can just pass option.rect directly



  • Already modified this whole line since i want to display 2 different icons next to each other :)

    But thank you.



  • Okay, i've got another problem.
    When i try to change the icons during runtime, or simply add new icons to my listview later on, the updated and new icons wont display any icons anymore. How can i fix this ?

    Currently i'm doing:

    onCreate:
    QIcon IconA = "myPathA"
    QIcon IconB = "myPathB"
    QStandardItem * iconItem = new QStandardItem;
    iconItem->setIcon(QIcon(iconPath));
    iconItem->setData(QIcon(iconA), Qt::UserRole + 50);
    iconItem->setData(QIcon(IconB), Qt::UserRole + 51);

    onUpdate:
    iconA = "anotherPathA"
    iconB = "anotehrPathB"
    model->setData(index, iconA, Qt::UserRole + 50);
    model->setData(index, iconB, Qt::UserRole + 51);

    changing my Icon names works. But the small icons seem to make some troubles.



  • Guess i found my problem. Sorry for disturbing. Will update



  • Used wrong type by accident.
    Used QString instead of QIcon. No wonder it didnt work
    Working fine :)


Log in to reply