How can I smoothly grow an angle/length-changing Arc with Qt QPainter? Here is minimum code I just created from Qt's Analog Clock Window Example.
The code randomly changes m_value +- 5 in 50-millisecond. This is to simulate the actual behavior I want to achieve. The arc starts at 12 O'clock position and grow counter-clockwise. m_value is scaled to fit 360 degree (12 O'clock to 12 O'clock).
My goal is to smoothly change the length of arc, in real-time, in response to the (simulated) value given, regardless of input value jitters.
I want to accomplish 2 things:
- Smooth redraw of the arc. The current code directly redraw the value at the time. I does not even use sub angle value. The result is visually noisy at the end of the arc.
- Update the drawing in along with V-Sync. So that I don't waste
computation power for non-displayed redraw. I don't know how to
trigger
renderevent by V-Sync, so I've setup 33-millisecond timer. This is needed whenm_valuechanges in less than 30 msec.
What I don't want
- QtQuick. I'm looking for QPainter way to do it.
Platform I'm using:
- Qt 5.x
- on Debian Linux (If it matters)
#include <QtGui>
#include "rasterwindow.h"
class SmoothArc : public RasterWindow
{
public:
SmoothArc();
protected:
void timerEvent(QTimerEvent *) Q_DECL_OVERRIDE;
void render(QPainter *p) Q_DECL_OVERRIDE;
private:
int m_timerId;
int m_valueTimerId;
int m_value = 50;
};
SmoothArc::SmoothArc()
{
setTitle("Smooth Arc");
resize(200, 200);
m_timerId = startTimer(33);
m_valueTimerId = startTimer(100);
}
void SmoothArc::timerEvent(QTimerEvent *event)
{
if (event->timerId() == m_timerId)
renderLater();
if (event->timerId() == m_valueTimerId) {
m_value = m_value + (qrand() % 11 - 5);
if (m_value > 100) m_value = 100;
if (m_value < 0) m_value = 0;
}
}
void SmoothArc::render(QPainter *p)
{
p->setRenderHint(QPainter::Antialiasing);
int side = qMin(width(), height());
p->scale(side / 200.0, side / 200.0);
QRectF rect(10, 10, 180, 180);
QPen pen = p->pen();
pen.setWidth(10);
p->setPen(pen);
p->drawArc(rect, 90*16, (360*(m_value/100.0))*16);
}
int main(int argc, char **argv)
{
QGuiApplication app(argc, argv);
SmoothArc arc;
arc.show();
return app.exec();
}
Complete code is at https://github.com/yashi/smooth-arc. Usual build process like the following should work.
git clone https://github.com/yashi/smooth-arc.git
cd smooth-arc
qmake
make
./smooth-arc

git clone https://github.com/yashi/smooth-arc.git; cd smooth-arc; qmake; make; ./smooth-arcshould work - Yasushi Shojiqrand(). No special meaning. My goal is to smoothly change the length of arc, in real-time, in response to the current value given, regardless of input value jitters. - Yasushi ShojiRasterWindow? - Mitch