Important: Please read the Qt Code of Conduct -

Method QListWidget::insertItem for QListWidget which is painting with ItemDelegate class [SOLVED]

  • Hello.
    I need advice how I can repaint a list with type QListWidget.
    I created ItemDelegate class which inherits from QAbstractItemDelegate class. The ItemDelegate class instance is set as itemDelegete for the list.

    header file code with my ItemDelegate class:

    class ItemDelegate : public QAbstractItemDelegate
        ItemDelegate(QListWidget *l) :QAbstractItemDelegate(l) {}
        ~ItemDelegate() {}
        void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
        QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const;

    Commands in class constructor for creating main window:

    ItemDelegate *itemDelegate = new ItemDelegate(ui->eventlist);

    Command which executed after left mouse click on a button:

    ui->eventlist->insertItem(itemIndex, item);

    This command adds item to end of the list even when itemIndex is less than index of last item.

  • Lifetime Qt Champion

    Hi and welcome

    Im not sure what your issue is.

    After you insert a new items, it is not shown in the list ?

    You could do
    ui->eventlist->viewport()->update() to make it redraw it all

  • Hi. Thanks.
    I tried your advice but the problem isn't solved.

    Command which executed after left mouse click on a button:

    ui->eventlist->insertItem(itemIndex, item);

    This command adds item to end of the list even when itemIndex variable is less than index of last item.
    What do I could do to new item was added to right place.

    ui->eventlist is the list with QListWidget type.

  • Lifetime Qt Champion

    @luke147 said:

    What do I could do to new item was added to right place.

    Hi Im afraid I do not understand what is not working for you ?

    Could you describe what you want or what you expect to happen and what happens instead.

    // add new entry above the selected
        int indx=ui->listWidget->currentIndex().row();
        ui->listWidget->insertItem( indx, "im new" );
        // add new to the end of list
        ui->listWidget->addItem( "last" );

  • I defined method ItemDelegate::paint which paints a list item.
    Inserted item is added always to end of the list.
    See my screen-shots:
    illustration with indexes:
    current status:

  • Lifetime Qt Champion


    Ok, so the issue is that the added item is put last in the list
    and you want it to be after the first in the list ?

    insertItem( 1 , "im new" );

    will not put it in 2 place ?

  • I need to put the item by the specified index.
    The new item is inserted always only at the end.
    First, second etc. or last but always by the specified index.
    I use:

    insertItem( index , item );

    But item is put always at the end.

  • Lifetime Qt Champion

    @mrjj said:

    and how do you get the index ?
    you use for
    insertItem( index , item );

    Also just for test, tell me if
    insertItem( 0 , "im new" );
    also be inserted last ?

    Just tested here and insertitem does what expected. As far as I know, having
    a Delegate should not change that.

  • Yes, I tried command:

    insertItem( 0, item );

    But the item is inserted at the end.

  • Lifetime Qt Champion

    Ok that sounds really strange.

    Need to test some code to have suggestions. My Delegate is inherited from
    QStyledItemDelegate but should makes no difference.

  • Lifetime Qt Champion

    Hi and welcome to devnet,

    Do you have any sorting active on your QListWidget ?

  • No, I have no sorting active.
    My item is my type. EventListItem class inherits from QListWidgetItem class. The list is QListWidget type.

    Now I tried create new QListWidget and to insert item with QListWidgetItem type.
    This work fine. Even if I set itemDelegate. It's OK.

    Can a item to be my type which inherits from QListWidgetItem class?

  • Lifetime Qt Champion

    I see no reason that you cannot make your own QListWidgetItem and
    since your list is not sorted, it should make no difference.
    (but seems it does)

    On thing you could try is to override
    virtual bool operator<(const QListWidgetItem &other) const;

    for you class and see if that changes where it gets inserted.

  • Lifetime Qt Champion

    Can you share your custom class ? There might be something to spot in it.

  • Sorry. My answers will be delayed this week.

    I try override the operator.

    the header file:

    #include <QPixmap>
    #include <QListWidget>
    #include <QListWidgetItem>
    #include "pts.h"
    class EventListItem : public QListWidgetItem
        enum eventtype { none, start, stop, chapter, bookmark };
        EventListItem( QListWidget *listbox, const QPixmap &pixmap, eventtype type, int picture, int picturetype, pts_t _pts );
        const QPixmap *pixmap() const
            return &pm;
        int getpicture() const
            return pic;
        pts_t getpts() const
            return pts;
        enum eventtype geteventtype() const
            return evtype;
        void seteventtype(enum eventtype type)
        int  height( const QListWidget *lb ) const;
        int  width( const QListWidget *lb )  const;
        int rtti() const;
        static int RTTI()
            return 294268923;
        QString getstring() const;
        QPixmap pm;
        enum eventtype evtype;
        int pic;
        int pictype;
        pts_t pts;

    the source file:

    #include <QApplication>
    #include <QIcon>
    #include "eventlistitem.h"
    #include "settings.h"
    EventListItem::EventListItem(QListWidget *listbox, const QPixmap &pixmap,
                                 eventtype type, int picture, int picturetype, pts_t _pts ) :
        QListWidgetItem(listbox), pm(pixmap), evtype(type), pic(picture), pictype(picturetype), pts(_pts)
        if (pm.width()>160 || pm.height()>90)
            pm=pm.scaled(130, 90, Qt::KeepAspectRatio, Qt::SmoothTransformation);
        int h = height(listbox);
        setSizeHint(QSize(sizeHint().width(), h));
    int EventListItem::rtti() const
        return RTTI();
    int EventListItem::height(const QListWidget *  ) const
        int h=0;
        if (!pm.isNull())
            h = pm.height();
        return qMax( h+6, QApplication::globalStrut().height() );
    int EventListItem::width(const QListWidget *lb ) const
        int width=3;
        if (!pm.isNull())
            width += pm.width()+3;
        // I will move this code other place and edit it. It specify exact width of text.
        if (lb) {
            QLabel rt(getstring());
            rt.setFixedWidth(1000); //drawinglistbox->width());
            width+=rt.width() + 3;
        return qMax( width, QApplication::globalStrut().width() );
    QString EventListItem::getstring() const
        QString label;
        if (evtype==start)
            label = settings()->start_label;
        else if (evtype==stop)
            label = settings()->stop_label;
        else if (evtype==chapter)
            label = settings()->chapter_label;
        else if (evtype==bookmark)
            label = settings()->bookmark_label;
        return label + QString().sprintf("<br><font color=\"%%normal-text-colour%%\">%02d:%02d:%02d.%03d</font><br><font color=\"%%normal-text-colour%%\">%d (%c)</font>",
                                         ((const char *)".IPB....")[pictype&7]);

  • Lifetime Qt Champion

    Ok, I see the problem: as recommended in the QListWidgetItem constructor doc, don't give it a parent if you want to insert your item at a given position.

  • Thanks to both.
    I don't give a parent to QListWidgetItem constructor if I use insertItem method.

    I overridden operator<.

    It works now.