1. 概述
这一节我们用QLabel+QTimer来做一个旋转的圆形音乐封面,实现以下几个功能:
-
自动将封面图转换成圆形
-
可以启动/停止旋转
-
可以控制旋转速度
2. 实现
创建一个rotatingcover模块,包含RotatingCover类,继承自QLabel:
rotatingcover
- rotatingcover.pri
- rotatingcover.h
- rotatingcover.cpp
主要思路如下:
-
设置一个旋转角度m_angle,初始为0
-
设置一个定时器m_timer,每interval毫秒触发一次,执行两个操作
-
++m_angle
-
update()
-
-
update操作会触发paintEvent事件,重载这个事件,根据m_angle绘制圆形封面
调用m_timer的start/stop接口就可以实现旋转的启动/停止,而控制interval的值就可以控制旋转的速度(越小越快),这部分代码如下:
// rotatingcover.h
class QTimer;
class RotatingCover : public QLabel {
Q_OBJECT
public:
RotatingCover(QWidget *parent = nullptr, Qt::WindowFlags f = Qt::WindowFlags());
virtual ~RotatingCover() = default;
void start(int interval = 100);
void stop();
private:
int m_angle = 0;
QTimer *m_timer = nullptr;
};
// rotatingcover.cpp
RotatingCover::RotatingCover(QWidget *parent, Qt::WindowFlags f) : QLabel(parent, f) {
m_timer = new QTimer(this);
connect(m_timer, &QTimer::timeout, this, [=]() {
++m_angle;
update();
});
}
void RotatingCover::start(int interval) { m_timer->start(interval); }
void RotatingCover::stop() { m_timer->stop(); }
绘制的部分如下:
void RotatingCover::paintEvent(QPaintEvent *ev) {
Q_UNUSED(ev)
if (!pixmap().isNull()) {
QPainter painter(this);
painter.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform);
QPainterPath path;
int radius = qMin(width(), height());
path.addEllipse(0, 0, radius, radius);
painter.setClipPath(path);
painter.resetTransform();
painter.translate(width() / 2, height() / 2);
painter.rotate(m_angle);
painter.translate(-width() / 2, -height() / 2);
painter.drawPixmap(0, 0, width(), height(), pixmap());
}
}
不过频繁地调用update会有性能损耗,导致界面卡顿,后续再想想其它实现方案。
PS: 代码已经开源在github:linqiaqun/music-player: A cross platform music player (github.com) 欢迎star/fork/issue