Я довольно новичок в QT и не могу понять, почему мои дуги нарисованы так плохо.
У меня 2 проблемы.
Первый, который я считаю нормальным для такого рисунка, это:
Если я рисую с помощью QPainterPath, прямая линия будет нарисована на каждой дуге, от конца дуги до направления точки 0,0, но не полностью до 0,0, вместо этого, я думаю, это просто половина пути к этому. точка …
Второй:
Если я использую QPainterPath или painter.drawArc, «кольца» будут несеметрическими, если я изменю ширину пера.
У меня есть этот код, который будет инициализировать мой Арк.
//Редактировать//
Извините, забыл указать, где 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)
Это вывод с painter.drawArc
//Редактировать//
Ожидаемый результат должен быть примерно таким. Обратите внимание, что зеленый кружок spanAngle отличается от двух изображений выше, потому что я сделал результат с фотошопом, и это было проще с этими spanAngles 🙂
Это должно дать понять, в чем заключается моя проблема.
После тестирования с drawEllipse я узнаю то же поведение, что ширина пера меньше на 45 часов, чем на 90 часов.
Кто-нибудь может помочь мне избавиться от этих проблем? Я также счастлив с различными решениями, чтобы получить такие открытые кольца.
с уважением,
PrDatur
Есть 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
больше чем maxValue
, Также вы должны опустить this->
при доступе к ученикам.
В случае каких-либо проблем с моим кодом, проверьте полный файл Я использовал, чтобы проверить это.
Других решений пока нет …