c++qtmodel-view

How to draw on a view?


There is a model, containing strings, and a list view.

The QListView is a descendant of QPaintDevice, so you can override paintEvent (QPaintEvent *) in it and draw something on it. For example, you need to draw image cheker.png:

#include <QApplication>
#include <QPainter>
#include <QPaintEvent>
#include <QListView>
#include <QStringListModel>

class View :public QListView {
public:
    void paintEvent(QPaintEvent* event) {
        QListView::paintEvent(event);
        QPainter painter(this);
        painter.drawPixmap(10,10,QPixmap("cheker.png"));         
    }
};

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    QStringListModel model;
    QStringList list;
    list << "a" << "b" << "c" << "d" << "e" << "f" << "g" << "h";
    model.setStringList(list);

    View view;
    view.setModel(&model);
    view.show();
    return a.exec();
}

checker.png looks like this: enter image description here

What is expected is not happening - the picture does not show. The view is depicted as if no methods were overridden. And the following is printed in the console:

enter image description here

Actual results:

enter image description here

What I expect:

enter image description here

So, how to draw in a view?


Solution

  • All item views that inherit from QAbstractScrollArea are a bit tricky in the sense that the list view itself is not typically the widget that is painted on. A view deriving from QAbstractScrollArea will have a viewport widget that is usually painted on instead. See: QAbstractScrollArea::viewport().

    To draw the image, you can change the paintEvent() implementation to draw on the viewport widget by letting the painter take the viewport widget as the paint device. The following will draw a red line over the items in the list view:

    void paintEvent(QPaintEvent* event) override
    {
      QListView::paintEvent(event);
    
      QPainter painter(viewport());
      painter.setPen(Qt::red);
      painter.drawLine(0, 0, 100, 100);
    }
    

    It will also get rid of the error messages you see on the console.