Windows下基于Qt的云音乐播放器软件开发

  • CloudMusicPlayer.pro文件添加模块
QT       += core gui sql multimedia concurrent
  • CloudMusicPlayer.h
#ifndef CLOUDMUSICPLAYER_H
#define CLOUDMUSICPLAYER_H

#include <QWidget>
#include<QMediaPlayer>
#include<QListWidgetItem>
#include<QPaintEvent>
#include<QPainter>
#include<QSystemTrayIcon>
#include<QAction>
#include<QMenu>
#include<QPoint>
#include<QMouseEvent>
#include<QApplication>
#include<QCursor>
#include<QSettings>
#include"loginwidget.h"
#include"userregister.h"
#include<QDialog>
#include<QLayoutItem>

namespace Ui {
class CloudMusicPlayer;
}

class CloudMusicPlayer : public QWidget
{
    Q_OBJECT

public:
    explicit CloudMusicPlayer(QWidget *parent = 0);
    ~CloudMusicPlayer();

private:
    Ui::CloudMusicPlayer *ui;
    void Init();
    bool m_IsPlaying = false;//播放器当前状态为停止
//    QAudioOutput *audioOuput;//音频输出对象
    QMediaPlayer *mediaPlayer;//媒体播放对象

    //使用绘图事件,设置背景图
    void paintEvent(QPaintEvent *);//绘图事件在运行的时候自动被调用

    //系统托盘
    QSystemTrayIcon *mySystemTray;
    //初始化系统托盘
    void InitSystemTrayIcon();

    //重写鼠标事件,实现拖动窗口移动
    QPoint m_lastPos;
    void mousePressEvent(QMouseEvent *event);
    void mouseMoveEvent(QMouseEvent *event);
    void mouseReleaseEvent(QMouseEvent *event);
    /*
     * 如果仅重写鼠标事件,则会导致在按住当前界面上的控件时,
     * 当按住这个动作一直存在并将鼠标从控件移动到QWidget的区域时,
     * 界面也会跟着移动,并且这样的移动时直接跳了过去,这样就很不完美,
     * 而且在界面很小,控件很多的情况下,拖动显得非常卡顿,
     * 所以我们就需要在mouse事件中添加一个判断,
     * 判断当前鼠标按下是否是处于QWidget所在的区域。
    */
    bool isPressQMusicWidget;

    QMenu *menu_changeSkin;

    loginWidget *loginwidget;
    QDialog *dialog;
    userRegister *userRegisterPage;

    QString currentuserName;

    QUrl url;
    //歌手
    QString author;
    //歌曲名
    QString title;
    //时长
    qint64 duration;
    //唱片集
    QString albumTitle;
    //比特率
    int audioBitRate;


private slots:
    //按钮信号槽
    void doProcess_btn_openfileClick();
    void doProcess_btn_preClick();
    void doProcess_btn_playClick();
    void doProcess_btn_nextClick();
    void doProcess_btn_volumeClick();
    void doProcess_btn_AboutClick();
    void doProcess_btn_About2Click();
    void doProcess_btn_MinmumClick();
    void doProcess_btn_QuitClick();
    void doProcessbtn_User();
    //换肤功能
    void doProcessbtn_SkinClick();
    void doProcessbtnbackgroud_to_default();
    void doProcessbtnbackgroud_to_custom();
    //滑动条控制音乐播放进度
    void doProcessdurationChanged(qint64 duration);
    void doProcesspositionChanged(qint64 pos);
    //鼠标双击播放音乐事件
    void doProcessitemDoubleClicked(QListWidgetItem* item);
    //音量调节
    void doProcessVolumevalueChanged(int num);
    //系统托盘点击事件
    void systemTrayIcon_activated(QSystemTrayIcon::ActivationReason reason);
    //接收登录成功信号
    void receive_signal_loginSuccess(QString);
    //更新Dialog中的登录或注册窗口
    void UpdateDialogWidget();

//    void reloadloginwidgetTodialog();




};

#endif // CLOUDMUSICPLAYER_H

  • CloudMusicPlayer.cpp
#include "cloudmusicplayer.h"
#include "ui_cloudmusicplayer.h"
#include<QDebug>
#include<QFileDialog>
#include<QMessageBox>
#include<QStandardPaths>
#include<QtConcurrent>

CloudMusicPlayer::CloudMusicPlayer(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::CloudMusicPlayer)
{
    ui->setupUi(this);
    Init();
}

CloudMusicPlayer::~CloudMusicPlayer()
{
    delete ui;
}

