前言
之前的宠物为静态图片,今天实现了它能够播放音乐并且在移动的过程中能够样子也在动,我们的大鹅因为没有ui只能用一个动漫少女来代替。
播放音乐功能
通过使用QMovie类,来加载GIF图片,然后通过定时器的方式不断显示当前图片,QMovie 的构造函数接受三个参数:GIF 文件的路径、一个 QByteArray 对象和一个 QObject 对象。
m_gooseMovie->start() 调用了 QMovie 类中的 start() 函数,开始播放 GIF 动画
在backgroundWidget::paintEvent()函数中,不再直接绘制大鹅的静态图片,而是使用QPainter的drawPixmap()函数绘制当前的QMovie帧:
painter.drawPixmap(0, 0, width(), height(), m_gooseMovie->currentPixmap());
更新我们宠物的绘制widget.c如下:
#include "backgroundwidget.h"
#include "ui_backgroundwidget.h"
backgroundWidget::backgroundWidget(QWidget *parent) :
QWidget(parent),
ui(new Ui::backgroundWidget)
{
ui->setupUi(this);
//setAttribute(Qt::WA_TranslucentBackground);
m_gooseMovie = new QMovie(":/image/background/goose.gif", QByteArray(), this);
m_gooseMovie->start();
}
backgroundWidget::~backgroundWidget()
{
delete ui;
}
void backgroundWidget::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
//QPixmap goosePixmap(":/image/background/goose.png"); // 加载大鹅图片
//painter.drawPixmap(0, 0, width(), height(), goosePixmap); // 绘制大鹅图片
painter.drawPixmap(0, 0, width(), height(), m_gooseMovie->currentPixmap());
}
void backgroundWidget::updateGoose()
{
update();
}
最下面的更新信号槽,我们在大鹅移动的线程中增加一个信号,在发送位置信息时发送这个更新信号;在我们的主页面进行关联:
connect(m_gooseThread, &GooseThread::updateGoose, m_backgroundWidget, &backgroundWidget::updateGoose);
这样就实现了在移动时不停的更新关键帧,实现了大鹅动的问题
用ps和pr扣了很久,就先让她来代替大鹅吧。
音乐播放功能
主要使用QMediaPlayer和QMediaPlaylist类来播放音乐文件然后通过使用水平滑块控件(QSlider)实现音乐的拖动和调节音乐播放位置
直接上代码:
musicwidget.h文件
#ifndef MUSICWIDGET_H
#define MUSICWIDGET_H
#include <QWidget>
#include <QtMultimedia/QMediaPlayer>
#include <QMediaPlaylist>
namespace Ui {
class musicWidget;
}
class musicWidget : public QWidget
{
Q_OBJECT
public:
explicit musicWidget(QWidget *parent = nullptr);
~musicWidget();
private slots:
void on_m_buttonPrevious_clicked();
void on_m_buttonNext_clicked();
void on_horizontalSlider_music_valueChanged(int value);
void on_m_buttonPlayPause_clicked(bool checked);
private:
Ui::musicWidget *ui;
QMediaPlayer *player;//播放器
QMediaPlaylist *playList;//播放列表
QString playBackTime;//当前播放时间
QString totalLengthTime;//总长度
void setMusic();
};
#endif // MUSICWIDGET_H
musicwidget.c文件
#include "musicwidget.h"
#include "ui_musicwidget.h"
#include <QDebug>
musicWidget::musicWidget(QWidget *parent) :
QWidget(parent),
ui(new Ui::musicWidget)
{
ui->setupUi(this);
//初始化音乐
setMusic();
//player->play();
}
musicWidget::~musicWidget()
{
delete ui;
}
void musicWidget::on_m_buttonPrevious_clicked()
{
qDebug() << "1";
}
void musicWidget::on_m_buttonNext_clicked()
{
qDebug() << "1";
}
void musicWidget::setMusic()
{
player = new QMediaPlayer;
playList = new QMediaPlaylist;
playList->setPlaybackMode(QMediaPlaylist::Loop);//设置循环播放模式
player->setPlaylist(playList);//将播放列表设置给音乐播放器。
connect(player,&QMediaPlayer::positionChanged,[=](qint64 duration){//positionChanged信号在音乐播放位置发生改变时发出
if(ui->horizontalSlider_music->isSliderDown())
{
return;
}
ui->horizontalSlider_music->blockSignals(true);
ui->horizontalSlider_music->setSliderPosition(duration);
ui->horizontalSlider_music->blockSignals(false);
int secs = int(duration)/1000;//将毫秒数转换成秒数
int min = secs/60;
secs = secs%60;//计算音乐播放的剩余秒数
playBackTime = QString::asprintf("%d:%d",min,secs);
ui->musicTime->setText(playBackTime);
});
connect(player,&QMediaPlayer::durationChanged,[=](qint64 duration){//durationChanged信号在音乐的时长发生改变时发出
ui->horizontalSlider_music->setMaximum(int(duration));
int secs = int(duration)/1000;
int min = secs/60; //取整
secs = secs%60; //剩余秒
totalLengthTime = QString::asprintf("%d:%d",min,secs);
ui->musicTimeMax->setText(totalLengthTime);
});
ui->m_buttonPlayPause->setCheckable(true);
//加载音乐
playList->addMedia(QUrl::fromLocalFile("./music/music.mp3"));
//playList->addMedia(QUrl::fromLocalFile("qrc:/images/music.mp3"));
playList->setCurrentIndex(0);
}
void musicWidget::on_horizontalSlider_music_valueChanged(int value)
{
player->blockSignals(true);
player->setPosition(value);
player->blockSignals(false);
}
void musicWidget::on_m_buttonPlayPause_clicked(bool checked)
{
if(checked)
{
qDebug() << "2";
player->pause();
}
else {
qDebug() << "1";
player->play();
}
}
等我完善完功能后会将工程给出,欢迎大佬们在评论区指导。