如何绘制视图?

How to draw on a view?

有一个模型,包含字符串和一个列表视图。

QListViewQPaintDevice 的后代,因此您可以覆盖其中的 paintEvent (QPaintEvent *) 并在其上绘制一些东西。比如你需要绘制图像 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 看起来像这样:

预期的情况并没有发生 - 图片没有显示。视图被描述为好像没有方法被覆盖。控制台打印如下:

实际结果:

我的期望:

那么,如何在视图中绘制?

继承自 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() 的所有项目视图。

要绘制图像,您可以更改 paintEvent() 实现以通过让画家将视口小部件作为绘画设备来在视口小部件上进行绘制。以下将在列表视图中的项目上绘制一条红线:

void paintEvent(QPaintEvent* event) override
{
  QListView::paintEvent(event);

  QPainter painter(viewport());
  painter.setPen(Qt::red);
  painter.drawLine(0, 0, 100, 100);
}

它还会消除您在控制台上看到的错误消息。

QListView::paintEvent() 重新实现 QAbstractScrollArea::paintEvent() 并且后者的文档说:

Note: If you open a painter, make sure to open it on the viewport().

(强调视口是我的。)

请参阅 QAbstractScrollArea::paintEvent(QPaintEvent*) 的 Qt 文档。