void CloudMusicPlayer::Init()
{
    //系统托盘初始化
    InitSystemTrayIcon();

    //窗口设置圆角后,会出现留白,需要添加以下代码
    setAttribute(Qt::WA_TranslucentBackground, true);
    //去除标题栏(发现去除标题栏之后无法移动窗口,此时需要重写鼠标事件)
    setWindowFlags(Qt::FramelessWindowHint);

    mediaPlayer=new QMediaPlayer(this);
    ui->volumeSlider->setVisible(false);//初始化状态下音乐滑块不可见
    //按钮绑定
    connect(ui->btn_openfile,SIGNAL(clicked(bool)),this,SLOT(doProcess_btn_openfileClick()));
    connect(ui->btn_pre,SIGNAL(clicked(bool)),this,SLOT(doProcess_btn_preClick()));
    connect(ui->btn_play,SIGNAL(clicked(bool)),this,SLOT(doProcess_btn_playClick()));
    connect(ui->btn_next,SIGNAL(clicked(bool)),this,SLOT(doProcess_btn_nextClick()));
    connect(ui->btn_volume,SIGNAL(clicked(bool)),this,SLOT(doProcess_btn_volumeClick()));
    connect(ui->btn_About,SIGNAL(clicked(bool)),this,SLOT(doProcess_btn_AboutClick()));
    connect(ui->btn_About2,SIGNAL(clicked(bool)),this,SLOT(doProcess_btn_About2Click()));
    connect(ui->btn_Minmum,SIGNAL(clicked(bool)),this,SLOT(doProcess_btn_MinmumClick()));
    connect(ui->btn_Quit,SIGNAL(clicked(bool)),this,SLOT(doProcess_btn_QuitClick()));
    connect(ui->btn_User,SIGNAL(clicked(bool)),this,SLOT(doProcessbtn_User()));
    //实现换肤功能
    connect(ui->btn_Skin,SIGNAL(clicked(bool)),this,SLOT(doProcessbtn_SkinClick()));

    //listWidget鼠标双击事件
    connect(ui->listWidget,SIGNAL(itemDoubleClicked(QListWidgetItem*)),this,SLOT(doProcessitemDoubleClicked(QListWidgetItem*)));
    //连接到volumeslider,获取其实时拖动的值,实时设置音乐的音量
    connect(ui->volumeSlider,SIGNAL(valueChanged(int)),this,SLOT(doProcessVolumevalueChanged(int)));

    //mediaPlayer总时长改变,同步至total_lbl
    connect(mediaPlayer,SIGNAL(durationChanged(qint64)),this,SLOT(doProcessdurationChanged(qint64)));

    //mediaPlayer当前播放时长改变,同步至cur_lbl
    connect(mediaPlayer,SIGNAL(positionChanged(qint64)),this,SLOT(doProcesspositionChanged(qint64)));

    //playProgressSlider被拖动时,音乐播放进度改变
    connect(ui->playProgressSlider,&QSlider::sliderMoved,mediaPlayer,&QMediaPlayer::setPosition);



    loginwidget=new loginWidget();
    dialog=new QDialog(this);
    //登录成功,删除对话框
    connect(loginwidget,SIGNAL(signal_loginSuccess()),dialog,SLOT(close()));
    connect(loginwidget,SIGNAL(signal_loginName(QString)),this,SLOT(receive_signal_loginSuccess(QString)));

    //接收登录界面发送过来的注册按钮点击信号,将注册界面加载在dialog中
    connect(loginwidget,SIGNAL(signal_register_click()),this,SLOT(UpdateDialogWidget()));

    //接收注册成功界面发送过来的信号,重新加载登录界面至dialog中

    //接收信号,将userRegisterPage加入Dialog中

    //实现登录功能,将登录功能加载到当前页面,登录之后显示用户所存储的歌曲

//    mediaPlayer->setAudioRole();
//    player = new QMediaPlayer;
//    connect(mediaPlayer, SIGNAL(positionChanged(qint64)), this, SLOT(positionChanged(qint64)));
//    QUrl fileUrl=":/Users/gys/Music/Cash Cash _ Christina Perri - Hero.mp3";

}
void CloudMusicPlayer::doProcess_btn_openfileClick()
{
    qDebug()<<"1"<<endl;
    QStringList fileNames = QFileDialog::getOpenFileNames(this,"请选择音乐所在目录","C:\\Users\\gys\\Music",tr("Music (*.mp3)"));//打开已经存在的目录
    qDebug()<<"fileNames"<<fileNames<<endl;
    ui->listWidget->addItems(fileNames);

    //音乐导入之后默认选择第0行作为选中行
    if(fileNames.length()!=0)
    {
        ui->listWidget->setCurrentRow(0);
        //模拟点击
        QModelIndex test=ui->listWidget->currentIndex();
        ui->listWidget->clicked(test);
    }
    else
    {
        QMessageBox::warning(this,"warning","----未选中文件----\n请重新添加音乐列表!");
        return;
    }

    //将当前列表中的数据重新写入数据库,并对数据库中的数据去重
    if(currentuserName.isEmpty())
    {
        return;
    }
    else
    {
        //对当前列表中的歌曲进行解析,获取歌曲的详细信息
        //歌曲信息
        //当前的url需要对fileNames进行遍历
        for(int i=0;i<fileNames.count();i++)
        {
            url = fileNames.at(i);
            //歌曲信息解析待学习
//                author = tempPlayer.metaData(QStringLiteral("Author")).toStringList().join(",");
//                //author = tempPlayer.metaData(QStringLiteral("Author")).toString(); //查手册发现,这里返回的是StringList
//                //author=tempPlayer.metaData(QStringLiteral("ContributingArtist")).toStringList().join(","); //另一种元数据
//                title = tempPlayer.metaData(QStringLiteral("Title")).toString();
//                albumTitle = tempPlayer.metaData(QStringLiteral("AlbumTitle")).toString();
//                audioBitRate = tempPlayer.metaData(QStringLiteral("AudioBitRate")).toInt();
//                duration=tempPlayer.duration();
            QSqlQuery query;
            QString insert_sql = "INSERT INTO MusicInfo (userName, url) VALUES (?, ?)";
            query.prepare(insert_sql);
            query.addBindValue(currentuserName);//当前用户名
            query.addBindValue(url);//当前url
            query.exec();

        }
        //对当前用户的重复歌曲去重
        QSqlQuery querys;
        QString removeDupl_sql="DELETE FROM MusicInfo WHERE rowid NOT IN ( SELECT rowid FROM MusicInfo GROUP BY ( userName || 'seprator' || url ) );";
        querys.exec(removeDupl_sql);
        if(querys.exec(removeDupl_sql))
        {
            qDebug()<<"执行成功!"<<endl;
        }
        else
        {
            QMessageBox::warning(this,"warning",querys.lastError().text());
            qDebug()<<"cloudmusicplayer---QSqlQuery::lastError()"<<querys.lastError().text()<<endl;
        }

    }
}
void CloudMusicPlayer::doProcess_btn_preClick()
{
    qDebug()<<"2"<<endl;
    //如果当前列表为空
    if(ui->listWidget->count()!=0)//避免出现listWidget中的数据个数为0导致的程序崩溃
    {
        int currentNum = ui->listWidget->currentRow();//当前所在行号
        int rowcount = ui->listWidget->model()->rowCount();//当前列表的总行数
        qDebug()<<rowcount<<currentNum<<endl;
        if(currentNum==0)
        {
            ui->listWidget->setCurrentRow(rowcount-1);//如果当前歌曲为第0行,则点击上一曲之后,设置当前播放歌曲为最后一个
        }
        else
        {
            ui->listWidget->setCurrentRow(currentNum-1);
        }
    //    ui->listWidget->setCurrentRow((currentNum-1)%rowcount);
        QModelIndex test=ui->listWidget->currentIndex();
        ui->listWidget->clicked(test);
        mediaPlayer->setMedia(QUrl::fromLocalFile(ui->listWidget->currentItem()->text()));
        mediaPlayer->setVolume(ui->volumeSlider->value());
        ui->btn_play->setIcon(QIcon(":/new/prefix1/img/image/play.png"));
        mediaPlayer->play();
        m_IsPlaying=true;
    }
    else
    {
        qDebug()<<"当前列表为空!"<<endl;
        QMessageBox::warning(this,"warning","----当前列表为空----\n请先添加音乐列表!");
        return;
    }
}
void CloudMusicPlayer::doProcess_btn_playClick()
{
    qDebug()<<"3"<<endl;
    //如果当前正在播放,则设置播放停止,否则,播放选中音乐
//    auto list= ui->listWidget->selectedItems();
//    qDebug()<<"list"<<ui->listWidget->currentItem()->text()<<endl;

    switch (mediaPlayer->state())//获取当前播放状态
    {
        //停止状态时,点击播放
        case QMediaPlayer::StoppedState:
        {
            if(ui->listWidget->count()!=0)//避免出现listWidget中的数据个数为0导致的程序崩溃
            {
                //判断当前是否有选中的item(将该问题转化为,文件添加到列表之后,默认选择第一个item,此时,即可避免未选中item,直接播放导致的崩溃)
                mediaPlayer->setMedia(QUrl::fromLocalFile(ui->listWidget->currentItem()->text()));
                mediaPlayer->setVolume(ui->volumeSlider->value());
                ui->btn_play->setIcon(QIcon(":/new/prefix1/img/image/play.png"));
                mediaPlayer->play();
                m_IsPlaying=true;

            }
            else
            {
        //            qDebug()<<"当前列表为空!"<<endl;
                QMessageBox::warning(this,"warning","----当前列表为空----\n请先添加音乐列表!");
                return;
            }
            break;
        }
        //正在播放时,点击停止
        case QMediaPlayer::PlayingState:
        {
            ui->btn_play->setIcon(QIcon(":/new/prefix1/img/image/pase.png"));
            mediaPlayer->pause();
            m_IsPlaying = false;//设置播放状态为非停止,便于下次调用
            break;
        }
        //暂停状态,继续播放
        case QMediaPlayer::PausedState:
        {
            ui->btn_play->setIcon(QIcon(":/new/prefix1/img/image/play.png"));
            mediaPlayer->play();
            m_IsPlaying=true;
            break;
        }
    }
    /*
    if(!m_IsPlaying)//如果当前播放停止,则进行选择播放
    {
        if(ui->listWidget->count()!=0)//避免出现listWidget中的数据个数为0导致的程序崩溃
        {
            //判断当前是否有选中的item(将该问题转化为,文件添加到列表之后,默认选择第一个item,此时,即可避免未选中item,直接播放导致的崩溃)
            mediaPlayer->setMedia(QUrl::fromLocalFile(ui->listWidget->currentItem()->text()));
            mediaPlayer->setVolume(ui->volumeSlider->value());
            ui->btn_play->setIcon(QIcon(":/new/prefix1/img/image/play.png"));
            mediaPlayer->play();
            m_IsPlaying=true;

        }
        else
        {
//            qDebug()<<"当前列表为空!"<<endl;
            QMessageBox::warning(this,"warning","----当前列表为空----\n请先添加音乐列表!");
            return;
        }
    }
    else
    {
        //如果当前正在播放,则播放停止
        ui->btn_play->setIcon(QIcon(":/new/prefix1/img/image/pase.png"));
        mediaPlayer->pause();
        m_IsPlaying = false;//设置播放状态为非停止,便于下次调用
    }
    */
}

