QPainter 保留以前的绘图
QPainter keep previous drawings
这是我第一次使用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的class,它有2个QPoint属性start和end。
Class正文:
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
个命令。您还可以从其文档中阅读以下内容:
Note that the list of painter commands is reset on each call to the
QPainter::begin() function.
并且带有绘制设备的 QPainter
构造函数会调用 begin()
。所以每次删除旧的记录命令。
使用它可能听起来很诱人,因为它确实有一些优点,例如,它与分辨率无关,但这并不是绘图应用程序在现实中的工作方式。切换到 QPixmap
,您的绘图将保留。
此外,不要忘记初始化像素图,因为默认情况下它是空的,您将无法在上面绘图。
Canvas() : pic(width,height) {...}
此外,如果您想像艺术画笔一样介绍画笔的概念而不是 QBrush
,您可能想看看这个 approach to draw the line。
编辑:请注意,您应该能够通过不多次调用 begin()
来防止 QPicture
丢失其内容。如果您创建一个画家,专用于仅在 class 范围内绘制,并在构造函数中调用 begin,则记录的不同绘制操作应该保持不变。但是随着它们数量的增加,将 QPicture
绘制到您的小部件将花费越来越多的时间。你可以通过同时使用 QPicture
和 QPixmap
来解决这个问题,并绘制到两者上,使用图片记录动作和像素图以避免连续重绘图片,即使你会做两次工作 它仍然会更有效率,同时您仍然可以使用图片以不同的分辨率重新栅格化或保存绘图历史记录。但我怀疑 QPicture
会做得很好,因为您的绘图应用程序开始形成实际的绘图应用程序,例如当您开始使用 pixmap brushe stencils 等时。
这是我第一次使用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的class,它有2个QPoint属性start和end。
Class正文:
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
个命令。您还可以从其文档中阅读以下内容:
Note that the list of painter commands is reset on each call to the QPainter::begin() function.
并且带有绘制设备的 QPainter
构造函数会调用 begin()
。所以每次删除旧的记录命令。
使用它可能听起来很诱人,因为它确实有一些优点,例如,它与分辨率无关,但这并不是绘图应用程序在现实中的工作方式。切换到 QPixmap
,您的绘图将保留。
此外,不要忘记初始化像素图,因为默认情况下它是空的,您将无法在上面绘图。
Canvas() : pic(width,height) {...}
此外,如果您想像艺术画笔一样介绍画笔的概念而不是 QBrush
,您可能想看看这个 approach to draw the line。
编辑:请注意,您应该能够通过不多次调用 begin()
来防止 QPicture
丢失其内容。如果您创建一个画家,专用于仅在 class 范围内绘制,并在构造函数中调用 begin,则记录的不同绘制操作应该保持不变。但是随着它们数量的增加,将 QPicture
绘制到您的小部件将花费越来越多的时间。你可以通过同时使用 QPicture
和 QPixmap
来解决这个问题,并绘制到两者上,使用图片记录动作和像素图以避免连续重绘图片,即使你会做两次工作 它仍然会更有效率,同时您仍然可以使用图片以不同的分辨率重新栅格化或保存绘图历史记录。但我怀疑 QPicture
会做得很好,因为您的绘图应用程序开始形成实际的绘图应用程序,例如当您开始使用 pixmap brushe stencils 等时。