Search code examples
qtlinemouseeventqpainterpaintevent

Qt 4.7 - Drawing a 2 point line with dynamic feedback using paintEvent


so I am trying to draw a line between two points. Left mouse click starts the line then I would like the line to by dynamically drawn as the mouse moves (almost like a preview of the line). Left mouse click again and the line will be permanently drawn. I know there are a lot of other posts about QPaintEvents and I have combined some of the techniques used, but for some reason nothing is being drawn to the canvas. Below is the code:

void Main::mousePressEvent(QMouseEvent * event)
{
    if (event->button() == Qt::LeftButton) {
    QPointF pos = event->pos();
        if( mStartPoint.isNull() ) {
            if(josh.contains(pos))
                mStartPoint = pos;
        } else {
            canvas.addLine(mStartPoint.x(),mStartPoint.y(),pos.x(),pos.y());
            mStartPoint = QPointF();
        }
    }
}

bool Main::eventFilter(QObject *obj, QEvent *event)
{
  if (event->type() == QEvent::MouseMove)
  {
    QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
    if (!mStartPoint.isNull()) {
        m_targetImage = QImage(canvas.width(),canvas.height(),QImage::Format_ARGB32);
        QPainter p;
        p.begin(&m_targetImage);
        p.drawLine(mStartPoint, mouseEvent->pos());
        p.end();
    }
    statusBar()->showMessage(QString("Mouse move (%1,%2)").arg(mouseEvent->pos().x()).arg(mouseEvent->pos().y()));
  }
  return false;
}

void Main::paintEvent(QPaintEvent *pe)
{
        QPainter painter(this);
        QPen pen(Qt::red);
        pen.setWidth(10);
        painter.setPen(pen);
        painter.drawImage(0, 0, m_targetImage);
}

Any help is appreciated! Thanks! Josh


Solution

  • I think this is what you want. Change parameters according to your requirements.

    //In your constructor 
    m_nInitialX = 0;
    m_nInitialY = 0;
    m_nFinalX = 0;
    m_nFinalY = 0;
    m_nPTargetPixmap = 0;
    m_nPTargetPixmap = new QPixmap(400,400);
    m_nbMousePressed = false;
    
    void Main::mousePressEvent(QMouseEvent* event)
    {
          m_nbMousePressed = true;
          m_nInitialX = event->pos().x();
          m_nInitialY = event->pos().y();
    }
    
    void Main::mouseReleaseEvent(QMouseEvent *event)
    {
    m_nbMousePressed = false;
    }
    
    void Main::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 Main::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
    }
    

    This piece of code will draw a 2 point line that you want.