void CloudMusicPlayer::doProcess_btn_nextClick()
{
    qDebug()<<"4"<<endl;
    //如果当前列表为空
    if(ui->listWidget->count()!=0)//避免出现listWidget中的数据个数为0导致的程序崩溃
    {
        int currentNum = ui->listWidget->currentRow();//当前所在行号
        int rowcount = ui->listWidget->model()->rowCount();//当前列表的总行数
        qDebug()<<rowcount<<currentNum<<endl;
//        if(currentNum==0)
//        {
//            ui->listWidget->setCurrentRow(rowcount-1);//如果当前歌曲为第0行,则点击上一曲之后,设置当前播放歌曲为最后一个
//        }
//        else
//        {
//            ui->listWidget->setCurrentRow(currentNum-1);
//        }
        ui->listWidget->setCurrentRow((currentNum+1)%rowcount);//数据结构,循环列表
        QModelIndex test=ui->listWidget->currentIndex();
        ui->listWidget->clicked(test);
        mediaPlayer->setMedia(QUrl::fromLocalFile(ui->listWidget->currentItem()->text()));
        mediaPlayer->setVolume(ui->volumeSlider->value());
        ui->btn_play->setIcon(QIcon(":/new/prefix1/img/image/play.png"));
        mediaPlayer->play();
        m_IsPlaying=true;
    }
    else
    {
        QMessageBox::warning(this,"warning","----当前列表为空----\n请先添加音乐列表!");
        return;
    }
}

