我们知道,为了在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();
}
答案 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)
的两个端点都满足此等式,因此您可以轻松找到a
和b
。现在,您需要做的就是从x0
增加到x1
的数量
您想要的像素(比如1),并计算相应的y
值,每次保存point(x,y)
。
因此,将覆盖pixelList
中保存的所有点,并对任意两个连续点重复此过程。