1.先上结果 和 代码
头文件:
#ifndef VIDEOPLAYER_H
#define VIDEOPLAYER_H
#include <QWidget>
#include <QObject>
#include <QVideoWidget>
#include <QMediaPlayer>
#include <QAudioOutput>
#include <QSqlDatabase>
#include <QSqlQuery>
#include <QSqlError>
class videoPlayer : public QWidget
{
Q_OBJECT
public:
videoPlayer(QString bg, QWidget* parent = nullptr);
QString formatTime(qint64 time);
void getListFromDB(void);
private slots:
private:
QMediaPlayer* player;
QVideoWidget* videoWidget;
QAudioOutput* audioOutput;
QStringList* filepathList;
int curListIndex = 0;
QSqlDatabase database;// 用于建立和数据库的连接
signals:
};
#endif // VIDEOPLAYER_H
源文件
#include "videoplayer.h"
#include <QGridLayout>
#include <QPalette>
#include <QLabel>
#include <QPixmap>
#include <QPushButton>
#include <QSlider>
#include <QSpacerItem>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QDir>
#include <QFileDialog>
#include <QMessageBox>
#include <QAudioFormat>
#include <QTimer>
videoPlayer:: videoPlayer(QString bg, QWidget* parent)
{
this->setParent(parent);
filepathList = new QStringList();
/***********************************************************************main widget***********************************************************************/
QWidget* widget = new QWidget(this);
QGridLayout* grid = new QGridLayout(widget);
widget->setFixedSize(400, 300);
this->move((parent->width()-widget->width())/2, (parent->height()-widget->height())/2);
widget->setStyleSheet(QString(".QWidget{background-color:rgba(200,100,186,10);}").append(".QWidget{border-image:url(")
.append(bg).append(");background-repeat:no-repeat;background-position:center;}")
.append(".QWidget{border:1px solid black;}")
.append(".QWidget{border-radius:10px;}")
.append("QSlider::groove:horizontal {border: 0px solid #bbb;}")
.append("QSlider::sub-page:horizontal{background:rgb(180,60,140);border-radius:4px;margin-top:7px;margin-bottom:7px;}")
.append("QSlider::add-page:horizontal{background:rgb(238,152,10);border:0px solid #777;border-radius:3px;margin-top:9px;margin-bottom:9px;}")
.append("QSlider::handle:horizontal{background:rgb(163,77,89);width: 10px;border:1px solid rgb(193,204,208);border-radius:4px;margin-top:4px;margin-bottom:4px;}")
.append("QSlider::handle:horizontal:hover{background:rgb(163,77,89);width: 10px;border:1px solid rgb(193,204,208);border-radius:5px; margin-top:4px;margin-bottom:4px;}")
/*.append(".QSlider{border:1px solid black;{border-radius:10px;}")*/
);
widget->move(0,0);
QFont font("华文新魏",10);
QPixmap pix;
QVBoxLayout* vedoLayout = new QVBoxLayout;
videoWidget = new QVideoWidget(widget);
// QLabel* vedo = new QLabel("lalala",widget);
// vedo->resize(200,200);
// vedo->setPixmap(QPixmap(":/pic/lotso (12).jpg"));
vedoLayout->addWidget(videoWidget);
QLabel* totalTimeLabel = new QLabel("00:00:00",widget);totalTimeLabel->setFont(font);
QLabel* voiceTitleLabel = new QLabel("音量",widget);voiceTitleLabel->setFont(font);voiceTitleLabel->setFixedSize(30,30);voiceTitleLabel->setAlignment(Qt::AlignJustify|Qt::AlignVCenter);
voiceTitleLabel->setPixmap(QPixmap(":/vedioRes/volumn.png").scaled(30,30));
QLabel* voiceLabel = new QLabel("100",widget);voiceLabel->setFont(font);voiceLabel->setFixedWidth(30);voiceLabel->setAlignment(Qt::AlignJustify|Qt::AlignVCenter);
QPushButton* startBtn = new QPushButton(widget);startBtn->setFixedSize(40,30);startBtn->setStyleSheet("QPushButton{border:0px;border-image:url(:/vedioRes/start.png)}");
QPushButton* stopBtn = new QPushButton(widget);stopBtn->setFixedSize(40,30);stopBtn->setStyleSheet("QPushButton{border:0px;border-image:url(:/vedioRes/pause_no.png)}");
QPushButton* nextBtn = new QPushButton(widget);nextBtn->setFixedSize(40,30);nextBtn->setCheckable(true);nextBtn->setChecked(false);nextBtn->setStyleSheet("QPushButton{border:0px;border-image:url(:/vedioRes/next.png)}QPushButton:pressed{border:0px;border-image:url(:/vedioRes/next_no.png)}");
QPushButton* replayBtn = new QPushButton(widget);replayBtn->setFixedSize(40,30);replayBtn->setCheckable(true);replayBtn->setChecked(false);replayBtn->setStyleSheet("QPushButton{border:0px;border-image:url(:/vedioRes/replay_no.png)}QPushButton:checked{border-image:url(:/vedioRes/replay.png)}");
qDebug()<<QString("the button is %1").arg(nextBtn->isChecked());
QSlider* processSlider = new QSlider(Qt::Horizontal,widget);
QSlider* voiceSlider = new QSlider(Qt::Horizontal,widget);voiceSlider->setFixedWidth(70);voiceSlider->setMaximum(100);voiceSlider->setRange(0,100);voiceSlider->setValue(100);
QSpacerItem* spacer = new QSpacerItem(100,30);
grid->addLayout(vedoLayout, 0,0,1,7);//grid->addWidget(vedo, 0,0,1,7);
grid->addWidget(processSlider, 1,0,1,6);
grid->addWidget(totalTimeLabel, 1,6);
grid->addWidget(startBtn, 2,0);
grid->addWidget(stopBtn, 2,1);
grid->addWidget(nextBtn, 2,2);
grid->addWidget(replayBtn, 2,3);
//grid->addItem(spacer, 2,3);
grid->addWidget(voiceTitleLabel,2,4);
grid->addWidget(voiceSlider, 2,5);
QHBoxLayout* layout = new QHBoxLayout;
QSpacerItem* spacerTemp = new QSpacerItem(6,30);
layout->addSpacerItem(spacerTemp);
layout->addWidget(voiceLabel);
QLabel* labtemp = new QLabel(widget);labtemp->setPixmap(QPixmap(":/pic/lotso (20).jpg").scaled(30,30));
layout->addWidget(labtemp);
grid->addLayout(layout, 2,6);//grid->addWidget(voiceLabel,2,6);d
//voiceSlider->setStyleSheet("QSlider{border:0px solid #bbb;border-radius:0px;}");
voiceSlider->setStyleSheet(QString("QSlider::groove:horizontal {border: 0px solid #bbb;}")
.append("QSlider::sub-page:horizontal{background:rgb(180,60,140);border-radius:4px;margin-top:7px;margin-bottom:7px;}")
.append("QSlider::add-page:horizontal{background:rgb(238,152,10);border:0px solid #777;border-radius:3px;margin-top:9px;margin-bottom:9px;}")
.append("QSlider::handle:horizontal{background:rgb(163,77,89);width: 10px;border:1px solid rgb(193,204,208);border-radius:4px;margin-top:4px;margin-bottom:4px;}")
.append("QSlider::handle:horizontal:hover{background:rgb(163,77,89);width: 10px;border:1px solid rgb(193,204,208);border-radius:5px; margin-top:4px;margin-bottom:4px;}")
);
/***********************************************************************logic***********************************************************************/
player = new QMediaPlayer(this);
audioOutput = new QAudioOutput(this);
player->setVideoOutput(videoWidget);
player->setAudioOutput(audioOutput);//player->audioOutput()->setVolume(1);
void (QSlider:: *sliderValueChangedSignal)(int) = &QSlider::valueChanged;
void (QLabel:: *labelSetNumSlot)(int) = &QLabel::setNum;
connect(player,&QMediaPlayer::positionChanged,[=](qint64 position){
if(player->duration() > 0)
{
int progress = static_cast<int>(position);
processSlider->setValue(progress);
totalTimeLabel->setText(formatTime(position));
//重播
if(position == player->duration())
{
player->stop();
if(replayBtn->isChecked() == true)
{
QTimer::singleShot(500,[=](){
player->play();
});
}
else
{
QTimer::singleShot(1000,[=](){
curListIndex++;
if(curListIndex<filepathList->count())
{
player->setSource(QUrl::fromLocalFile(filepathList->at(curListIndex)));
}
else
{
curListIndex = 0;
player->setSource(QUrl::fromLocalFile(filepathList->at(curListIndex)));
}
player->play();
});
}
}
}
});
connect(processSlider, &QAbstractSlider::sliderMoved, [=](int pos){
qint64 progress = static_cast<qint64>(pos);
if(player->duration() > 0)
{
player->setPosition(progress);
}
});
connect(player, &QMediaPlayer::durationChanged,[=](){
qDebug()<<"!!!!!!!!!!!!!!!!!!!!!!!!!";
qint64 totaltime = player->duration();
totalTimeLabel->setText(formatTime(totaltime));
//视频进度条初始化,duration为视频总长,单位毫秒
processSlider->setRange(0, totaltime);
});
// connect(audioOutput, &QAudioOutput::volumeChanged, [=](){
// voiceSlider->setValue(audioOutput->volume());
// });
connect(voiceSlider, sliderValueChangedSignal, voiceLabel, labelSetNumSlot);
connect(voiceSlider, sliderValueChangedSignal, audioOutput, [=](int vol){
audioOutput->setVolume(((float)vol)/100);
if(vol == 0){voiceTitleLabel->setPixmap(QPixmap(":/vedioRes/volumn_no.png").scaled(30,30));}
else{voiceTitleLabel->setPixmap(QPixmap(":/vedioRes/volumn.png").scaled(30,30));}
});
connect(startBtn,&QPushButton::clicked,[=](){
player->play();
startBtn->setStyleSheet("QPushButton{border:0px;border-image:url(:/vedioRes/start_no.png)}");
startBtn->setDisabled(true);
stopBtn->setStyleSheet("QPushButton{border:0px;border-image:url(:/vedioRes/pause.png)}");
stopBtn->setEnabled(true);
});
connect(stopBtn,&QPushButton::clicked,[=](){
player->pause();
stopBtn->setStyleSheet("QPushButton{border:0px;border-image:url(:/vedioRes/pause_no.png)}");
stopBtn->setDisabled(true);
startBtn->setStyleSheet("QPushButton{border:0px;border-image:url(:/vedioRes/start.png)}");
startBtn->setEnabled(true);
});
connect(nextBtn,&QPushButton::clicked,[=](){
player->stop();
//qDebug()<<QString("the button is %1").arg(nextBtn->isChecked());
QTimer::singleShot(500,[=](){
curListIndex++;
if(curListIndex<filepathList->count())
{
player->setSource(QUrl::fromLocalFile(filepathList->at(curListIndex)));
}
else
{
curListIndex = 0;
player->setSource(QUrl::fromLocalFile(filepathList->at(curListIndex)));
}
player->play();
});
startBtn->setStyleSheet("QPushButton{border:0px;border-image:url(:/vedioRes/start_no.png)}");
startBtn->setDisabled(true);
stopBtn->setStyleSheet("QPushButton{border:0px;border-image:url(:/vedioRes/pause.png)}");
stopBtn->setEnabled(true);
});
connect(replayBtn,&QPushButton::clicked,[=](){
qDebug()<<QString("the button is %1").arg(replayBtn->isChecked());
});
/***********************************************************************play***********************************************************************/
// QString currentpath = QDir::homePath();//获取系统当前目录
// QString openfiletitle = "请选择文件";//title
// QString filefilter = "all(*.*);;MP4(*.mp4);;OGG(*.ogg);;MP3(*.mp3)";//"all(*.*);;MP4(*.mp4);;image(*.jpg);;file(*.txt)";//选择文件
// //QStringList* filepath = new QStringList(QFileDialog::getOpenFileNames(this,openfiletitle,currentpath,filefilter));//(this, openfiletitle, currentpath, filefilter);
// filepathList = new QStringList(QFileDialog::getOpenFileNames(this,openfiletitle,currentpath,filefilter));
// // if(filepath.isEmpty())
// // {
// // QMessageBox::warning(this, "打开文件", "文件不能为空!!!!!");
// // return;
// // }
// for(const QString &fileName : *filepathList) {
// qDebug() << "Selected file:" << fileName;
// }
// //QFileInfo info(filepath);//获取文件信息
// player->setSource(QUrl::fromLocalFile(filepathList->at(0)));//setMedia(QUrl::fromLocalFile(filepath));
// //player->play();//播放
}
QString videoPlayer::formatTime(qint64 time)
{
int seconds = (time / 1000) % 60;
int minutes = (time / 60000) % 60;
int hours = (time / 3600000) % 24;
return QString("%1:%2:%3")
.arg(hours, 2, 10, QLatin1Char('0'))
.arg(minutes, 2, 10, QLatin1Char('0'))
.arg(seconds, 2, 10, QLatin1Char('0'));
}
void videoPlayer::getListFromDB(void)
{
QSqlQuery sqlQuery;
if (QSqlDatabase::contains("qt_sql_default_connection"))
{
database = QSqlDatabase::database("qt_sql_default_connection");
}
else
{
// 建立和SQlite数据库的连接
database = QSqlDatabase::addDatabase("QSQLITE");
// 设置数据库文件的名字
database.setDatabaseName("MyDataBase.db");
}
if (!database.open())
{
qDebug() << "Error: Failed to connect database." << database.lastError();return;
}
if(!database.tables().contains(QString("videoList")))
{
qDebug() << "Error: Failed to connect database." << database.lastError();
// 构建创建数据库的sql语句字符串
QString createSql = QString("CREATE TABLE ").append("videoList").append(" (\
id INT PRIMARY KEY NOT NULL,\
path TEXT NOT NULL,\
type TEXT NOT NULL)");
sqlQuery.prepare(createSql);
// 执行sql语句
if(!sqlQuery.exec())
{
qDebug() << "Error: Fail to create table. " << sqlQuery.lastError();return;
}
/***********************************************************************play***********************************************************************/
QString currentpath = QDir::homePath();//获取系统当前目录
QString openfiletitle = "请选择文件";//title
QString filefilter = "all(*.*);;MP4(*.mp4);;OGG(*.ogg);;MP3(*.mp3)";//"all(*.*);;MP4(*.mp4);;image(*.jpg);;file(*.txt)";//选择文件
//QStringList* filepath = new QStringList(QFileDialog::getOpenFileNames(this,openfiletitle,currentpath,filefilter));//(this, openfiletitle, currentpath, filefilter);
filepathList = new QStringList(QFileDialog::getOpenFileNames(this,openfiletitle,currentpath,filefilter));
int indexID = 0;
for(const QString &fileName : *filepathList) {
indexID++;
qDebug() << "Selected file:" << fileName;
sqlQuery.prepare(QString("INSERT INTO ").append("videoList").append(" VALUES(:id,:path,:type)"));
sqlQuery.bindValue(":id", indexID);
sqlQuery.bindValue(":path", fileName);
sqlQuery.bindValue(":type", QFileInfo(fileName).suffix());
if(!sqlQuery.exec())
{
qDebug() << "Error: Fail to insert data. " << sqlQuery.lastError();
}
else
{
// do something
}
}
//QFileInfo info(filepath);//获取文件信息
player->setSource(QUrl::fromLocalFile(filepathList->at(0)));//setMedia(QUrl::fromLocalFile(filepath));
//player->play();//播放
}
else
{
sqlQuery.exec(QString("SELECT path FROM ").append("videoList").append(" WHERE type IN ('mp3', 'MP3', 'ogg', 'OGG', 'mp4', 'MP4')"));//.append(name).append("'"));
if(!sqlQuery.exec())
{
qDebug() << "Error: Fail to query table. " << sqlQuery.lastError();
}
else
{
filepathList->clear();
while(sqlQuery.next())
{
filepathList->append(sqlQuery.value(0).toString());
// data->id = sqlQuery.value(0).toInt();
// data->name = sqlQuery.value(1).toString();
// data->age = sqlQuery.value(2).toInt();
// data->password = sqlQuery.value(3).toString();
qDebug()<<sqlQuery.value(0).toString();
}
player->setSource(QUrl::fromLocalFile(filepathList->at(0)));//setMedia(QUrl::fromLocalFile(filepath));
}
}
}
2.其中问题点
1)QT6的QMediaPlayer:
首先实现播放器工程需要三个类对象:
1.QMediaPlayer 自然是需要的;
2.QVideoWidget用于承载(不知道用词是否合适哈)播放图像资源;
3.QAudioOutput新版Qt的音频需要使用其来管理。
然后就是将为player添加视屏资源 和 音频资源管理的对象:;
2)代码布局方式
结果中展现的布局其实是一个三行七列的栅格式布局:
如何统一设置布局中两个QSlider 的样式:其中所有页面下的子控件的父类都是整个播放器的widget,所以在以下代码设置了QSlider的样式,将进度条 和 音量条的样式统一设置;
widget->setStyleSheet(QString(".QWidget{background-color:rgba(200,100,186,10);}").append(".QWidget{border-image:url(")
.append(bg).append(");background-repeat:no-repeat;background-position:center;}")
.append(".QWidget{border:1px solid black;}")
.append(".QWidget{border-radius:10px;}")
.append("QSlider::groove:horizontal {border: 0px solid #bbb;}")
.append("QSlider::sub-page:horizontal{background:rgb(180,60,140);border-radius:4px;margin-top:7px;margin-bottom:7px;}")
.append("QSlider::add-page:horizontal{background:rgb(238,152,10);border:0px solid #777;border-radius:3px;margin-top:9px;margin-bottom:9px;}")
.append("QSlider::handle:horizontal{background:rgb(163,77,89);width: 10px;border:1px solid rgb(193,204,208);border-radius:4px;margin-top:4px;margin-bottom:4px;}")
.append("QSlider::handle:horizontal:hover{background:rgb(163,77,89);width: 10px;border:1px solid rgb(193,204,208);border-radius:5px; margin-top:4px;margin-bottom:4px;}")
/*.append(".QSlider{border:1px solid black;{border-radius:10px;}")*/
);