void CloudMusicPlayer::doProcess_btn_volumeClick()
{
    qDebug()<<"5"<<endl;
    if(ui->volumeSlider->isVisible())
    {
        ui->volumeSlider->setVisible(false);
    }
    else
    {
        //设置滑块可见之后,通过获取滑块的值,调整歌曲的音量
        ui->volumeSlider->setVisible(true);
    }
}

void CloudMusicPlayer::doProcess_btn_AboutClick()
{
    QMessageBox::about(this,"AboutApp","Windows下基于Qt的云音乐播放器\n创作者:GYS\n");
}
void CloudMusicPlayer::doProcess_btn_About2Click()
{
    QMessageBox::about(this,"AboutApp","Windows下基于Qt的云音乐播放器\n创作者:GYS\n");
}

void CloudMusicPlayer::doProcess_btn_MinmumClick()
{
    //退出到系统托盘最小化
    showMinimized();
}

void CloudMusicPlayer::doProcess_btn_QuitClick()
{
    close();
}

void CloudMusicPlayer::doProcessbtn_User()
{
    loginwidget->show();
    dialog->setWindowTitle("登录");
    dialog->setWindowModality(Qt::ApplicationModal);
    dialog->setLayout(new QVBoxLayout);
    dialog->layout()->addWidget(loginwidget);
    dialog->exec();

//    loginwidget->show();
    // 将新窗口移动到主窗口中间
    int x = this->pos().x() + (this->width() - loginwidget->width()) / 2;
    int y = this->pos().y() + (this->height() - loginwidget->height()) / 2;
    loginwidget->move(x, y);

}

void CloudMusicPlayer::receive_signal_loginSuccess(QString usrName)
{

//    delete dialog;
    ui->listWidget->clear();
    //登录之后只展示用户之前添加过并写入数据库中的音乐,同时,当用户点击添加音乐时,仍然可以添加音乐至listwidget中,
    //此时,在添加音乐时,可以检测当前的用户userName是否为空,如果为空,则直接添加,不用更新数据库,否则,添加之后,将当前listwidget中的音乐更新至数据库
    currentuserName=usrName;
    qDebug()<<"登陆成功!加载数据库中歌曲"<<endl;
    QSqlQuery sql_query;
    QString select_sql = "select url, author, title, duration, albumTitle, audioBitRate from MusicInfo where userName = ?";
    sql_query.prepare(select_sql);
    sql_query.addBindValue(currentuserName);//添加登录成功的用户名字
    if(sql_query.exec())
    {

        while(sql_query.next())
        {

//            if(sql_query.value(0).isNull())
//            {
//                return;
//            }

            url=QUrl(sql_query.value(0).toString());
            author=sql_query.value(1).toString();
            title=sql_query.value(2).toString();
            duration=sql_query.value(3).toLongLong();
            albumTitle=sql_query.value(4).toString();
            audioBitRate=sql_query.value(5).toInt();
            QListWidgetItem *item=new QListWidgetItem;

            item->setText(url.toString());
            ui->listWidget->addItem(item);

        }
    }
    //默认模拟点击第一行,防止上一曲出现崩溃
    ui->listWidget->setCurrentRow(0);
    //模拟点击
    QModelIndex test=ui->listWidget->currentIndex();
    ui->listWidget->clicked(test);
}

void CloudMusicPlayer::doProcessitemDoubleClicked(QListWidgetItem *item)
{

//    ui->listWidget->setCurrentRow(0);
//    QModelIndex test=ui->listWidget->currentIndex();
//    ui->listWidget->clicked(test);

    mediaPlayer->setMedia(QUrl::fromLocalFile(item->text()));
    mediaPlayer->setVolume(ui->volumeSlider->value());
    ui->btn_play->setIcon(QIcon(":/new/prefix1/img/image/play.png"));
    mediaPlayer->play();
}

void CloudMusicPlayer::doProcessVolumevalueChanged(int num)
{
    mediaPlayer->setVolume(num);
}

void CloudMusicPlayer::doProcessdurationChanged(qint64 duration)
{
    //当前duration为毫秒数,毫秒/1000->秒,毫秒/1000/60->分钟数
    QString str = QString("%1:%2:%3").arg(duration/1000/60/60,2,10,QLatin1Char('0')).arg(duration/1000/60,2,10,QLatin1Char('0')).arg(duration/1000%60,2,10,QLatin1Char('0'));
    ui->total_lbl->setText(str);
    //设置slider的范围
    ui->playProgressSlider->setRange(0,duration);
}

void CloudMusicPlayer::doProcesspositionChanged(qint64 pos)
{
    QString str = QString("%1:%2:%3").arg(pos/1000/60/60,2,10,QLatin1Char('0')).arg(pos/1000/60,2,10,QLatin1Char('0')).arg(pos/1000%60,2,10,QLatin1Char('0'));
    ui->cur_lbl->setText(str);
    //将当前的播放进度同步至slider
    ui->playProgressSlider->setValue(pos);
}

