这是我第一次使用Qt,我必须使MSPaint与Qt等效。但是我在画线时遇到了麻烦。目前,我可以通过单击屏幕上的某个位置并释放其他位置来绘制一条线,但是当我绘制第二条线时,前一行将被删除。喷涂另一个项目时,如何保留先前绘制的项目?

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的类,它具有2个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 * );

};

最佳答案

QPicture记录QPainter命令。您也可以从其文档中阅读以下内容:



带有绘画设备的QPainter构造函数会调用begin()。因此,每次删除旧的记录命令。

使用它可能听起来很诱人,因为它确实说出了很多好处,例如,它与分辨率无关,但是实际上这并不是绘图应用程序的工作方式。切换到QPixmap,您的图形将继续存在。

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

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

此外,如果您希望像艺术画笔一样引入笔刷的概念,而不是QBrush,则可能需要看看这个approach to draw the line

编辑:请注意,您应该能够通过不多次调用QPicture来防止begin()丢失其内容。如果您创建一个仅在类范围内仅在其上进行绘画的绘画工具,并在构造函数中调用begin,则应保留不同的记录绘画操作。但是随着数量的增加,将QPicture绘制到小部件上将花费越来越多的时间。您可以通过同时使用QPictureQPixmap来解决这个问题,并绘制两者,使用图片记录 Action 和像素图以避免连续重绘图片,即使您将工作加倍,它仍然会更高效,尽管您仍然可以使用图片以其他分辨率重新栅格化或保存绘图历史记录。但是我怀疑QPicture在您的绘图应用程序开始形成实际的绘图应用程序时会很好用,例如,当您开始使用pixmap brushe模具等时。

07-24 22:04