创建时候注意事项

QMainWindow:
QMainWindow 是用于创建应用程序主窗口的类。它通常用于具有菜单栏、工具栏、状态栏等标准组件的窗口。
QMainWindow 提供了一种框架,用于组织和管理应用程序的用户界面元素。它可以包含其他小部件(widgets)和布局管理器(layout managers),如中心部件(central widget)、dock 窗口(dock widgets)等。

QDialog:
QDialog 是一个对话框窗口的基类。对话框通常用于临时交互,例如消息框、文件对话框、设置对话框等。
QDialog 提供了对话框的标准外观和行为,包括窗口标题、按钮、标签等。它可以用于创建自定义对话框,也可以用作其他对话框类的基类。

QWidget:
QWidget 是 Qt 中所有用户界面组件的基类。它提供了绘制、事件处理、布局等功能,是其他所有用户界面组件的基础。
QWidget 可以独立存在,也可以嵌入到其他容器中,如窗口、对话框、布局等。它是所有可视化组件的基础,包括按钮、文本框、标签等。
总的来说,QMainWindow 用于创建主窗口应用程序,QDialog 用于创建对话框窗口,而 QWidget 则是所有用户界面组件的基类,可以用于创建各种自定义的用户界面元素。

ui->setupUi(this);

这行代码是在一个 Qt 应用程序中常见的一行。它通常出现在一个窗口或对话框的构造函数中。

ui 是指向用户界面类对象的指针,通常由 Qt 的用户界面设计器自动生成。这个指针提供了对用户界面中各种部件(如按钮、文本框、标签等)的访问。

setupUi(this) 是一个自动生成的函数,负责初始化用户界面。它会将用户界面中的各种部件和布局加载到指定的窗口或对话框中,以便用户界面能够正常显示和交互。

在这行代码中,this 表示当前窗口或对话框的指针,即指向当前对象的指针。通过将当前窗口或对话框的指针传递给 setupUi 函数,可以确保用户界面正确地加载到当前窗口或对话框中,以便用户可以与之进行交互。

ui界面的设计

1、移除状态栏和菜单栏
2、需要用到的控件
QPushButton(按钮): QPushButton是用于创建按钮的类,用户可以单击按钮执行特定的操作。按钮可以显示文本、图像或两者的组合,并且可以与特定的槽函数相关联,以便在用户单击按钮时触发相应的操作。

QLineEdit(行编辑器): QLineEdit用于接受单行文本输入,用户可以在其中输入文本或数字。它通常用于获取用户输入的信息,例如用户名、密码、搜索词等。

QGroupBox(分组框): QGroupBox是用于将相关的控件组合在一起的容器类。它通常用于创建具有相关功能或设置的组件集合,以便更好地组织和管理用户界面。放一起后要设置放在后面才能操作控件 groupbox的title可以重命名

QPlainTextEdit(纯文本编辑器): QPlainTextEdit是用于显示和编辑多行纯文本的控件。与QTextEdit相比,它不支持文本的富文本格式,但提供了更高的性能和更少的内存占用。

QHorizontalSlider(水平滑块): QHorizontalSlider是用于选择范围内数值的控件,用户可以通过拖动滑块来选择所需的值。它通常用于调整音量、亮度、进度等参数。

QLCDNumber(数码管): QLCDNumber是用于显示数字的控件,通常用于显示实时数据、计时器、测量值等。它的外观类似于数码管显示屏,可以显示整数或浮点数值。

ui界面搭建好要进行重命名

背景图片的插入

public:
    // 处理窗口重绘背景图片
    void paintEvent(QPaintEvent *event);

void paintEvent(QPaintEvent *event);:这是一个成员函数的声明,函数名为paintEvent,参数类型为QPaintEvent *指针类型的event。在Qt中,paintEvent函数用于处理窗口的重绘事件,即当窗口需要重新绘制时,会调用这个函数来进行绘制操作

QPainter qPainter(this);

QPainter:这是Qt中用于执行绘图操作的类。通过QPainter对象,可以在指定的绘图设备上绘制各种图形元素。

qPainter(this):这是创建QPainter对象的语法。括号内的参数指定了绘图的目标设备,通常是指定一个窗口、控件或绘图区域作为绘图的目标。在这里,this代表当前的窗口或控件,即表示绘图将在当前窗口或控件上进行。

qPainter.drawPixmap(0,0,width(),height(),QPixmap(":/new/prefix1/ResImages/a69782376c9e57fb395a139ba24cb66c.jpg"));