void CloudMusicPlayer::paintEvent(QPaintEvent *)
{
    //测试发现,不要将高精度的图片作为背景,否则会导致渲染压力大
    //例如:在默认背景下,鼠标鼠标放置在按钮上无需等待直接显示hover,
    //在更换背景图片之后,鼠标放置在按钮上需要等待一些时间才能显示hover
    QString fileName=":/new/prefix1/img/background/default.jpg";
    QSettings mysettings("./CloudMusic.ini", QSettings::IniFormat);
    mysettings.setIniCodec("UTF8");
    QString str = mysettings.value("background/image-url", fileName).toString();

    // Use QtConcurrent to load the image asynchronously
    QFuture<QPixmap> future = QtConcurrent::run([&]() {
        return QPixmap(str);
    });

    // Wait for the image to be loaded and draw it onto the widget
    QPixmap pixmap = future.result();
    QPainter painter(this);
    painter.drawPixmap(this->rect(), pixmap);
}

//系统托盘初始化
void CloudMusicPlayer::InitSystemTrayIcon()
{
    mySystemTray=new QSystemTrayIcon(this);
    mySystemTray->setIcon(QIcon(":/new/prefix1/img/image/systemTrayIcon.png"));
    mySystemTray->setToolTip("CloudMusic");
    //绑定信号槽,实现双击弹出或隐藏界面
    connect(mySystemTray,SIGNAL(activated(QSystemTrayIcon::ActivationReason)),this,SLOT(systemTrayIcon_activated(QSystemTrayIcon::ActivationReason)));

    //为托盘创建菜单,实现快捷点击
    QAction *action_systemTray_pre=new QAction(QIcon(":/new/prefix1/img/image/pre2.png"),"上一首",this);
    //将action与页面中的上一首按钮处理槽绑定,实现同样功能
    connect(action_systemTray_pre,SIGNAL(triggered(bool)),this,SLOT(doProcess_btn_preClick()));
    QAction *action_systemTray_play=new QAction(QIcon(":/new/prefix1/img/image/play2.png"),"播放",this);
    connect(action_systemTray_play,SIGNAL(triggered(bool)),this,SLOT(doProcess_btn_playClick()));
    QAction *action_systemTray_next=new QAction(QIcon(":/new/prefix1/img/image/next2.png"),"下一首",this);
    connect(action_systemTray_next,SIGNAL(triggered(bool)),this,SLOT(doProcess_btn_nextClick()));
    QAction *action_systemTray_quit = new QAction(QIcon(":/new/prefix1/img/image/exit.png"), "退出",this);
    connect(action_systemTray_quit, SIGNAL(triggered(bool)), this, SLOT(close()));

    //创建菜单,将action加入
    QMenu *pContextMenu = new QMenu(this);
    pContextMenu->addAction(action_systemTray_pre);
    pContextMenu->addAction(action_systemTray_play);
    pContextMenu->addAction(action_systemTray_next);
    pContextMenu->addAction(action_systemTray_quit);
    mySystemTray->setContextMenu(pContextMenu);
    mySystemTray->show();
}
void CloudMusicPlayer::systemTrayIcon_activated(QSystemTrayIcon::ActivationReason reason)
{
    switch (reason)
    {
    case QSystemTrayIcon::DoubleClick:
        //显/隐主界面
        if(isHidden()){
            show();
        }else{
            hide();
        }
        break;
    default:
        break;
    }
}

void CloudMusicPlayer::mousePressEvent(QMouseEvent *event)
{
    if(this==QApplication::widgetAt(event->globalPos()))
    {
        m_lastPos=event->globalPos();//记录鼠标按下时窗口所在屏幕的位置
        isPressQMusicWidget=true;
    }

}

void CloudMusicPlayer::mouseMoveEvent(QMouseEvent *event)
{
    if(isPressQMusicWidget)
    {
        //移动的x和y的位置
        this->move(this->x()+(event->globalX()-m_lastPos.x()),
                   this->y()+(event->globalY()-m_lastPos.y()));
        //更新窗口所在的屏幕位置
        m_lastPos=event->globalPos();
    }
}

void CloudMusicPlayer::mouseReleaseEvent(QMouseEvent *event)
{
    m_lastPos=event->globalPos();
    isPressQMusicWidget=false;
}

void CloudMusicPlayer::doProcessbtn_SkinClick()
{
    //实现菜单项
    QAction *action_backgroud_to_default = new QAction(QIcon(":/new/prefix1/img/background/default.jpg"),"默认背景",this);
    connect(action_backgroud_to_default,SIGNAL(triggered(bool)),this,SLOT(doProcessbtnbackgroud_to_default()));
    QAction *action_backgroud_to_custom=new QAction(QIcon(":/new/prefix1/img/image/setting.png"),"自定义背景",this);
    connect(action_backgroud_to_custom,SIGNAL(triggered(bool)),this,SLOT(doProcessbtnbackgroud_to_custom()));
    //将菜单项添加到菜单
    menu_changeSkin=new QMenu(this);
    menu_changeSkin->addAction(action_backgroud_to_default);
    menu_changeSkin->addAction(action_backgroud_to_custom);
    menu_changeSkin->exec(QCursor::pos());
}

