0

我们知道,在 qt 中绘制图像时,会使用 qpainter。最近,我使用 drawLine() 函数来绘制用户正在涂鸦的任何内容。这是通过将来自 mouseMoveEvent 的 lastPoint 和 currentPoint 传递给实现 drawLine() 的自定义函数来完成的。我已经传递了该自定义函数的参数,如下所示:

void myPaint::mouseMoveEvent(QMouseEvent *event) {  
qDebug() << event->pos();
   if ((event->buttons() & Qt::LeftButton) && scribbling) {
    pixelList.append(event->pos());
    drawLineTo(event->pos());
    lastPoint = event->pos();
   }
}

现在在 qDebug() 的帮助下,我注意到绘制时遗漏了一些像素,但绘制是精确的。我查看了 qt-painting 的来源,我看到 drawLine() 正在调用 drawLines(),它使用 qpainterPath 在图像上绘制形状。

我的问题是,是否有任何方法可以跟踪这些“丢失”的像素或找到所有已绘制的像素的方法?

谢谢!

void myPaint::drawLineTo(const QPoint &endPoint) {    
QPainter painter(image); //image is initialized in the constructor of myPaint
painter.setRenderHint(QPainter::Antialiasing);
painter.setPen(QPen(Qt::blue, myPenWidth, Qt::SolidLine, Qt::RoundCap,Qt::RoundJoin));
painter.drawLine(lastPoint, endPoint);
modified = true;
lastPoint = endPoint; //at the mousePressEvent, the event->pos() will be stored as
                      // lastPoint 
update();
}
4

1 回答 1

2

首先,不要画一个mouseEvent(). 实际上处理鼠标事件应该尽可能快地完成。此外,查看 Qt 源代码也不是一个好主意,它可能会造成混淆。而是假设 Qt 为您提供了工作,并首先尝试回答“我做错了什么?”。正如我所说,在鼠标事件中绘制绝对是错误的。

您的描述确实很主观,也许您的输出图像更好。您是否正在尝试模仿笔(例如在 windows 油漆中)?在这种情况下,鼠标按钮必须按下吗?这是你变量的目的scribbling吗?

还有更多。按照文档,QMouseEvent::buttons()总是返回鼠标移动事件的所有按钮的组合。这很有意义:鼠标移动独立于按钮。它的意思是

if ((event->buttons() & Qt::LeftButton)

永远都是真的。

假设您想在按下左键时绘制鼠标的路径。然后你使用类似的东西:

void myPaint::mousePressEvent(QMouseEvent *event){
     scribbling = true;
     pixelList.clear();
}

void myPaint::mouseReleaseEvent(QMouseEvent *event){
     scribbling = false;
}

void myPaint::mouseMoveEvent(QMouseEvent *event) {  
  if ( scribbling) {
    pixelList.append(event->pos());
  }
}

void myPaint::paintEvent(){
  QPainter painter(this)
  //some painting here
  if ( scribbling) {
     painter.setRenderHint(QPainter::Antialiasing);
     painter.setPen(QPen(Qt::blue, myPenWidth, Qt::SolidLine, Qt::RoundCap,Qt::RoundJoin));
    // here draw your path
    // for example if your path can be made of lines, 
    // or you just put the points if they are close from each other
  }

  //other painting here
}

如果毕竟这一切你没有一个好的渲染,尝试使用浮点精度(较慢),即QMouseEvent::posF()而不是QMouseEvent::pos().

编辑:
“我想知道是否有任何方法可以计算我们作为参数发送给drawLine的任何两个像素之间的所有子像素”
是的。我不知道你为什么需要做这样的事情,但真的很简单。一条线可以用等式来表征

   y = ax + b

线的两个端点p0 = (x0, y0)和都p1 = (x1, y1)满足这个方程,所以你可以很容易地找到ab。现在您需要做的就是从x0到增加x1您想要的像素数量(比如 1),并计算相应的y值,每次都 save point(x,y)

因此,将检查保存的所有点,pixelList并对任意两个连续点重复此过程。

于 2012-03-13T12:54:10.810 回答