qPainter.drawPixmap(:这表示调用QPainter对象的drawPixmap函数开始绘制图片。

0, 0:这是图片的左上角在绘图设备中的坐标,即x和y坐标,通常是左上角的位置。

width()和height():这是绘图设备的宽度和高度,通常是窗口或控件的宽度和高度。这里使用了窗口或控件的宽度和高度作为绘制图片的宽度和高度,以便将图片绘制在整个窗口或控件上。

QPixmap(“:/new/prefix1/ResImages/a69782376c9e57fb395a139ba24cb66c.jpg”):这是要绘制的图片对象。QPixmap是Qt中用于表示图像的类,通过传递图片的路径或资源前缀来创建一个QPixmap对象。在这里,图片的路径是:/new/prefix1/ResImages/a69782376c9e57fb395a139ba24cb66c.jpg。

按钮转到槽(MainWindow标题的删除)

通过ui界面的按钮单击右键转到槽作为单机事件

首先先写关闭窗口

//关闭窗口
void MainWindow::on_pushButton_Exit_clicked()
{
    this->close();
}

紧接着要删除标题
在这里插入图片描述
就是上面所示的

在MainWindow的构造函数里面写

// 去掉窗口标题栏
this->setWindowFlag(Qt::FramelessWindowHint);

控件透明化

Qt的样式表(QSS)规则。QSS是Qt中用于定义用户界面控件样式的一种机制,类似于CSS(层叠样式表)。

font-size: 14px;
color: rgb(255, 255, 255);
background-color: rgba(255, 255, 255, 50);

font-size: 14px;:这行代码指定了文本的字体大小为14像素。

color: rgb(255, 255, 255);:这行代码设置了文本的颜色为白色,使用RGB表示法。

background-color: rgba(255, 255, 255, 50);:这行代码设置了背景颜色为半透明的白色。RGBA表示法中,前三个参数表示红色、绿色和蓝色通道的值,最后一个参数表示透明度。在这里,透明度设置为50,使得背景颜色呈现半透明效果。

这些样式规则可以应用于Qt应用程序中的控件,例如按钮、标签等,以定义它们的外观。通过将这些规则应用于控件,你可以改变它们的字体大小、颜色和背景颜色,以满足特定的设计需求或用户偏好。

按钮透明化

QPushButton
{
background-repeat:no-repeat;
background-position:center center;
border:none;
color:white;
}
QPushButton:hover{
background-repeat:no-repeat;
background-position:center center;
}
QPushButton:press{
background-repeat:no-repeat;
background-position:center center;
}

这些QSS规则用于自定义QPushButton控件的外观和行为

QPushButton:这是选择器,指定了应用规则的目标控件类型,即QPushButton。

在大括号 {} 内部的规则包括:

background-repeat: no-repeat;:设置背景图片不重复。
background-position: center center;:设置背景图片在按钮中水平和垂直方向上居中对齐。
border: none;:移除按钮的边框。
color: white;:设置文本颜色为白色。
QPushButton:hover:这是一个伪状态选择器,指定了鼠标悬停在按钮上时的样式。

在大括号 {} 内部的规则与普通状态下的样式相同,用于设置按钮在悬停状态下的样式。
QPushButton:press:这是另一个伪状态选择器,指定了按钮被按下时的样式。

在大括号 {} 内部的规则与普通状态下的样式相同,用于设置按钮在被按下状态下的样式。
通过这些规则,可以自定义QPushButton控件的外观,包括背景图片的布局和按钮文本的颜色,以及按钮在不同状态下的外观变化,例如悬停和按下状态

播放进度条控件美化

 ui->horizontalSlider_PlayProgress->setStyleSheet(
                  "QSlider::groove:horizontal {"
                  "border:1px solid skyblue;"
                  "background-color:skyblue;"
                  "height:10px;"
                  "border-radius:5px;"
                  "}"

                  "QSlider::handle:horizontal {"
                  "background:qradialgradient(spread:pad,cx:0.5,cy:0.5,radius:0.5,fx:0.5,fy:0.5,stop:0.7 white,stop:0.8 rgb(140,212,255));"
                  "width:20px;"
                  "border-radius:10px;"
                  "margin-top:-5px;"
                  "margin-bottom:-5px;}"

                  "horizontalSlider::sub-page:horizontal{"
                  "background:red;"
                  "margin:5px;"
                  "border-radius:5px;}"
                  );

    ui->horizontalSlider_Volume->setStyleSheet(
                  "QSlider::groove:horizontal {"
                  "border:1px solid skyblue;"
                  "background-color:skyblue;"
                  "height:10px;"
                  "border-radius:5px;"
                  "}"

                  "QSlider::handle:horizontal {"
                  "background:qradialgradient(spread:pad,cx:0.5,cy:0.5,radius:0.5,fx:0.5,fy:0.5,stop:0.7 white,stop:0.8 rgb(140,212,255));"
                  "width:20px;"
                  "border-radius:10px;"
                  "margin-top:-5px;"
                  "margin-bottom:-5px;}"

                  "horizontalSlider::sub-page:horizontal{"
                  "background:red;"
                  "margin:5px;"
                  "border-radius:5px;}"
                  );

这段代码是用于设置 horizontalSlider_PlayProgress 控件样式的,让我逐一解释:

QSlider::groove:horizontal:这部分规则用于定义水平滑块的轨道样式。

border:1px solid skyblue;:设置轨道的边框为1像素的天蓝色边框。
background-color: skyblue;:设置轨道的背景颜色为天蓝色。
height: 10px;:设置轨道的高度为10像素。
border-radius: 5px;:设置轨道的边框圆角半径为5像素。
QSlider::handle:horizontal:这部分规则用于定义水平滑块的样式。

background: qradialgradient(spread:pad, cx:0.5, cy:0.5, radius:0.5, fx:0.5, fy:0.5, stop:0.7 white, stop:0.8 rgb(140, 212, 255));:使用径向渐变作为滑块的背景,创建一个从白色到天蓝色的渐变。
width: 20px;:设置滑块的宽度为20像素。
border-radius: 10px;:设置滑块的边框圆角半径为10像素。
margin-top: -5px; 和 margin-bottom: -5px;:将滑块向上移动5像素,以使其垂直居中于轨道。
horizontalSlider::sub-page:horizontal:这部分规则用于定义水平滑块的子页面(在滑块的滑动范围内)的样式。

background: red;:设置子页面的背景颜色为红色。
margin: 5px;:设置子页面与滑块边界的间距为5像素。
border-radius: 5px;:设置子页面的边框圆角半径为5像素。
通过这些规则,你可以自定义水平滑块控件的外观,包括轨道、滑块和滑块的子页面。

    ui->horizontalSlider_Volume->setStyleSheet(
                  "QSlider::groove:horizontal {"
                  "border:1px solid white;"
                  "background-color:sky;"
                  "height:10px;"
                  "border-radius:5px;"
                  "}"

                  "QSlider::handle:horizontal {"
                  "background:qradialgradient(spread:pad,cx:0.5,cy:0.5,radius:0.5,fx:0.5,fy:0.5,stop:0.7 white,stop:0.8 rgb(140,212,255));"
                  "width:15px;"
                  "border-radius:10px;"
                  "margin-top:-5px;"
                  "margin-bottom:-5px;}"

                  "horizontalSlider::sub-page:horizontal{"
                  "background:red;"
                  "margin:5px;"
                  "border-radius:5px;}"
                  );

“QSlider::groove:horizontal {”: 这一行定义了水平滑块的轨道部分的样式。在这里,你设置了边框、背景颜色、高度和边框半径。

“border:1px solid white;”: 这一行设置轨道部分的边框为白色,宽度为 1 像素。

“background-color:sky;”: 这一行设置轨道部分的背景颜色为天蓝色。

“height:10px;”: 这一行设置轨道部分的高度为 10 像素。

“border-radius:5px;”: 这一行设置轨道部分的边框半径为 5 像素,使得轨道呈现圆角效果。

“QSlider::handle:horizontal {”: 这一行定义了水平滑块的滑块(手柄)的样式。在这里,你设置了滑块的背景颜色、宽度、边框半径以及上下外边距。

“background:qradialgradient(spread:pad,cx:0.5,cy:0.5,radius:0.5,fx:0.5,fy:0.5,stop:0.7 white,stop:0.8 rgb(140,212,255));”: 这一行使用径向渐变来设置滑块的背景。滑块的背景颜色从白色渐变到天蓝色,其中心位于滑块的中心。

“width:15px;”: 这一行设置滑块的宽度为 15 像素。

“border-radius:10px;”: 这一行设置滑块的边框半径为 10 像素,使得滑块呈现圆角效果。

“margin-top:-5px;”: 这一行设置滑块的顶部外边距为 -5 像素,以便让滑块垂直居中。

“margin-bottom:-5px;”: 这一行设置滑块的底部外边距为 -5 像素,以便让滑块垂直居中。

“horizontalSlider::sub-page:horizontal {”: 这一行定义了填充部分(已填充部分)的样式。在这里,你设置了填充部分的背景颜色、外边距和边框半径。

“background:red;”: 这一行设置填充部分的背景颜色为红色。

“margin:5px;”: 这一行设置填充部分的外边距为 5 像素。

“border-radius:5px;”: 这一行设置填充部分的边框半径为 5 像素,使得填充部分呈现圆角效果。

改变鼠标手势

ui界面点击控件寻找cursor

实现拖动主窗口

是为了是你写的界面能够拖动到桌面的任何位置

    // 功能:使用鼠标拖动窗口移动MP3播放器到桌面的任意位置
    //按压鼠标
    void mousePressEvent(QMouseEvent *event);
    //移动鼠标
    void mouseMoveEvent(QMouseEvent *event);
    //释放鼠标
    void mouseReleaseEvent(QMouseEvent *event);
    //鼠标拖动的bool类型
    bool m_MouseDrag;
    QPoint mouseStartPoint; // 获取鼠标的起始位置
    QPoint windowStartPoint; // 获取窗口的初始位置
// 功能:使用鼠标拖动窗口移动MP3播放器到桌面的任意位置
void MainWindow::mousePressEvent(QMouseEvent *event)
{
    if(event->button()==Qt::LeftButton)
    {
        //判断鼠标已经按下去了
        m_MouseDrag=true;
        //鼠标按下时的全局坐标
        mouseStartPoint=event->globalPos();
        //记录窗口移动前的位置 this指针指向的是Mainwindow
        //以窗口左上角为原点 相对于父窗口(或者屏幕)的坐标
        windowStartPoint=this->frameGeometry().topLeft();
    }

}

void MainWindow::mouseMoveEvent(QMouseEvent *event)
{
    if(m_MouseDrag)
    {
        // 获取鼠标移动的距离
        // 事件发生时候的全局坐标-鼠标按下时候的全局坐标=鼠标移动的距离
        QPoint m_Distance=event->globalPos()-mouseStartPoint;

        // 更改窗口的对应位置
        this->move(windowStartPoint+m_Distance);
    }

}

void MainWindow::mouseReleaseEvent(QMouseEvent *event)
{
    // 释放鼠标事件(左键)
    //event->button() 是一个方法,用于获取与事件相关的鼠标按钮的信息
    if(event->button()==Qt::LeftButton)
    {
        m_MouseDrag=false;
    }

}

event->button() 是一个用于获取鼠标事件中所按下的按钮的方法。
Qt::LeftButton 是 Qt 中用于表示鼠标左键的枚举常量之一。它表示鼠标事件中涉及到的是左键

mouseStartPoint = event->globalPos();:这行代码将鼠标按下时的全局位置(即相对于整个屏幕的位置)存储在变量 mouseStartPoint 中。这样做通常是为了后续计算鼠标移动的距离或者实现窗口的拖动功能。

windowStartPoint = this->frameGeometry().topLeft();:这行代码获取了窗口的左上角在屏幕上的位置,存储在变量 windowStartPoint 中。这通常在实现窗口拖动功能时使用,可以用来计算窗口移动的偏移量

显示图标

在ui界面下,找到windowicon进行添加即可

QMessagebox

//QMessageBox::information(this,"提示","关于对话框",QMessageBox::Yes);

当调用 QMessageBox::information 函数时,它接受四个参数,分别是:

parent:这是对话框的父对象。它指定了在对话框显示时的父级窗口。通常情况下,将 this 作为参数传递,表示当前窗口是对话框的父对象,这样对话框就会显示在当前窗口的顶部,并且与当前窗口关联。

title:这是对话框的标题,显示在对话框的顶部。在这个例子中,标题是 “提示”,它会显示在对话框的标题栏上。

text:这是对话框显示的消息文本。在这个例子中,消息文本是 “关于对话框”,它会显示在对话框的主体部分,用于向用户提供提示或信息。

buttons:这是对话框显示的按钮。它指定了对话框中要显示的按钮的类型。在这个例子中,使用了 QMessageBox::Yes,表示对话框只显示一个 “确定” 按钮,用于确认信息。用户点击该按钮后,对话框会关闭。

在我编写的代码里MainWindow是parent

pixmap

ui界面里面的pixmap 可以用来显示图标

信号与槽的机制

private slots:
void on_pushButton_CloseW_clicked();
void AboutDialog::on_pushButton_CloseW_clicked()
{
    this->close();
}

有人可能会有疑问这私有的 为什么能调用?

在 Qt 中,private slots 是一种特殊的声明,用于标记类中的私有槽函数。槽函数是在特定信号被触发时执行的函数。on_pushButton_CloseW_clicked() 函数被标记为一个私有槽函数,因此只能在类的内部被调用。

尽管这个槽函数是私有的,但通常情况下,它是由 Qt 的信号-槽机制触发的。例如,如果有一个名为 pushButton_CloseW 的按钮,并且与某个特定的信号(例如 clicked())关联了这个槽函数,那么当用户点击该按钮时,Qt 将自动调用这个槽函数。

因此,尽管 on_pushButton_CloseW_clicked() 是私有的,但它可以被 Qt 的信号-槽机制调用

调整dialog对话框的位置

让对话框的位置在中心点

AboutDialog *pAboutDialogs=new AboutDialog(this);//this指向的是MainWindow(dialog的父类)

//QRect 是 Qt 框架中用于表示矩形的类。它通常用于指定矩形区域的位置和大小。
QRect qRect=geometry();//MainWindow的位置
int iX=qRect.x()+61;
int iY=qRect.y()+103;
//对话框的坐标 以及宽和高
//此时的指针仍然指向的是堆区
//传入MainWindow的x与y 与 dialog的x y进行相减 再除以2    
pAboutDialogs->setGeometry(iX,iY,453,394); // 331 187   

多媒体模块和网络编程模块的添加

QT += multimedia
QT += network

在pro后缀的文件 加入这两个模块 分别是多媒体 和 网络编程的模块

在QT += core gui后面加入即可

头文件的添加:

#include <QMainWindow>
#include <QPainter>
#include <QMessageBox>
// 使用该类可以进行网络请求、获取响应、处理错误等操作
#include <QNetworkAccessManager>
// QNetworkReply是QNetworkAccessManager发送请求之后返回的响应类
#include <QNetworkReply>
#include "aboutdialog.h"
// 添加多媒体播放器类 播放 暂停 停止
#include <QMediaPlayer>
// 添加多媒体播放列表类
#include <QMediaPlaylist>
//文本段落读取
#include <QTextBlock>
//QT定时器
#include <QTimer>
//打开本地文件
#include <QFileDialog>

// 用于解析JSON数据时错误处理类
#include <QJsonParseError>
// 用于操作JSON数组的类   用于修改数据等操作
#include <QJsonObject>

#include <QLCDNumber>

:这个头文件是用来包含 Qt 中的 LCD 数字显示部件的相关定义。LCD 数字显示部件是用于显示数字值的控件,通常用于显示数字型数据,比如计数器的值或者时间等。通过包含 头文件,你可以在你的代码中使用 LCD 数字显示部件,进行数字值的显示和控制。

:这个头文件是用来包含 Qt 中 JSON 数组的相关定义。JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,常用于在不同系统之间传输和存储数据。 头文件提供了操作和处理 JSON 数组的类和函数,使得在 Qt 应用程序中可以方便地处理 JSON 数据。

通过包含这两个头文件,可以在 Qt 应用程序中使用 LCD 数字显示部件和处理 JSON 数据的功能。

光标的操作

  // 将光标焦点定位到搜索歌曲名称控件当中  光标就是|
  ui->lineEdit_InputSongs->setFocus();

在这里插入图片描述
这就是光标 就是|

相关模块指针的定义

	QMediaPlayer *p_PlayerObject; // 定义多媒体播放器
    QMediaPlaylist *p_PlayerList; // 定义多媒体播放列表

    //QString StrLocalMusicPath; // 导入本地音乐路径

    // 歌曲ID
    int I_MusicID;
    // 歌曲名称 歌手姓名
    QString StrMusicName,StrSingerName;


    int iPlayFlags; // 标记播放状态

    QByteArray QByteArySearchInfo; // 存储搜索音乐返回数据信息
    QTextDocument *docTextObject; // 处理富文本内容  获取文本对象的内容
    QTextBlock *qTextLine; // 处理文本块指针

    QNetworkAccessManager *NetworkAccessManagers;

富文本内容实际上就是这一块的内容
在这里插入图片描述

  // 将光标焦点定位到搜索歌曲名称控件当中  光标就是|
  ui->lineEdit_InputSongs->setFocus();

  // 初始化QNetworkAccessManager一个实例
  NetworkAccessManagers=new QNetworkAccessManager(this);

  iPlayFlags=0; // 标记播放状态为0

  // 文本对象
  docTextObject=ui->plainTextEdit_SongList->document();
  // 将控件设置为只读
  ui->plainTextEdit_SongList->setReadOnly(true);

  // 初始化多媒体实例
  p_PlayerObject=new QMediaPlayer(this);
  p_PlayerList=new QMediaPlaylist(this);
  // 设置播放列表
  p_PlayerObject->setMedia(p_PlayerList);
  // 设置播放模式
  p_PlayerList->setPlaybackMode(QMediaPlaylist::Loop);

docTextObject=ui->plainTextEdit_SongList->document();:获取了名为 plainTextEdit_SongList 的文本编辑器部件的文档对象,并将其赋值给 docTextObject。这样可以在代码中访问文本编辑器中的文档对象,从而对文本内容进行操作。

ui->plainTextEdit_SongList->setReadOnly(true);:将名为 plainTextEdit_SongList 的文本编辑器部件设置为只读模式,这意味着用户无法编辑其中的文本内容。

p_PlayerObject=new QMediaPlayer(this); 和 p_PlayerList=new QMediaPlaylist(this);:创建了两个多媒体相关的对象实例。QMediaPlayer 是用于播放音频和视频文件的多媒体播放器类,而 QMediaPlaylist 是用于管理播放列表的类。

p_PlayerObject->setMedia(p_PlayerList);:将播放列表 p_PlayerList 设置为多媒体播放器 p_PlayerObject 的媒体内容。这样,当播放器开始播放时,它将按照设置的播放列表进行播放。

p_PlayerList->setPlaybackMode(QMediaPlaylist::Loop);:设置播放列表的播放模式为循环播放模式。这意味着当播放列表中的最后一首歌曲播放完成后,播放器将自动从头开始循环播放整个播放列表中的歌曲。

自定义的槽函数

   // 自定义槽函数
public slots:
   // 处理数据信息返回函数
   void HandleDataBackFunc(QNetworkReply *pReply);

   // 处理LCDNumber控件时间变化
   void HandleLCDNumerTimeChangeFunc(qint64 SongDuration);

   // 处理进度条控件变化
   void HandleProgressTimeChangeFunc(qint64 SongDuration);

   // 处理播放位置变化
   void HandlePositionChangeFunc(qint64 position);

qint64 是 Qt 中定义的一个整数数据类型,用于表示带符号的 64 位整数。在 C++ 标准库中,通常使用 long long int 来表示 64 位整数,但 Qt 为了跨平台的兼容性和一致性,引入了 qint64 类型来代替标准库中的 long long int。

qint64 类型在 Qt 库的头文件 qglobal.h 中定义,其实际类型取决于编译器和平台,但通常被定义为 long long int。

使用 qint64 类型可以确保在所有平台上对于 64 位整数的操作都是一致的,并且能够正确处理大于 32 位的整数值,比如文件大小、时间戳等。因此,在 Qt 中处理大整数时,推荐使用 qint64 类型

为什么定义为这些为槽函数?
当某个对象发出了一个信号,比如一个按钮被点击,或者一个网络请求完成,与之相关联的槽函数将被执行。这些槽函数通常用于响应这些事件,执行特定的操作,比如更新界面、处理数据等

  // 信号与槽处理如下
  connect(p_PlayerObject,SIGNAL(positionChanged(qint64)),this,SLOT(HandleLCDNumerTimeChangeFunc(qint64)));
  connect(p_PlayerObject,SIGNAL(positionChanged(qint64)),this,SLOT(HandlePositionChangeFunc(qint64)));
  connect(p_PlayerObject,SIGNAL(durationChanged(qint64)),this,SLOT(HandleProgressTimeChangeFunc(qint64)));

  connect(NetworkAccessManagers,SIGNAL(finished(QNetworkReply*)),this,SLOT(HandleDataBackFunc(QNetworkReply*)));

具体来说:

connect(p_PlayerObject,SIGNAL(positionChanged(qint64)),this,SLOT(HandleLCDNumerTimeChangeFunc(qint64)));:将 p_PlayerObject(多媒体播放器对象)的 positionChanged 信号连接到当前对象(可能是一个窗口或控制器)的 HandleLCDNumerTimeChangeFunc(qint64) 槽函数上。这意味着当播放器的播放位置发生变化时,HandleLCDNumerTimeChangeFunc 函数将被调用,传递当前播放位置作为参数。

connect(p_PlayerObject,SIGNAL(positionChanged(qint64)),this,SLOT(HandlePositionChangeFunc(qint64)));:将 p_PlayerObject 的 positionChanged 信号连接到当前对象的 HandlePositionChangeFunc(qint64) 槽函数上。这意味着当播放器的播放位置发生变化时,HandlePositionChangeFunc 函数将被调用,传递当前播放位置作为参数。

connect(p_PlayerObject,SIGNAL(durationChanged(qint64)),this,SLOT(HandleProgressTimeChangeFunc(qint64)));:将 p_PlayerObject 的 durationChanged 信号连接到当前对象的 HandleProgressTimeChangeFunc(qint64) 槽函数上。这意味着当播放器的媒体文件持续时间发生变化时,HandleProgressTimeChangeFunc 函数将被调用,传递当前播放位置作为参数。

connect(NetworkAccessManagers,SIGNAL(finished(QNetworkReply*)),this,SLOT(HandleDataBackFunc(QNetworkReply*)));:将 NetworkAccessManagers(可能是一个网络访问管理器对象)的 finished 信号连接到当前对象的 HandleDataBackFunc(QNetworkReply*) 槽函数上。这意味着当网络请求完成时,HandleDataBackFunc 函数将被调用,传递完成的网络回复对象作为参数。

通过这些连接,程序可以在特定的事件发生时执行相应的操作,比如更新界面、处理数据等。这种信号-槽机制使得 Qt 应用程序的设计更加灵活和可扩展。

信号与槽的解释

在 connect 函数中,有四个参数,分别是信号源对象、发射的信号、接收信号的对象以及槽函数。

信号源对象:指的是发送信号的对象,通常是 Qt 中的某个 QObject 或其子类的实例。p_PlayerObject 和 NetworkAccessManagers 就是信号源对象。

发射的信号:是指信号源对象发出的信号。在 Qt 中,信号是一种特殊的成员函数,用于通知其他对象发生了某种特定的事件或状态变化。例如,在你的代码中,positionChanged(qint64) 和 durationChanged(qint64) 就是两个信号。

接收信号的对象:是指接收并处理信号的对象。通常是当前对象(this)或其他 QObject 或其子类的实例。在你的代码中,this 表示当前对象,可能是一个窗口或控制器。

槽函数:是在接收信号的对象中定义的函数,用于处理信号被发射时所执行的操作。槽函数可以是任何普通的成员函数,其声明方式类似于常规的 C++ 函数。在你的代码中,HandleLCDNumerTimeChangeFunc(qint64)、HandlePositionChangeFunc(qint64)、HandleProgressTimeChangeFunc(qint64) 和 HandleDataBackFunc(QNetworkReply*) 分别是四个槽函数。

所以,connect 函数的作用是将信号源对象发出的特定信号与接收信号的对象中的相应槽函数进行连接,这样当信号被发射时,相应的槽函数就会被执行。这里槽函数传入的是类型 就是函数的占位参数

搜索歌曲的实现

// 搜索歌曲名称实现
void MainWindow::on_pushButton_SearchSong_clicked()
{
    QString str1,str2;
    //str1用来获取文本
    str1=ui->lineEdit_InputSongs->text();
    //通过调用的api进行搜索str1 请求过去了
    str2="http://music.163.com/api/search/get/web?csrf_token=hlpretag=&hlposttag=&s={"+str1+"}&type=1&offset=0&total=true&limit=1";

    // 定义一个QNetworkRequest请求对象
    QNetworkRequest networkRequest;
    
    // 将请求格式设置给对应请求对象  
    networkRequest.setUrl(str2);

    // 使用QNetworkAccessManager类对应的API发送GET请求并获取响应数据
    NetworkAccessManagers->get(networkRequest); // 请求处理
}

这段代码是一个用于搜索歌曲名称的功能实现。让我逐行解释:

void MainWindow::on_pushButton_SearchSong_clicked():这是一个槽函数,通常会在用户点击名为 pushButton_SearchSong 的按钮时被调用。这个函数属于 MainWindow 类的一部分。

QString str1, str2;:声明了两个字符串变量 str1 和 str2,用于存储用户输入的歌曲名称和构建的搜索请求 URL。

str1 = ui->lineEdit_InputSongs->text();:从名为 lineEdit_InputSongs 的文本框中获取用户输入的歌曲名称,并将其存储在 str1 中。

构建搜索请求 URL:这一行代码将用户输入的歌曲名称拼接到了一个固定的 URL 中,形成一个完整的搜索请求 URL。这个 URL 包含了搜索参数和用户输入的歌曲名称,以便向特定的音乐 API 发送请求。

QNetworkRequest networkRequest;:创建了一个 QNetworkRequest 对象 networkRequest,用于发送网络请求。

networkRequest.setUrl(str2);:将之前构建好的搜索请求 URL 设置给 networkRequest 对象,以便发送给服务器。

NetworkAccessManagers->get(networkRequest);:使用 NetworkAccessManagers 对象(可能是一个 QNetworkAccessManager 类的实例)发送一个 GET 请求,并传递了之前构建的请求对象 networkRequest。这样,服务器将收到这个请求,并返回相应的数据。

总的来说,这段代码的作用是获取用户输入的歌曲名称,构建一个搜索请求 URL,并使用 QNetworkAccessManager 类发送这个请求,以获取相应的搜索结果数据。

信号的解释

positionChanged 信号

positionChanged 信号通常用于在多媒体播放器中指示当前播放位置发生变化。在 Qt 中,这个信号可能与音频或视频播放器相关联,用于通知应用程序当前媒体的播放位置已经改变。

当播放器播放媒体文件时,它会不断地更新播放位置,例如每秒更新一次。每当播放位置发生变化时,就会发射 positionChanged 信号,告知相关的槽函数或连接了这个信号的对象当前的播放位置。

通常情况下,这个信号会携带一个参数,指示当前的播放位置。在你提供的代码中,positionChanged 信号的参数类型是 qint64,这意味着它传递的是一个64位整数,用来表示播放位置的时间戳或帧数。

这个信号的使用场景包括但不限于:

实时更新播放进度条或时间显示;
控制音频或视频播放器的播放进度;
根据播放位置执行特定的操作,比如在特定时间点触发事件等。

信号durationChanged

durationChanged 信号通常与多媒体播放器相关联,用于指示媒体文件的持续时间发生了变化。在 Qt 中,这个信号会在播放器加载新的媒体文件或者检测到媒体文件的持续时间变化时发射。

当一个新的媒体文件被加载到播放器中时,播放器会读取该文件的持续时间信息,并将其作为媒体文件的属性之一。如果在播放过程中切换到了另一个媒体文件,或者当前媒体文件的持续时间发生了变化(例如,用户通过特定操作修改了媒体文件),那么就会触发 durationChanged 信号。

这个信号的携带参数通常是一个 qint64 类型的整数,表示新的持续时间。接收到这个信号的槽函数可以根据新的持续时间进行相应的处理,比如更新界面上显示的总时长信息。

使用 durationChanged 信号的场景包括但不限于:

在加载新的媒体文件时更新播放器的总时长信息;
监听用户修改媒体文件持续时间的操作,并更新相关显示信息;
根据媒体文件的总时长进行特定操作,比如设置播放进度条的最大值等。

SIGNAL(finished(QNetworkReply*))

这是一个 Qt 信号(Signal),用于表示当一个 QNetworkReply 对象完成时发出的信号。在 Qt 中,SIGNAL() 宏用于将信号的名称转换为字符串,以便在使用信号与槽机制时进行连接。

具体来说,finished(QNetworkReply*) 信号在一个 QNetworkReply 对象完成网络请求并且接收到响应时发出。通常情况下,这个信号会连接到一个槽函数,以便在网络请求完成后执行一些特定的操作,比如处理响应数据或者更新用户界面。

处理数据信息返回函数

// 处理数据信息返回函数
void MainWindow::HandleDataBackFunc(QNetworkReply *pReply)
{

    // 读取网络回馈数据 存放搜索音乐返回的数据信息的指针
    // 将网络回复的所有数据读取到字节数组 QByteArySearchInfo 中
    QByteArySearchInfo=pReply->readAll();

    // 用于存储 JSON 解析过程中的错误信息
    // 存储 JSON 解析过程中的错误信息是为了在解析出现问题时能够及时捕获和处理这些错误
    QJsonParseError JSonPError; 

    // 将json文本转换为json文件对象
    // 将从网络请求返回的原始数据解析为 JSON 文档对象
    QJsonDocument JSonDoc_RecvData=QJsonDocument::fromJson(QByteArySearchInfo,&JSonPError);
            
    // 如果解析过程中出现了错误,则执行条件体中的代码
    if(JSonPError.error != QJsonParseError::NoError)
    {
        //错误的情况下的QMessageBox用的是critical
        QMessageBox::critical(this,"Prompt","提示:搜索歌曲获取json格式错误,请重新检查?",QMessageBox::Yes);
        return;
    }

    // QJsonObject使用函数object()
    // JSonDoc_RecvData 是一个 QJsonDocument 对象,代表从网络请求返回的数据解析得到的 JSON 文档对象
    // object() 是 QJsonDocument 类的成员函数,用于获取 JSON 文档的根对象(也就是 JSON 数据的顶层对象)
    // 这里将其赋值给 TotalJsonOjbect 变量,它是一个 QJsonObject 对象
    QJsonObject TotalJsonOjbect=JSonDoc_RecvData.object();
    // 列出json里面所有的key
    // keys() 是 QJsonObject 类的成员函数,用于获取 JSON 对象中所有键的列表
    QStringList strKeys=TotalJsonOjbect.keys();
    //用于检查 JSON 数据中是否包含键名为 "result" 的键。如果存在,则执行条件体中的代码,表示有数据信息需要进一步处理
    if(strKeys.contains("result"))
    {
        // 将带有result的数据内容提取之后转换为对象
        QJsonObject resultobject=TotalJsonOjbect["result"].toObject();

        // 存储所有keys
        QStringList strResultKeys=resultobject.keys();

        // 如果keys是songs,证明搜索到对应的歌曲,可以参考官网提提供API
        if(strResultKeys.contains("songs"))
        {
            QJsonArray array = resultobject["songs"].toArray();

            // 通过for循环查找歌曲当中的字段信息
            // 这是一个范围-based 循环,用于遍历 array 中的每个元素,isong 是当前迭代的 JSON 元素
            for(auto isong:array)
            {
                QJsonObject jsonobect1=isong.toObject();

                // 获取歌曲ID 歌名 歌手
                I_MusicID=jsonobect1["id"].toInt();//转化为整型
                StrMusicName=jsonobect1["name"].toString();//转化为string类型

                QStringList strkeys=jsonobect1.keys();

                if(strkeys.contains("artists"))
                {
                    QJsonArray artistsjsonarray=jsonobect1["artists"].toArray();
                    for(auto js:artistsjsonarray)
                    {
                        QJsonObject jsonobject2=js.toObject();
                        StrSingerName=jsonobject2["name"].toString();
                    }
                }
            }
        }
    }

    QString strURL;
    //要根据音乐id去搜索  %0指的是所有的歌曲
    strURL=QString("https://music.163.com/song/media/outer/url?id=%0").arg(I_MusicID);
    // 将构建好的音乐播放 URL 转换为 QUrl 类型,并添加到音乐播放列表 p_PlayerList 中
    // URL 是统一资源定位符(Uniform Resource Locator)的缩写,它是用于在互联网上定位资源的地址。
    // URL 通常由多个部分组成,包括协议、主机名(或 IP 地址)、端口号、路径、查询参数和片段等
    p_PlayerList->addMedia(QUrl(strURL));
    // 将歌曲名称和艺术家名称连接成一个字符串,用 "-" 分隔,然后将其添加到名为 plainTextEdit_SongList 的文本框中
    ui->plainTextEdit_SongList->appendPlainText(StrMusicName+"-"+StrSingerName);


}


导入本地音乐

//添加音乐
void MainWindow::on_pushButton_AddSong_clicked()
{
    QString strCurrentPaths=QDir::homePath();
    QString strDlgTitle="请选择MP3音乐文件";
    QString strFilters="所有文件(*.*);;音频文件(*.mp3);;mp3文件(*.mp3)";

    QStringList strMp3FileList=QFileDialog::getOpenFileNames(this,strDlgTitle,strCurrentPaths,strFilters);

    if(strMp3FileList.count()<1)
        return ;

    for (int i=0;i<strMp3FileList.count();i++)
    {
        QString strFiles=strMp3FileList.at(i);

        // 将音乐文件添加播放列表
        p_PlayerList->addMedia(QUrl::fromLocalFile(strFiles));

        QFileInfo qFileInfo(strFiles);

        // 将歌曲添加到plainTextEdit控件
        ui->plainTextEdit_SongList->appendPlainText(qFileInfo.fileName());
    }

    // 添加完毕立刻播放
    if(p_PlayerObject->state()!=QMediaPlayer::PlayingState)
        p_PlayerList->setCurrentIndex(0);

    p_PlayerObject->play();
}

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