void CloudMusicPlayer::doProcessbtnbackgroud_to_default()
{
    QString fileName=":/new/prefix1/img/background/default.jpg";
    //Constructs a QSettings object for accessing the settings
    //stored in the file called fileName, with parent parent.
    //If the file doesn't already exist, it is created.
    //If format is QSettings::IniFormat, fileName is the name of an INI file.
    QSettings mysettings("./CloudMusic.ini",QSettings::IniFormat);
    mysettings.setIniCodec("UTF8");
    mysettings.setValue("background/image-url",fileName);
    setStyleSheet(QString("QWidget#CloudMusicPlayer{"
                          "border-radius:10px;"
                          "border-image: url(%1);}"
                          "listWidget{"
                          "border:none;}").arg(fileName));
//    QApplication::processEvents();
    qDebug()<<"1:"<<fileName<<endl;
}

void CloudMusicPlayer::doProcessbtnbackgroud_to_custom()
{
    //从默认图片位置打开文件选择框
    QString fileName=QFileDialog::getOpenFileName(this,"选择自定义背景图片","C:\\Users\\gys\\Pictures","图片文件(*jpg *png)");
    if(!fileName.isEmpty())
    {
        QImage testImage(fileName);
        if(!testImage.isNull())
        {
            QSettings mysettings("./CloudMusic.ini",QSettings::IniFormat);
            mysettings.setIniCodec("UTF8");
            mysettings.setValue("background/image-url",fileName);
            setStyleSheet(QString("QWidget#CloudMusicPlayer{"
                                  "border-radius:10px;"
                                  "border-image: url(%1);}"
                                  "listWidget{"
                                  "border:none;}").arg(fileName));
//            QApplication::processEvents();
            qDebug()<<"2:"<<fileName<<endl;
        }
    }
}
void CloudMusicPlayer::UpdateDialogWidget()
{
    //用于清空QDialog中的所有widget
//    QLayoutItem *child;
//    while ((child = dialog->layout()->takeAt(0)) != nullptr)
//    {
//        if (child->widget() != nullptr) {
//            child->widget()->deleteLater();
//        }
//        delete child;
//    }
//    if(!userRegisterPage->close())
//    {
//        delete userRegisterPage;
//    }
    loginwidget->hide();
    userRegisterPage= new userRegister();
    dialog->layout()->addWidget(userRegisterPage);
    dialog->layout()->update();
    dialog->exec();

    // 将新窗口移动到主窗口中间
    int x = this->pos().x() + (this->width() - userRegisterPage->width()) / 2;
    int y = this->pos().y() + (this->height() - userRegisterPage->height()) / 2;
    userRegisterPage->move(x, y);
}


//void CloudMusicPlayer::reloadloginwidgetTodialog()
//{

//}

  • loginwidget.h
#ifndef LOGINWIDGET_H
#define LOGINWIDGET_H

#include <QWidget>
#include <QSqlDatabase>
#include "userregister.h"
//#include"qmusic.h"//应该是cloudMusicPlayer继承loginWidget
#include<QPixmap>
#include<QPainter>
#include<QDialog>


class userRegister;//使用前向声明(forward declaration)来代替 #include 引用,或将类的实现移到源文件中,避免头文件相互引用的情况。

namespace Ui {
class loginWidget;
}

class loginWidget : public QWidget
{
    Q_OBJECT

public:
    explicit loginWidget(QWidget *parent = 0);
    ~loginWidget();

    friend class CloudMusicPlayer;

private:
    Ui::loginWidget *ui;
    void Init();
    QSqlDatabase db;
    userRegister *userRegisterPage;
//    QMusic *qmusic1;
    void paintEvent(QPaintEvent *);//绘图事件,自动调用

private slots:
    void doProcessLoginIn();
    void doProcessRegister();
    //接收userRegister传送过来的信号,并进行处理
    void reBackToLoginWidget();

signals:
    void signal_loginSuccess();
    void signal_register_click();
    void signal_loginName(QString);
//    void signal_reloadloginwidgetTodialog();

};

#endif // LOGINWIDGET_H

  • loginwidget.cpp
#include "loginwidget.h"
#include "ui_loginwidget.h"
#include<QSqlDatabase>
#include<QSqlQuery>
#include<QDebug>
#include<QSqlRecord>
#include<QSqlError>
#include<QMessageBox>

loginWidget::loginWidget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::loginWidget)
{
    ui->setupUi(this);
    setFixedSize(400, 300);
    setWindowIcon(QIcon(":/new/prefix1/img/image/systemTrayIcon.png"));//设置界面图标
    Init();
}

loginWidget::~loginWidget()
{
    delete ui;
}

