使用 QGraphicsView 子类用 QPainter 画一条线

Draw a line with QPainter using QGraphicsView subclass

问题: 我无法让 GraphicsView 的 paintEvent 被调用,或者换句话说,我不知道如何让 QPainter 一起工作。

主要window'Window.cpp':

Window::Window(QWidget* parent) :
    QMainWindow(parent),
    ui(new Ui::Window),
    draw(*this)  //my own QGraphicsView instance (see class below)
{
    ui->setupUi(this);
    //assigning a new scene to draw and to window's graphicsView
    this->scene = new QGraphicsScene(this);
    this->draw.setScene(scene);
    this->ui->graphicsView->setScene(scene);
}

void Window::MyRepaint()
{
    qInfo() << "Repaint - start" << this->draw.scene();
    this->draw.scene()->update(this->draw.sceneRect());
    this->draw.repaint();
    this->draw.viewport()->update();
    /*only the following line made the paintEvent executed eventually but without a visible result and with an error in the output*/
    this->draw.paintEvent(NULL);
    qInfo() << "Repaint - end"; 
}

子类化 QGraphicsView,文件:Draw.h:

class Window;
class Draw : public QGraphicsView{
private:
    Window& parent;

public:
    Draw(Window &parent);
    void paintEvent(QPaintEvent*e) override;
};

Draw.cpp

void Draw::paintEvent(QPaintEvent *e)
{
    qInfo() << "trying to draw";
    QPainter p(this);
    p.setPen(QPen(Qt::black, 12, Qt::DashDotLine, Qt::RoundCap));
    p.drawLine(0, 0, 200, 200);
}

输出:

Repaint - start QGraphicsScene(0x15c7eca8)
trying to draw
QWidget::paintEngine: Should no longer be called
QPainter::begin: Paint device returned engine == 0, type: 1
QPainter::setPen: Painter not active
QPainter::viewport: Painter not active
QPainter::end: Painter not active, aborted
Repaint - end

也许我选择了一个完全错误的方法。

QGraphicsView 旨在与 QGraphicsScene 一起使用。如果你只想画线,那么从 QWidget 派生并覆盖它的 paintEvent。在设计器中将 QWidget 提升到您的派生 class.

另外,Qt 有很好的文档。我建议您访问 this 页面。

简而言之,您可以使用 QGraphicsLineItem *QGraphicsScene::addLine(...)

这是Graphics View Framwork画线的方式,而接受的答案是QWidget方式

QGraphicsView 是图形视图框架的一部分。通常通过调用 update(),小部件能够触发 paintEvent()。然而,据我所知,在图形视图框架中,QGraphicsView 不可能通过调用 update()

来触发 paintEvent()

根据qt文档,还有一件事你应该知道:

Warning: When the paintdevice is a widget, QPainter can only be used inside a paintEvent() function or in a function called by paintEvent()