QPainter 保留之前的绘画

9

这是我第一次使用Qt,我需要用Qt制作一个类似于MSPaint的软件。然而,我在绘制线条时遇到了问题。我可以通过在屏幕上点击某处并释放另一个位置来绘制一条线,但当我绘制第二条线时,之前的线会被擦除。如何在绘制新项目时保留先前绘制的项目?

void Canvas::paintEvent(QPaintEvent *pe){
    QWidget::paintEvent(pe);
    QPainter p(this);
    p.drawPicture(0,0,pic);
}

void Canvas::mousePressEvent(QMouseEvent *mp){
    start = mp->pos();
}

void Canvas::mouseReleaseEvent(QMouseEvent *mr){
    end = mr->pos();
    addline();
}

void Canvas::addline()Q_DECL_OVERRIDE{
    QPainter p(&pic);
    p.drawLine(start,end);
    p.end();
    this->update();
}

Canvas是继承自QWidget的类,它有两个QPoint属性start和end。

类内容:

class Canvas : public QWidget{
Q_OBJECT
private:
    QPoint start;
    QPoint end;
    QPicture pic;
public:
    Canvas(){paint = false;setAttribute(Qt::WA_StaticContents);}
    void addline();
protected:
    void paintEvent(QPaintEvent *);
    void  mousePressEvent( QMouseEvent * );
    //void  mouseMoveEvent( QMouseEvent * );
    void  mouseReleaseEvent( QMouseEvent * );

};

我认为问题在于每次添加新行时,您都会创建一个新的QPainter变量,这会导致之前存储的QPainter变量被销毁,因为它已经离开了作用域(但由于OpenGL的性质,它仍然保留在帧缓冲区中)。尝试将QPainter声明为类范围变量,看看是否有所帮助。 - Poriferous
1
@Poriferous - 没关系,pic 是他的缓冲区,绘图器不应该影响缓冲区数据。这并不意味着保留绘图器是一个坏主意。 - dtech
@Poriferous - 但从他的代码来看,pic似乎具有类作用域。它应该在不同的调用之间保持不变。从迄今为止发布的代码中,我没有看到任何清除pic的内容。 - dtech
如果是这种情况,那么pic重新实现的paintEngine()函数可能存在实现缺陷。在我们获得更多信息之前,我们无法提供进一步的帮助。 - Poriferous
我尝试使用QPixmap和QImage,但是我一直收到以下错误: QPainter :: begin:Paint device returned engine == 0,type:2 QPainter :: end:Painter not active,aborted - anaBad
显示剩余4条评论
1个回答

6

QPicture记录QPainter命令。根据它的文档,您可以读到这个:

请注意,每次调用QPainter::begin()函数时,绘图器命令列表都会重置。

带有绘图设备的QPainter构造函数确实调用了begin()。因此,旧的记录命令在每次调用时都会被删除。

尽管QPicture声称具有一些好处,例如与分辨率无关,但在现实中绘图应用程序却不是这样工作的。切换到QPixmap并且您的图纸将持久存在。

此外,不要忘记初始化像素图,因为默认情况下它将为空,您将无法在其上绘制。

Canvas() : pic(width,height) {...}

此外,如果你想介绍艺术画笔而不是QBrush的概念,可以参考这个绘制线条的方法

注意:要防止QPicture丢失其内容,应该避免在它上面调用多次begin()。如果你创造了一个仅在类作用域中用于绘制的绘图工具,并在构造函数中调用begin,则不同记录的绘制操作应该会持久存在。但随着它们数量的增加,越来越需要时间才能将QPicture绘制到窗口小部件上。你可以通过同时使用QPictureQPixmap并在两者上绘制来解决这个问题,使用picture记录操作并使用pixmap避免连续重绘图片,即使你做双倍的工作,也会更有效率,而你仍然可以使用picture来重新栅格化到不同分辨率或保存绘图历史。但我怀疑,在你的绘图应用程序开始呈现实际绘图应用程序的形态时(例如当你开始使用像素笔刷模板等),QPicture将不会表现良好。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接