2015-04-01 525 views
0

下面是在窗口小部件上绘制线条的代码。问题在于它保留了先前绘制的线条,并且在每次移动鼠标时它都会一次又一次地绘制。我想绘制像mspaint,即只在鼠标释放事件,它会最终确定线条绘制(否则只是预览线)。我想到的一个想法是在每次鼠标移动时删除预览行,另一个想法是利用一些临时视图并在鼠标释放时完成它。但难以找到正确的方法如何做到这一点。 感谢您的帮助在QtWidget上动态绘制线条

#include "paintwidget.h" 
#include "ui_paintwidget.h" 

#include <QtGui> 

paintWidget::paintWidget(QWidget* parent) 
    : QWidget(parent) 
    , ui(new Ui::paintWidget) 
{ 
    ui->setupUi(this); 

    m_nInitialX = 0; 
    m_nInitialY = 0; 
    m_nFinalX = 0; 
    m_nFinalY = 0; 
    m_nPTargetPixmap = 0; 
    m_nPTargetPixmap = new QPixmap(400, 400); 
    m_nbMousePressed = false; 
} 

paintWidget::~paintWidget() 
{ 
    delete ui; 
} 

void paintWidget::mousePressEvent(QMouseEvent* event) 
{ 
    m_nbMousePressed = true; 
    m_nInitialX = event->pos().x(); 
    m_nInitialY = event->pos().y(); 
} 

void paintWidget::mouseReleaseEvent(QMouseEvent* event) 
{ 
    m_nbMousePressed = false; 
    //update(); 
} 

void paintWidget::paintEvent(QPaintEvent* e) 
{ 
    if (m_nbMousePressed) { 
     QPainter PixmapPainter(m_nPTargetPixmap); 
     QPen pen(Qt::green); 
     PixmapPainter.setPen(pen); 
     //PixmapPainter.drawLine(m_nInitialX, m_nInitialY, m_nFinalX, m_nFinalY); 
    } 
    QPainter painter(this); 
    painter.drawPixmap(0, 0, *m_nPTargetPixmap); 
} 

void paintWidget::mouseMoveEvent(QMouseEvent* event) 
{ 
    if (event->type() == QEvent::MouseMove) { 
     QPainter PixmapPainter(m_nPTargetPixmap); 
     QPen pen(Qt::black); 
     PixmapPainter.setPen(pen); 
     PixmapPainter.drawLine(m_nInitialX, m_nInitialY, m_nFinalX, m_nFinalY); 
     update(); // update your view 
     m_nFinalX = event->pos().x(); 
     m_nFinalY = event->pos().y(); 
    } 
    update(); // update your view 
} 

回答

2

我在这里把我的资料来源:

https://github.com/peteristhegreat/persistent_paint

注意添加评论

下面是相关文件:

#include "paintwidget.h" 
#include <QPainter> 
#include <QPen> 
#include <QBrush> 
#include <QDebug> 

PaintWidget::PaintWidget(QWidget *parent) : QWidget(parent) 
{ 
// the ui form wasn't needed here, so I added it without it. 

// QLine neatly keeps track of both the two points, m_line in this case 
// m_nInitialX = 0; 
// m_nInitialY = 0; 
// m_nFinalX = 0; 
// m_nFinalY = 0; 
// m_nPTargetPixmap = 0; 
// m_nPTargetPixmap = new QPixmap(400,400); 
    m_nPTargetPixmap = QPixmap(400,400);// put the pixmap on the stack instead of the heap 
    m_nPTargetPixmap.fill(); 
    m_nbMousePressed = false; 
} 

PaintWidget::~PaintWidget() 
{ 
// delete ui; 
} 

void PaintWidget::mousePressEvent(QMouseEvent* event) 
{ 
    m_nbMousePressed = true; 
// m_nInitialX = event->pos().x(); 
// m_nInitialY = event->pos().y(); 
    m_line.setP1(event->pos()); 
    m_line.setP2(event->pos()); 
} 

void PaintWidget::mouseReleaseEvent(QMouseEvent *event) 
{ 
    m_nbMousePressed = false; 
    update(); 
} 

void PaintWidget::paintEvent(QPaintEvent *e) 
{ 
    static bool wasPressed = false; 
    QPainter painter(this); 

    if(m_nbMousePressed) 
    { 
     painter.drawPixmap(0, 0, m_nPTargetPixmap); 
     painter.drawLine(m_line); 
     wasPressed = true; 
    } 
    else if(wasPressed) 
    { 
     // Note that this painting only needs to happen once, 
     // right when the mouse is released. 
     QPainter PixmapPainter(&m_nPTargetPixmap); 
     QPen pen(Qt::green); 
     PixmapPainter.setPen(pen); 
     PixmapPainter.drawLine(m_line); 

     painter.drawPixmap(0, 0, m_nPTargetPixmap); 
     wasPressed = false; 
    } 
} 

void PaintWidget::mouseMoveEvent(QMouseEvent *event) 
{ 
    if (event->type() == QEvent::MouseMove) 
    { 
//  QPainter PixmapPainter(m_nPTargetPixmap); 
//  QPen pen(Qt::black); 
//  PixmapPainter.setPen(pen); 
//  PixmapPainter.drawLine(m_nInitialX, m_nInitialY, m_nFinalX, m_nFinalY); 
//  m_nFinalX = event->pos().x(); 
//  m_nFinalY = event->pos().y(); 
     m_line.setP2(event->pos()); 
//  update(); // update your view 
    } 
    update(); // update your view 
} 

更新:使用QGraphicsScene和绘制线条和省略号的附加信息:

QGraphicsScene有点击场景时可添加的直线和省略号。

How to draw a point (on mouseclick) on a QGraphicsScene?

Arc in QGraphicsScene

http://doc.qt.io/qt-5/graphicsview.html

http://doc.qt.io/qt-5/examples-graphicsview.html

该实施例尤其似乎是相似的:

http://doc.qt.io/qt-5/qtwidgets-graphicsview-diagramscene-example.html

希望有所帮助。

+0

我的理解是m_nPTargetPixmap是作为一个额外的绘图层工作,当鼠标被释放时,它正在画家画。这是对的吗? – ruben 2015-04-01 20:19:19

+1

是的。最先画的是底部,最后画的是顶部。 – phyatt 2015-04-01 20:48:01