我对QT很陌生,我无法理解为什么我的弧线如此糟糕。 我有两个问题。
第一个,我认为这种绘图是正常的,是: 如果我使用QPainterPath绘制一条直线将绘制在每个弧上,从弧的末端到点0,0的方向,但不完全是0,0而不是它只是,我认为,只有一半到那个点...
第二个: 如果我使用QPainterPath或painter.drawArc,如果我改变笔的宽度,“环”是不显着的。
我有这个代码,它将启动我的Arc。
// //编辑 抱歉忘了提供创建w和h的位置。 this-> getMainWidget()只返回我绘制元素的QWidget。 toplevel小部件的几何和位置以及this-> getMainWidget()中的一个是相同的。
QRect mainWidgetGeo = geometry();
int w = mainWidgetGeo.width();
int h = mainWidgetGeo.height();
QPen secondPen(Qt::yellow);
secondPen.setWidth(50);
circleSeconds = new Circle(this->getMainWidget());
circleSeconds->setMaxValue(60);
circleSeconds->setValue(55);
circleSeconds->setSteps(60);
circleSeconds->setMouseTracking(true);
circleSeconds->setPen(secondPen);
circleSeconds->setGeometry(QRect(0, 0, w, h));
QPen minutePen(Qt::red);
minutePen.setWidth(100);
circleMinutes = new Circle(this->getMainWidget());
circleMinutes->setMaxValue(60);
circleMinutes->setValue(50);
circleMinutes->setSteps(60);
circleMinutes->setMouseTracking(true);
circleMinutes->setPen(minutePen);
circleMinutes->setGeometry(QRect(50, 50, w-100, h-100));
QPen hourPen(Qt::green);
hourPen.setWidth(50);
circleHours = new Circle(this->getMainWidget());
circleHours->setMaxValue(12);
circleHours->setValue(45);
circleHours->setSteps(12);
circleHours->setMouseTracking(true);
circleHours->setPen(hourPen);
circleHours->setGeometry(QRect(150, 150, w-300, h-300));
这将设置3个Arc。 第一个和第三个具有相同的笔宽度50,第二个具有100。
完成此处的是Circle类:
#include <QtGui>
#include "Circle.h"
#include <QDebug>
Circle::Circle(QWidget *parent): QWidget(parent)
{
}
void Circle::setSteps(int i)
{
this->steps = i;
}
void Circle::setValue(int i)
{
this->value = i;
repaint();
}
void Circle::setMaxValue(int i)
{
this->maxValue = i;
}
void Circle::paintEvent(QPaintEvent *)
{
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing, true);
painter.setPen(this->pen);
int stepSize = 360/this->steps;
float devideValue = ((100.0/this->maxValue)*this->value)/100.0;
int roundedSize = this->steps*devideValue;
int angel = -1.0*16.0*(stepSize*roundedSize);
qDebug() << "steps: " << steps;
qDebug() << "stepSize: " << stepSize;
qDebug() << "devideValue: " << devideValue;
qDebug() << "roundedSize: " << roundedSize;
qDebug() << "stepSize*roundedSize: " << (stepSize*roundedSize);
qDebug() << "angel: " << angel;
qDebug() << "angel: " << angel;
painter.drawArc(this->pen.width()/2, this->pen.width()/2, this->geometry().width()-(this->pen.width()), this->geometry().height()-(this->pen.width()), 0, angel);
/*QPainterPath circle_path;
circle_path.arcTo(this->pen.width()/2, this->pen.width()/2, this->geometry().width()-(this->pen.width()), this->geometry().height()-(this->pen.width()), 0, angel);
painter.drawPath(circle_path);*/
}
void Circle::setPen(QPen pen)
{
this->pen = pen;
}
另外我注意到,如果笔的宽度与其他弧的不同,每个笔宽的“起点0”都不同......
以下是输出,以便更好地了解出现了什么问题。
在此图片中,线问题的第一个问题也出现了。 (QPainterPath)
这是painter.drawArc的输出
// //编辑 预期的结果应该是这样的。请注意,绿色圆圈spanAngle与上面的2个图像不同,因为我使用photoshop完成了结果,并且使用那些spanAngles更容易:)
它应该让它清楚我的问题是什么。 在使用drawEllipse进行测试后,我认识到相同的行为,即笔时的宽度在45时钟时小于90时。
有人可以帮助我摆脱这些问题吗?我也很高兴有不同的解决方案来获得这样的开放戒指。
最好的问候, PrDatur
答案 0 :(得分:3)
有两个问题。首先是弧的起点取决于笔的宽度。对于每个使用过的笔,可以通过设置pen.setCapStyle(Qt::FlatCap);
轻松修复。
第二个问题是弧之间未填充的空间。我不明白为什么会这样。它与Qt的QPen / QPainter系统有某种联系,但我找不到任何方法来修复它。
然而,我找到了一个解决方法。创建包含图形的边框的相应QPainterPath
,然后使用QPainter::fillPath
而不是用笔抚摸。
一项附带任务是使用QPainterPath::moveArcTo
来移动和划线。据我所知,它不受支持。我们需要以下辅助函数,它将与QPainterPath::lineTo
方法一起使用:
QPointF my_find_ellipse_coords(const QRectF &r, qreal angle) {
QPainterPath path;
path.arcMoveTo(r, angle);
return path.currentPosition();
}
在paintEvent
函数中:
double angle = -1.0*(stepSize*roundedSize); // removed '*16' here
QPainterPath path;
QRectF outer_rect(0, 0, width(), height());
QRectF inner_rect(pen.width(), pen.width(),
width() - pen.width() * 2, height() - pen.width() * 2);
path.arcMoveTo(outer_rect, 0);
path.arcTo(outer_rect, 0, angle);
path.lineTo(my_find_ellipse_coords(inner_rect, angle));
path.arcTo(inner_rect, angle, -angle);
path.lineTo(my_find_ellipse_coords(outer_rect, 0));
path.closeSubpath();
painter.fillPath(path, QBrush(pen.color()));
您的代码中还有一些其他小问题。对于circleHours
,您已将value
设置为大于maxValue
。此外,您在访问班级成员时应省略this->
。
如果我的代码出现任何问题,请查看我用来测试它的complete file。