void loginWidget::Init()
{
    //    q.prepare("INSERT INTO userNameAndPwd1 (userName, userPwd) "
    //                "VALUES (:userName, :userPwd)");
    //    q.bindValue(":userPwd", "xiaogao");
    //    q.bindValue(":userPwd", "123456789");

    //    qDebug() << "插入完毕! " << endl;


    //遍历数据库
//    QSqlRecord rec = q.record();

//    qDebug() << "Number of columns: " << rec.count();

//    int nameCol = rec.indexOf("userPwd"); // index of the field "name"
//    while (q.next())
//      qDebug() << q.value(nameCol).toString(); // output all names


    if(QSqlDatabase::contains("qt_sql_default_connection"))
    {
        db=QSqlDatabase::database("qt_sql_default_connection");
    }
    else
    {
        db=QSqlDatabase::addDatabase("QSQLITE");//设置数据库驱动 这里使用的是SQL Server
        db.setDatabaseName("userNameAndPwd1.db");
        //        db.setHostName("127.0.0.1");//设置主机名称,本地主机为127.0.0.1
        //        db.setDatabaseName("userNameAndPwd1.db");//添加数据源,在ODBC中添加的
        //        db.setUserName("aaa");//登录名称,在SQL Server中添加的登录名
        //        db.setPassword("123456");//密码,在SQL Server中添加的登录名的密码
        if(!db.open())
        {
            qDebug()<<"数据库打开失败";
            QMessageBox::critical(this,"无法打开数据库文件:userNameAndPwd1.db",db.lastError().databaseText());
            exit(-1);
        }
        else
        {
            qDebug()<<"数据库打开成功";
        }
    }

    //检查MusicInfo表是否存在,不存在则创建该表
    QSqlQuery query;
    query.exec(QString("select count(*) from sqlite_master where type='table' and name='%1'").arg("MusicInfo"));
    if(query.next()){
        if(query.value(0).toInt()==0){
            QSqlQuery sql_query;
            //QString create_sql = "create table MusicInfo (id int primary key, name varchar(30), url varchar(200), author varchar(50), title varchar(50), duration bigint, albumTitle varchar(50), audioBitRate int)";
            QString create_sql = "create table MusicInfo (userName varchar(30), url varchar(200), author varchar(50), title varchar(50), duration bigint, albumTitle varchar(50), audioBitRate int)";
            sql_query.prepare(create_sql);
            sql_query.exec();
        }
    }
    //检查UsrNamePwd表是否存在,不存在则创建该表
    QSqlQuery query2;
    query2.exec(QString("select count(*) from sqlite_master where type='table' and name='%1'").arg("UsrNamePwd"));
    if(query2.next()){
        if(query2.value(0).toInt()==0){
            QSqlQuery sql_query;
            QString create_sql = "create table UsrNamePwd (userName varchar(30),userPwd varchar(30))";
            sql_query.prepare(create_sql);
            sql_query.exec();
        }
    }

    connect(ui->btn_Login_in_2,SIGNAL(clicked(bool)),this,SLOT(doProcessLoginIn()));
    connect(ui->btn_Register_2,SIGNAL(clicked(bool)),this,SLOT(doProcessRegister()));


}

void loginWidget::doProcessLoginIn()
{
    db=QSqlDatabase::addDatabase("QSQLITE");//设置数据库驱动 这里使用的是SQL Server
    db.setDatabaseName("userNameAndPwd1.db");
    //        db.setHostName("127.0.0.1");//设置主机名称,本地主机为127.0.0.1
    //        db.setDatabaseName("userNameAndPwd1.db");//添加数据源,在ODBC中添加的
    //        db.setUserName("aaa");//登录名称,在SQL Server中添加的登录名
    //        db.setPassword("123456");//密码,在SQL Server中添加的登录名的密码
    if(!db.open())
    {
        qDebug()<<"数据库打开失败";
        QMessageBox::critical(this,"无法打开数据库文件:userNameAndPwd1.db",db.lastError().databaseText());
        exit(-1);
    }
    else
    {
        qDebug()<<"数据库打开成功";
    }

    //遍历当前目录下数据库userNameAndPwd1中的表UsrNamePwd
    QString sql="select * from UsrNamePwd";
    QSqlQuery q;
    if(!q.exec(sql))
    {
        qDebug() << "loginwidget------Error: Fail to create table." << q.lastError();
        db.close();
    }
    while (q.next())
    {
        QString userName = ui->lineEdit_userName_2->text();
        QString userPwd = ui->lineEdit_userPwd_2->text();
        if(!(userName.isEmpty()) && !(userPwd.isEmpty()))
        {
            if(userName==q.value(0).toString())
            {
                if(userPwd==q.value(1).toString())
                {
                    QMessageBox::about(this,"Success","登录成功!");
                    //产生新的窗体,用于网络通信功能

                    //登录成功加载该用户数据库中存储的内容
//                    qmusic1=new QMusic();
//                    qmusic1->show();
                    //登录成功之后向主窗体发出信号,删除dialog对话框
                    emit signal_loginSuccess();
                    emit signal_loginName(userName);
                    qDebug()<<"信号发送成功signal_loginSuccess"<<endl;
                    ui->lineEdit_userName_2->clear();
                    ui->lineEdit_userPwd_2->clear();
//                    this->hide();
//                    this->parent()->destroyed();
                    return;
                }
                else
                {
                    QMessageBox::warning(this,"Warning","密码错误!");
                }
            }
//            qDebug() << q.value(0).toString()<<q.value(1).toString()<<endl; // output all names
        }
        else
        {
            qDebug()<<"用户名或密码为空!"<<endl;
            return;
        }
    }
}
void loginWidget::doProcessRegister()
{
    userRegisterPage= new userRegister();
//    userRegisterPage->show();//加载子窗体
//    this->destroy(true);//销毁当前窗体
//    this->hide();
    //用户点击注册按钮之后,隐藏当前窗口,并发送信号,使得注册界面加载在dialog中
    emit signal_register_click();
    qDebug()<<"信号发送成功signal_register_click"<<endl;
    //接收注册成功的信号,并进行处理
    connect(userRegisterPage,SIGNAL(backToLoginWidget()),this,SLOT(reBackToLoginWidget()));
}

void loginWidget::paintEvent(QPaintEvent *)
{
    QPixmap pixmap=QPixmap(":/new/prefix1/img/background/default.jpg");
    QPainter painter(this);
    painter.drawPixmap(this->rect(),pixmap);
}

void loginWidget::reBackToLoginWidget()
{
    delete userRegisterPage;
//    this->show();
//    emit signal_reloadloginwidgetTodialog();

}

  • userregister.h
#ifndef USERREGISTER_H
#define USERREGISTER_H

