如何在使用drawLine时跟踪缺失的像素

时间:2012-03-13 08:04:54

标签: qt qt4 qpainter

我们知道,为了在qt中绘制图像,使用qpainter。最近,我使用drawLine()函数绘制用户正在涂鸦的内容。这是通过将lastM和currentPoint从mouseMoveEvent传递给实现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();
}

1 个答案:

答案 0 :(得分:2)

首先,不要画一个mouseEvent()。实际上应该尽快处理mouseevent。此外,查看Qt源并不是一个好主意,它可能会令人困惑。而是假设Qt给你的工作,并首先尝试回答“我做错了什么?”。正如我所说,在鼠标事件中画画肯定是错误的。

您的描述非常主观,也许您的输出图像更好。你想模仿一支笔(就像在窗户上画画一样)吗?在这种情况下,鼠标按钮是否必须关闭?这是你的变量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
}

如果在所有这些之后你没有很好的渲染,请尝试使用float精度(较慢),即QMouseEvent::posF()而不是QMouseEvent::pos()

编辑:
“我想知道是否有办法计算我们作为drawLine参数发送的任意两个像素之间的所有子像素”
就在这里。我不知道为什么你需要做这样的事情但很简单。线可以用等式

表征
   y = ax + b

p0 = (x0, y0)p1 = (x1, y1)的两个端点都满足此等式,因此您可以轻松找到ab。现在,您需要做的就是从x0增加到x1的数量 您想要的像素(比如1),并计算相应的y值,每次保存point(x,y)

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