Qt 沿着圆形路径移动文本
Qt move text following a circular path
我正在使用 Qt5 制作一个简单的模拟时钟,我有打印当前时间的想法,例如秒针上方的当前秒数。所以保存秒值的文本会随着时钟移动。
我目前的情况是这样的
painter.save();
painter.setPen(Qt::NoPen);
pen.setBrush(Qt::white);
painter.rotate(360 * (time.second() / 60.0));
painter.drawEllipse(QPointF(0,30), 9, 9);
painter.restore();
painter.save();
QRect rec(0, 30, 10, 10);
painter.setPen(Qt::black);
QFont font = painter.font() ;
font.setPointSize(ampmTextSize());
painter.setFont(font);
QFontMetrics fm(font);
int pixelsWide = fm.width(time.toString("ss a").left(2));
int pixelsHigh = fm.height();
rec.setWidth(pixelsWide);
rec.setHeight(pixelsHigh);
painter.rotate(360 * (time.second() / 60.0));
painter.drawText(rec, Qt::AlignCenter, time.toString("ss"));
painter.restore();
哪个诅咒是不正确的,因为它会导致文本旋转,如图所示
有没有人知道如何在 Qt 中正确实现这种效果?
编辑
我忘了提到的是,我希望有一个涉及 Qt 函数的解决方案,而不是使用圆的参数方程或一些类似的解决方案,因为这只是一个练习,所以我可以训练自己使用 Qt。
如果我们只是想获得我想要遵循的坐标以追踪时钟秒针的尖端,那么像这里的方程式就足够了
int posx = cos(((360 * (time.second() / 60.0)) * M_PI / 180) - ((90) * M_PI / 180)) * 30.0 + 0;
int posy = sin(((360 * (time.second() / 60.0)) * M_PI / 180) - ((90) * M_PI / 180)) * 30.0 + 0;
然而,我更感兴趣的是学习一种使用 Qt 提供的画家来执行此操作的有效方法。
你让你的生活变得复杂?为什么要在单个对象中执行此操作?
您可以使用几个 QGgraphicsViewItem
轻松地做到这一点,并且不需要绘制实现!你会避免很多绘画和表演的问题。
此外,如果您需要添加一些鼠标功能,这将更容易做到。
我使用 QGraphicsView
实现了一个快速示例:
#include "analogclock.h"
#include <QTimer>
#include <QVector>
#include <QVector>
#include <QTime>
#include <QGraphicsItem>
#include <cmath>
AnalogClock::AnalogClock(QWidget *parent)
: QGraphicsView(parent)
{
QTimer *timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(timeout()));
timer->start(1000);
setWindowTitle(tr("Analog Clock"));
resize(200, 200);
QGraphicsScene* scene = new QGraphicsScene();
setScene(scene);
scene->setSceneRect(QRect(-70,-70,140,140));
static const QVector<QPointF> hourHand(QVector<QPointF>()
<< QPointF(7, 8)
<< QPointF(-7, 8)
<< QPointF(0, -40) );
static const QVector<QPointF> minuteHand( QVector<QPointF>()
<< QPoint(7, 8)
<< QPoint(-7, 8)
<< QPoint(0, -70) );
QColor hourColor(127, 0, 127);
QColor minuteColor(0, 127, 127, 191);
m_hour = scene->addPolygon(QPolygonF(hourHand), QPen(), QBrush(hourColor));
m_minute = scene->addPolygon(QPolygonF(minuteHand), QPen(), QBrush(minuteColor));
m_text = scene->addText("");
timeout();
}
AnalogClock::~AnalogClock() { }
// This is a protected slot:
void AnalogClock::timeout()
{
QTime time = QTime::currentTime();
m_hour->setRotation(30.0 * ((time.hour() + time.minute() / 60.0)));
qreal mAngle(6.0 * ((time.minute() + time.second() / 60.0)));
m_minute->setRotation(mAngle);
m_text->setPos(70.0 * std::sin(mAngle * M_PI / 180.0), -70.0 * std::cos(mAngle * M_PI / 180.0));
m_text->setPlainText(QString("%1").arg(time.minute()));
}
对于 main.cpp
和头文件,您可以使用 Qt AnalogClock 示例并将其余成员作为私有变量添加到其中。
我正在使用 Qt5 制作一个简单的模拟时钟,我有打印当前时间的想法,例如秒针上方的当前秒数。所以保存秒值的文本会随着时钟移动。
我目前的情况是这样的
painter.save();
painter.setPen(Qt::NoPen);
pen.setBrush(Qt::white);
painter.rotate(360 * (time.second() / 60.0));
painter.drawEllipse(QPointF(0,30), 9, 9);
painter.restore();
painter.save();
QRect rec(0, 30, 10, 10);
painter.setPen(Qt::black);
QFont font = painter.font() ;
font.setPointSize(ampmTextSize());
painter.setFont(font);
QFontMetrics fm(font);
int pixelsWide = fm.width(time.toString("ss a").left(2));
int pixelsHigh = fm.height();
rec.setWidth(pixelsWide);
rec.setHeight(pixelsHigh);
painter.rotate(360 * (time.second() / 60.0));
painter.drawText(rec, Qt::AlignCenter, time.toString("ss"));
painter.restore();
哪个诅咒是不正确的,因为它会导致文本旋转,如图所示
有没有人知道如何在 Qt 中正确实现这种效果?
编辑 我忘了提到的是,我希望有一个涉及 Qt 函数的解决方案,而不是使用圆的参数方程或一些类似的解决方案,因为这只是一个练习,所以我可以训练自己使用 Qt。
如果我们只是想获得我想要遵循的坐标以追踪时钟秒针的尖端,那么像这里的方程式就足够了
int posx = cos(((360 * (time.second() / 60.0)) * M_PI / 180) - ((90) * M_PI / 180)) * 30.0 + 0;
int posy = sin(((360 * (time.second() / 60.0)) * M_PI / 180) - ((90) * M_PI / 180)) * 30.0 + 0;
然而,我更感兴趣的是学习一种使用 Qt 提供的画家来执行此操作的有效方法。
你让你的生活变得复杂?为什么要在单个对象中执行此操作?
您可以使用几个 QGgraphicsViewItem
轻松地做到这一点,并且不需要绘制实现!你会避免很多绘画和表演的问题。
此外,如果您需要添加一些鼠标功能,这将更容易做到。
我使用 QGraphicsView
实现了一个快速示例:
#include "analogclock.h"
#include <QTimer>
#include <QVector>
#include <QVector>
#include <QTime>
#include <QGraphicsItem>
#include <cmath>
AnalogClock::AnalogClock(QWidget *parent)
: QGraphicsView(parent)
{
QTimer *timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(timeout()));
timer->start(1000);
setWindowTitle(tr("Analog Clock"));
resize(200, 200);
QGraphicsScene* scene = new QGraphicsScene();
setScene(scene);
scene->setSceneRect(QRect(-70,-70,140,140));
static const QVector<QPointF> hourHand(QVector<QPointF>()
<< QPointF(7, 8)
<< QPointF(-7, 8)
<< QPointF(0, -40) );
static const QVector<QPointF> minuteHand( QVector<QPointF>()
<< QPoint(7, 8)
<< QPoint(-7, 8)
<< QPoint(0, -70) );
QColor hourColor(127, 0, 127);
QColor minuteColor(0, 127, 127, 191);
m_hour = scene->addPolygon(QPolygonF(hourHand), QPen(), QBrush(hourColor));
m_minute = scene->addPolygon(QPolygonF(minuteHand), QPen(), QBrush(minuteColor));
m_text = scene->addText("");
timeout();
}
AnalogClock::~AnalogClock() { }
// This is a protected slot:
void AnalogClock::timeout()
{
QTime time = QTime::currentTime();
m_hour->setRotation(30.0 * ((time.hour() + time.minute() / 60.0)));
qreal mAngle(6.0 * ((time.minute() + time.second() / 60.0)));
m_minute->setRotation(mAngle);
m_text->setPos(70.0 * std::sin(mAngle * M_PI / 180.0), -70.0 * std::cos(mAngle * M_PI / 180.0));
m_text->setPlainText(QString("%1").arg(time.minute()));
}
对于 main.cpp
和头文件,您可以使用 Qt AnalogClock 示例并将其余成员作为私有变量添加到其中。