#include <QWidget>
#include<QLabel>
#include<QLineEdit>
#include<QGridLayout>
#include<QPushButton>
#include<QSqlDatabase>
#include<QSqlQuery>
#include<QDebug>
#include<QSqlRecord>
#include<QSqlError>
#include<QMessageBox>
#include<QPainter>
//#include"loginwidget.h"


//class loginWidget;//使用前向声明(forward declaration)来代替 #include 引用,或将类的实现移到源文件中,避免头文件相互引用的情况。

class userRegister : public QWidget
{
    Q_OBJECT
public:
    explicit userRegister(QWidget *parent = 0);

//    friend class CloudMusicPlayer;

signals:
    void backToLoginWidget();

public slots:
    void doProcessRegister();

private:
    void Init();
    QSqlDatabase db;
    QLabel *lbl_username;
    QLabel *lbl_userPwd1;
    QLabel *lbl_userPwd2;
    QLineEdit *liedt_username;
    QLineEdit *liedt_userPwd1;
    QLineEdit *liedt_userPwd2;
    QGridLayout *mainLayout;
    QPushButton *register_d;
//    loginWidget *LoginPage;

    //绘图事件,自动调用
    void paintEvent(QPaintEvent *);

};

#endif // USERREGISTER_H

  • userregister.cpp
#include "userregister.h"

userRegister::userRegister(QWidget *parent) : QWidget(parent)
{
    setFixedSize(400, 300);
    setWindowTitle(tr("用户注册"));
    setWindowIcon(QIcon(":/new/prefix1/img/image/systemTrayIcon.png"));
    Init();
}
void userRegister::Init()
{
    db=QSqlDatabase::addDatabase("QSQLITE");
    db.setDatabaseName("userNameAndPwd1.db");
    if(!db.open())
    {
        qDebug()<<"数据库打开失败";
    }
    else
    {
        qDebug()<<"数据库打开成功";
    }

    //创建标签、行文本编辑器、按钮
    lbl_username=new QLabel(tr("用户名:"));
    lbl_userPwd1=new QLabel(tr("请输入密码:"));
    lbl_userPwd2=new QLabel(tr("请再次输入密码:"));
    liedt_username=new QLineEdit();
    liedt_userPwd1=new QLineEdit();
    liedt_userPwd2=new QLineEdit();
    register_d=new QPushButton(tr("确认注册"));

    //创建布局,添加当前按钮至布局中
    mainLayout = new QGridLayout(this);
    mainLayout->addWidget(lbl_username,0,0);
    mainLayout->addWidget(lbl_userPwd1,1,0);
    mainLayout->addWidget(lbl_userPwd2,2,0);
    mainLayout->addWidget(liedt_username,0,1);
    mainLayout->addWidget(liedt_userPwd1,1,1);
    mainLayout->addWidget(liedt_userPwd2,2,1);
    mainLayout->addWidget(register_d,3,0,1,2);//行跨度为1,列跨度为2

    //按钮绑定
    connect(register_d,SIGNAL(clicked(bool)),this,SLOT(doProcessRegister()));//绑定按钮

}

void userRegister::doProcessRegister()
{
    QString regName=liedt_username->text();//测试代码,在调试成功之后,将新建窗口,使用新的窗口注册
    QString regPwd1=liedt_userPwd1->text();
    QString regPwd2=liedt_userPwd2->text();

    QSqlQuery q;

    //检测用户输入密码或者用户名是否重复,若重复,则提醒,否则进行注册
    //遍历当前目录下数据库userNameAndPwd1中的表usrNamePwd,检查是否用户名已被注册
    QString sql1="select * from UsrNamePwd WHERE userName==";
    sql1+="\'"+regName+"\'";
    if(!q.exec(sql1))
    {
        qDebug() << "regName---Error: Fail to create table." << q.lastError();
        db.close();
    }
    while(q.next())
    {
        if(regName==q.value(0).toString())
        {
            QMessageBox::warning(this,"Warning","当前用户名已被注册!请重新输入用户名");
            liedt_username->selectAll();
            return;
        }
//        qDebug() << q.value(0).toString()<<q.value(1).toString()<<endl; // output all names
    }


//


    //检测用户输入的用户名格式、密码格式是否符合要求
    if(!(regName.isEmpty()) && !(regPwd1.isEmpty()) && !(regPwd2.isEmpty()))
    {
        //添加逻辑检测,例如:两次输入的密码是否相同,用户名规则等
        if(regPwd1!=regPwd2)
        {
            QMessageBox::warning(this,"Warning","请确保两次输入的密码相同!");
            return;
        }

        QString sql="INSERT INTO UsrNamePwd(userName,userPwd)VALUES(";
                sql+="\'"+regName+"\'"+","+"\'"+regPwd1+"\'"+")";

        if(!q.exec(sql))
        {
            qDebug() << "Error: Fail to create table." << q.lastError();
            db.close();
        }
        QMessageBox::about(this,"Success","注册成功!请重新登录");
        qDebug()<<"注册成功!"<<endl;
        //将注册成功的信号发送出去
        emit backToLoginWidget();

//        LoginPage = new loginWidget();
//        LoginPage->show();
        this->hide();
//        this->destroyed(this);
//        this->destroy(true);
    }
    else
    {
        qDebug()<<"用户名或密码为空!"<<endl;
    }
}
void userRegister::paintEvent(QPaintEvent *)
{
    QPixmap pixmap=QPixmap(":/new/prefix1/img/background/default.jpg");
    QPainter painter(this);
    painter.drawPixmap(this->rect(),pixmap);
}

  • main.cpp
#include "cloudmusicplayer.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    CloudMusicPlayer w;
    w.show();

    return a.exec();
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

colorful_stars

您是我见过全宇宙最可爱的人!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值