1

我对 QT 很陌生,我不明白为什么我的弧线画得这么差。我有2个问题。

第一个,我认为对于这种绘图来说是正常的,是:如果我使用 QPainterPath 绘制一条直线,将在每个弧上绘制一条直线,从弧的末端到点 0,0 的方向,但不完全到 0 ,0 相反,它只是,我认为,到那一点的一半......

第二个:如果我使用 QPainterPath 或painter.drawArc 如果我改变笔宽,“环”是不均匀的。

我有这段代码将初始化我的 Arc。

//编辑// 抱歉忘记提供 w 和 h 的创建位置。this->getMainWidget() 只返回一个 QWidget,我的元素在其中绘制。顶层小部件的几何形状和位置与 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 个弧。第一个和第三个的笔宽相同,均为 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) 在这张图片中,线路问题的第一个问题也存在。 (QPainterPath)

这是painter.drawArc的输出 这是painter.drawArc的输出

//Edit// 预期的结果应该是这样的。请注意,绿色圆圈 spanAngle 与上面的 2 张图片不同,因为我使用 Photoshop 制作了结果,使用这些 spanAngle 更容易:) 在此处输入图像描述

它应该清楚地知道我的问题是什么。在使用 drawEllipse 进行测试后,我发现笔宽在 45 时钟时比在 90 时钟时更小的行为相同。

任何人都可以帮助我摆脱这些问题吗?我也很高兴有不同的解决方案来获得这种打开的戒指。

最好的问候, PrDatur

4

1 回答 1

4

有2个问题。首先是弧的起点取决于笔的宽度。它可以通过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大于maxValuethis->访问类成员时也应该省略。

如果我的代码有任何问题,请检查我用来测试它的完整文件。

于 2013-06-15T11:16:52.827 回答