├── HiLogo4.ico
├── HiPlayer_test.pro
├── HiPlayer_test.pro.user
├── aboutDialog.cpp
├── aboutDialog.h
├── hiButton.cpp
├── hiButton.h
├── hiLabel.cpp
├── hiLabel.h
├── hiLrcWidget.cpp
├── hiLrcWidget.h
├── hiVolBotton.cpp
├── hiVolBotton.h
├── hiplayer.cpp
├── hiplayer.h
├── icon.qrc
├── lrcLabel.cpp
├── lrcLabel.h
├── main.cpp
├── miniWindow.cpp
├── miniWindow.h
├── network.cpp
├── network.h
├── nofocusdelegate.cpp
├── nofocusdelegate.h
├── playslider.cpp
├── playslider.h
├── readme.md
├── resources
├── HiLogo.png
├── HiLogo4.ico
├── HiLogo_2.ico
├── HiPlayer_16_16_2.png
├── HiPlayer_256_256_2.png
├── HiPlayer_32_32_2.png
├── HiPlayer_38_38.png
├── HiPlayer_48_48_2.png
├── HiPlayer_80_80_2.png
├── Last_40_40.png
├── Lyric_40_40.png
├── Next_40_40.png
├── Pause_100_100.png
├── Pause_60_60.png
├── Play_100_100.png
├── Play_60_60.png
├── Volumn_40_40.png
├── about.png
├── addMusic_40_40.png
├── album.png
├── background.png
├── default_album.jpg
├── last_mini.png
├── lrc_background.png
├── max_mini.png
├── mini_back.png
├── mode.png
├── next_mini.png
├── pause_mini.png
├── play_mini.png
├── 关闭.png
├── 播放按钮mini.png
├── 最小化.png
└── 缩小.png
├── singleApp.cpp
├── singleApp.h
└── songinfo.h
/HiLogo4.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiaolong361/HiPlayer/441f1cab106a1c5c3f80c8cc07d6b286034e13ea/HiLogo4.ico
--------------------------------------------------------------------------------
/HiPlayer_test.pro:
--------------------------------------------------------------------------------
1 | #-------------------------------------------------
2 | #
3 | # Project created by QtCreator 2017-12-19T16:32:58
4 | #
5 | #-------------------------------------------------
6 |
7 | QT += core gui network multimedia
8 |
9 | greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
10 |
11 | TARGET = HiPlayer
12 | TEMPLATE = app
13 |
14 | #RC_ICONS = logo.ico
15 | RC_ICONS = HiLogo4.ico
16 | CONFIG += c++11
17 | # The following define makes your compiler emit warnings if you use
18 | # any feature of Qt which as been marked as deprecated (the exact warnings
19 | # depend on your compiler). Please consult the documentation of the
20 | # deprecated API in order to know how to port your code away from it.
21 | DEFINES += QT_DEPRECATED_WARNINGS
22 |
23 | # You can also make your code fail to compile if you use deprecated APIs.
24 | # In order to do so, uncomment the following line.
25 | # You can also select to disable deprecated APIs only up to a certain version of Qt.
26 | #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
27 |
28 |
29 | SOURCES += main.cpp\
30 | hiButton.cpp \
31 | aboutDialog.cpp \
32 | hiLabel.cpp \
33 | lrcLabel.cpp \
34 | hiLrcWidget.cpp \
35 | hiVolBotton.cpp \
36 | singleApp.cpp \
37 | nofocusdelegate.cpp \
38 | network.cpp \
39 | hiplayer.cpp \
40 | miniWindow.cpp \
41 | playslider.cpp
42 |
43 | HEADERS += \
44 | hiButton.h \
45 | aboutDialog.h \
46 | hiLabel.h \
47 | lrcLabel.h \
48 | hiLrcWidget.h \
49 | hiVolBotton.h \
50 | singleApp.h \
51 | songinfo.h \
52 | nofocusdelegate.h \
53 | network.h \
54 | hiplayer.h \
55 | miniWindow.h \
56 | playslider.h
57 |
58 | RESOURCES += \
59 | icon.qrc
60 |
--------------------------------------------------------------------------------
/HiPlayer_test.pro.user:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | EnvironmentId
7 | {2ded4aa9-436d-4906-a6f4-6cd40ced68f4}
8 |
9 |
10 | ProjectExplorer.Project.ActiveTarget
11 | 0
12 |
13 |
14 | ProjectExplorer.Project.EditorSettings
15 |
16 | true
17 | false
18 | true
19 |
20 | Cpp
21 |
22 | CppGlobal
23 |
24 |
25 |
26 | QmlJS
27 |
28 | QmlJSGlobal
29 |
30 |
31 | 2
32 | UTF-8
33 | false
34 | 4
35 | false
36 | 80
37 | true
38 | true
39 | 1
40 | true
41 | false
42 | 0
43 | true
44 | true
45 | 0
46 | 8
47 | true
48 | 1
49 | true
50 | true
51 | true
52 | false
53 |
54 |
55 |
56 | ProjectExplorer.Project.PluginSettings
57 |
58 |
59 |
60 | ProjectExplorer.Project.Target.0
61 |
62 | Desktop Qt 5.8.0 MinGW 32bit
63 | Desktop Qt 5.8.0 MinGW 32bit
64 | qt.58.win32_mingw53_kit
65 | 0
66 | 0
67 | 0
68 |
69 | I:/HiPlayer/build-HiPlayer-Desktop_Qt_5_8_0_MinGW_32bit-Debug
70 |
71 |
72 | true
73 | qmake
74 |
75 | QtProjectManager.QMakeBuildStep
76 | true
77 |
78 | false
79 | false
80 | false
81 |
82 |
83 | true
84 | Make
85 |
86 | Qt4ProjectManager.MakeStep
87 |
88 | false
89 |
90 |
91 |
92 | 2
93 | 构建
94 |
95 | ProjectExplorer.BuildSteps.Build
96 |
97 |
98 |
99 | true
100 | Make
101 |
102 | Qt4ProjectManager.MakeStep
103 |
104 | true
105 | clean
106 |
107 |
108 | 1
109 | 清理
110 |
111 | ProjectExplorer.BuildSteps.Clean
112 |
113 | 2
114 | false
115 |
116 | Debug
117 |
118 | Qt4ProjectManager.Qt4BuildConfiguration
119 | 2
120 | true
121 |
122 |
123 | I:/HiPlayer/HiPlayer_test/build-HiPlayer_test-Desktop_Qt_5_8_0_MinGW_32bit-Release
124 |
125 |
126 | true
127 | qmake
128 |
129 | QtProjectManager.QMakeBuildStep
130 | false
131 |
132 | false
133 | false
134 | false
135 |
136 |
137 | true
138 | Make
139 |
140 | Qt4ProjectManager.MakeStep
141 |
142 | false
143 |
144 |
145 |
146 | 2
147 | 构建
148 |
149 | ProjectExplorer.BuildSteps.Build
150 |
151 |
152 |
153 | true
154 | Make
155 |
156 | Qt4ProjectManager.MakeStep
157 |
158 | true
159 | clean
160 |
161 |
162 | 1
163 | 清理
164 |
165 | ProjectExplorer.BuildSteps.Clean
166 |
167 | 2
168 | false
169 |
170 | Release
171 |
172 | Qt4ProjectManager.Qt4BuildConfiguration
173 | 0
174 | true
175 |
176 |
177 | I:/HiPlayer/HiPlayer_test/build-HiPlayer_test-Desktop_Qt_5_8_0_MinGW_32bit-Profile
178 |
179 |
180 | true
181 | qmake
182 |
183 | QtProjectManager.QMakeBuildStep
184 | true
185 |
186 | false
187 | true
188 | false
189 |
190 |
191 | true
192 | Make
193 |
194 | Qt4ProjectManager.MakeStep
195 |
196 | false
197 |
198 |
199 |
200 | 2
201 | 构建
202 |
203 | ProjectExplorer.BuildSteps.Build
204 |
205 |
206 |
207 | true
208 | Make
209 |
210 | Qt4ProjectManager.MakeStep
211 |
212 | true
213 | clean
214 |
215 |
216 | 1
217 | 清理
218 |
219 | ProjectExplorer.BuildSteps.Clean
220 |
221 | 2
222 | false
223 |
224 | Profile
225 |
226 | Qt4ProjectManager.Qt4BuildConfiguration
227 | 0
228 | true
229 |
230 | 3
231 |
232 |
233 | 0
234 | 部署
235 |
236 | ProjectExplorer.BuildSteps.Deploy
237 |
238 | 1
239 | 在本地部署
240 |
241 | ProjectExplorer.DefaultDeployConfiguration
242 |
243 | 1
244 |
245 |
246 | false
247 | false
248 | 1000
249 |
250 | true
251 |
252 | false
253 | false
254 | false
255 | false
256 | true
257 | 0.01
258 | 10
259 | true
260 | 1
261 | 25
262 |
263 | 1
264 | true
265 | false
266 | true
267 | valgrind
268 |
269 | 0
270 | 1
271 | 2
272 | 3
273 | 4
274 | 5
275 | 6
276 | 7
277 | 8
278 | 9
279 | 10
280 | 11
281 | 12
282 | 13
283 | 14
284 |
285 | 2
286 |
287 | HiPlayer_test
288 |
289 | Qt4ProjectManager.Qt4RunConfiguration:I:/HiPlayer/HiPlayer/HiPlayer_test.pro
290 | true
291 |
292 | HiPlayer_test.pro
293 | false
294 |
295 | I:/HiPlayer/build-HiPlayer-Desktop_Qt_5_8_0_MinGW_32bit-Debug
296 | 3768
297 | false
298 | true
299 | false
300 | false
301 | true
302 |
303 | 1
304 |
305 |
306 |
307 | ProjectExplorer.Project.TargetCount
308 | 1
309 |
310 |
311 | ProjectExplorer.Project.Updater.FileVersion
312 | 18
313 |
314 |
315 | Version
316 | 18
317 |
318 |
319 |
--------------------------------------------------------------------------------
/aboutDialog.cpp:
--------------------------------------------------------------------------------
1 | #include "aboutDialog.h"
2 | #include "hiButton.h"
3 |
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 |
11 | AboutDialog::AboutDialog(QWidget *parent)
12 | :QDialog(parent)
13 | ,m_Moveing(false)
14 | {
15 | m_exitButton = new HiButton(this);
16 | m_exitButton->setObjectName(QStringLiteral("exitButton"));
17 | m_exitButton->setGeometry(QRect(240, 14, 30, 30));
18 | QIcon icon_exit, icon_exit_focus;
19 | icon_exit.addFile(QStringLiteral(":/hiplayer/resources/关闭.png"), QSize(), QIcon::Normal, QIcon::Off);
20 | icon_exit_focus.addFile(QStringLiteral(":/hiplayer/resources/关闭按钮.png"), QSize(), QIcon::Normal, QIcon::Off);
21 | m_exitButton->hi_setButtonIcons(icon_exit, icon_exit);
22 |
23 | m_exitButton->setIconSize(QSize(20,20));
24 | m_exitButton->setFlat(true);
25 | m_exitButton->setFocusPolicy(Qt::NoFocus);
26 | //RGB(255,255,255)表示白色.基本语法:{color: Rgba (red, green, blue, opacity)}
27 | m_exitButton->setStyleSheet("QPushButton{background-color:rgba(255,255,255,0);border-style:solid;border-width:0px;border-color:rgba(255,255,255,0);}");
28 |
29 | connect(m_exitButton, SIGNAL(clicked()), this, SLOT(close()));
30 |
31 | //去除标题栏,需要自定义窗口的拖动
32 | this->setWindowFlags(Qt::FramelessWindowHint);
33 |
34 | //设置窗体背景透明,配合paintEvent设置不规则背景图
35 | setAttribute(Qt::WA_TranslucentBackground);
36 |
37 | //半透明
38 | this->setWindowOpacity(0.9);
39 |
40 | //固定大小
41 | this->setFixedSize(290, 310);
42 |
43 | //模态窗口(即弹出后无法点击主界面)
44 | this->setModal(true);
45 | }
46 |
47 | void AboutDialog::paintEvent(QPaintEvent * )
48 | {
49 | QPainter p(this);
50 | p.drawPixmap(0, 0 , QPixmap(":/hiplayer/resources/about.png"));
51 | }
52 |
53 | AboutDialog::~AboutDialog()
54 | {}
55 |
56 | void AboutDialog::mousePressEvent(QMouseEvent *event)
57 | {
58 | m_Moveing=true;
59 | //记录下鼠标相对于窗口的位置
60 | //event->globalPos()鼠标按下时,鼠标相对于整个屏幕位置
61 | //pos() this->pos()鼠标按下时,窗口相对于父窗口的位置
62 | m_MovePosition=event->globalPos() - pos();
63 | return QDialog::mousePressEvent(event);
64 | }
65 |
66 | void AboutDialog::mouseMoveEvent(QMouseEvent *event)
67 | {
68 | //(event->buttons() && Qt::LeftButton)按下是左键
69 | //鼠标移动事件需要移动窗口,窗口移动到哪里呢?就是要获取鼠标移动中,窗口在整个屏幕的坐标,然后move到这个坐标,怎么获取坐标?
70 | //通过事件event->globalPos()知道鼠标坐标,鼠标坐标减去鼠标相对于窗口位置,就是窗口在整个屏幕的坐标
71 | if (m_Moveing && (event->buttons() && Qt::LeftButton)
72 | && (event->globalPos()-m_MovePosition).manhattanLength() > QApplication::startDragDistance())
73 | {
74 | move(event->globalPos()-m_MovePosition);//相对于桌面的位置.
75 | m_MovePosition = event->globalPos() - pos();
76 | }
77 | return QDialog::mouseMoveEvent(event);
78 | }
79 |
80 | void AboutDialog::mouseReleaseEvent(QMouseEvent *)
81 | {
82 | m_Moveing=false;
83 | }
84 |
--------------------------------------------------------------------------------
/aboutDialog.h:
--------------------------------------------------------------------------------
1 | #ifndef ABOUT_H
2 | #define ABOUT_H
3 |
4 | #include
5 | #include
6 |
7 | class HiButton;
8 |
9 | class AboutDialog : public QDialog
10 | {
11 | Q_OBJECT
12 | public:
13 | AboutDialog(QWidget *parent = 0);
14 | ~AboutDialog();
15 |
16 |
17 | protected:
18 | void paintEvent(QPaintEvent *event); //用窗口绘制事件来绘制背景图片
19 |
20 | void mousePressEvent(QMouseEvent *event);
21 | void mouseMoveEvent(QMouseEvent *event);
22 | void mouseReleaseEvent(QMouseEvent *event);
23 | private slots:
24 |
25 | private:
26 | HiButton * m_exitButton;
27 | bool m_Moveing;
28 | QPoint m_MovePosition;
29 |
30 | };
31 |
32 |
33 | #endif
34 |
--------------------------------------------------------------------------------
/hiButton.cpp:
--------------------------------------------------------------------------------
1 | #include "hiButton.h"
2 |
3 | HiButton::HiButton(QWidget *parent)
4 | : QPushButton(parent)
5 | {
6 | //设置图标无焦点
7 | setFocusPolicy(Qt::NoFocus);
8 | }
9 |
10 | HiButton::~HiButton()
11 | {
12 | }
13 |
14 | void HiButton::enterEvent(QEvent *)
15 | {
16 | if( isEnabled() && !focusIcon.isNull() )
17 | setIcon(focusIcon);
18 | }
19 |
20 | void HiButton::leaveEvent(QEvent *)
21 | {
22 | if( isEnabled() )
23 | setIcon(normalIcon);
24 | }
25 |
26 |
27 | void HiButton::mousePressEvent(QMouseEvent *event)
28 | {
29 | if( isEnabled() && !pressedIcon.isNull() )
30 | setIcon(pressedIcon);
31 | QPushButton::mousePressEvent(event);
32 | }
33 |
34 | void HiButton::mouseReleaseEvent(QMouseEvent *event)
35 | {
36 | if( isEnabled() && !focusIcon.isNull() )
37 | setIcon(focusIcon);
38 | QPushButton::mouseReleaseEvent(event);
39 | }
40 |
41 | void HiButton::hi_setButtonIcons(const QIcon &normal, const QIcon &focus, const QIcon &pressed)
42 | {
43 | normalIcon = normal;
44 | focusIcon = focus;
45 | pressedIcon = pressed;
46 | setIcon(normalIcon);
47 | }
48 |
--------------------------------------------------------------------------------
/hiButton.h:
--------------------------------------------------------------------------------
1 | #ifndef HIBUTTON_H
2 | #define HIBUTTON_H
3 |
4 | //#include
5 | #include
6 | #include
7 |
8 | class HiButton : public QPushButton
9 | {
10 | Q_OBJECT
11 | public:
12 | HiButton(QWidget *parent = 0);
13 | ~HiButton();
14 |
15 | //设置图标
16 | //若只指定一个图标,则默认“进入”,按下,松开都为此图标
17 | void hi_setButtonIcons(const QIcon &normal, const QIcon &focus = QIcon(), const QIcon &pressed = QIcon() );
18 |
19 | protected:
20 | //重载“进入”和“离开”事件,进入时切换为另一个图标,离开时还原
21 | void enterEvent(QEvent *);
22 | void leaveEvent(QEvent *);
23 |
24 | //重载鼠标按下和松开事件 ,切换图标
25 | void mousePressEvent(QMouseEvent *event);
26 | void mouseReleaseEvent(QMouseEvent *event);
27 | private:
28 | QIcon normalIcon;
29 | QIcon focusIcon;
30 | QIcon pressedIcon;
31 |
32 | };
33 |
34 |
35 | #endif//HIBUTTON_H
36 |
--------------------------------------------------------------------------------
/hiLabel.cpp:
--------------------------------------------------------------------------------
1 | #include "hiLabel.h"
2 | #include
3 |
4 | HiLabel::HiLabel(QWidget *parent)
5 | :QLabel(parent)
6 | ,m_context("")
7 | ,m_timer(NULL)
8 | ,m_ms(0)
9 | ,m_pos(0)
10 | {
11 | }
12 |
13 | HiLabel::~HiLabel()
14 | {
15 | hi_stop();
16 | }
17 |
18 | void HiLabel::hi_stop()//label停止滚动,直接从头显示文本
19 | {
20 | if (m_timer)
21 | {
22 | if (m_timer->isActive())
23 | {
24 | m_timer->stop();
25 | }
26 | delete m_timer;
27 | m_timer = NULL;
28 | }
29 | setText(m_context);
30 | }
31 |
32 | void HiLabel::hi_setText(const QString &context,const int &ms)//设置label文本和滚动的时间间隔
33 | {
34 | m_context = context;
35 | m_ms = ms;
36 |
37 | if (m_ms != 0 && m_timer == NULL)
38 | {
39 | m_timer = new QTimer(this);
40 | if (m_timer)
41 | {
42 | connect(m_timer, SIGNAL(timeout()), this, SLOT(slotTimeout()));
43 | m_timer->start(m_ms);
44 | }
45 | //return;
46 | }
47 | setText(m_context);
48 | }
49 |
50 | void HiLabel::slotTimeout()//定时器触发则显示滚动的文字
51 | {
52 |
53 | QString str="";
54 |
55 | if (m_pos > m_context.count())
56 | {
57 | m_pos = 0;
58 | }
59 |
60 | str = m_context.mid(m_pos);
61 |
62 |
63 | setText(str);
64 | //qDebug()<<"str:"<
4 | #include
5 |
6 | //实现带有文字滚动功能的Label
7 | class HiLabel : public QLabel
8 | {
9 | Q_OBJECT
10 | public:
11 | explicit HiLabel(QWidget *parent=0);
12 | ~HiLabel();
13 |
14 | //设置文本:
15 | //如果ms为0则文字不滚动(默认不滚动);若不为0则一定按时间间隔滚动;
16 | //如果调用setText()文字将不滚动(与使用QLabel相同);
17 | void hi_setText(const QString & context=0, const int & ms=0);
18 |
19 | //停止滚动
20 | void hi_stop();
21 |
22 | private slots:
23 |
24 | void slotTimeout();
25 |
26 | private:
27 | QString m_context;
28 | QTimer *m_timer;
29 |
30 | int m_ms;
31 | int m_pos;
32 | };
33 |
34 | #endif//HILABEL_H
35 |
--------------------------------------------------------------------------------
/hiLrcWidget.cpp:
--------------------------------------------------------------------------------
1 | #include "hiLrcWidget.h"
2 |
3 | HiLrcWidget::HiLrcWidget(QWidget *parent)
4 | :QWidget(parent)
5 | {
6 | lrcLabel=nullptr;
7 |
8 | //无边界的窗口,总在最上
9 | setWindowFlags(Qt::Window | Qt::FramelessWindowHint | Qt::Tool | Qt::WindowStaysOnTopHint);
10 | //去除窗体原背景(背景透明)
11 | setAttribute(Qt::WA_TranslucentBackground);
12 |
13 | //固定大小
14 | this->setFixedSize(800, 60);
15 |
16 | lrcLabel =new LrcLabel(this);
17 | lrcLabel->setGeometry(QRect(0, 6, 800, 60));
18 | }
19 |
20 | HiLrcWidget::~HiLrcWidget()
21 | {
22 | if(lrcLabel!=nullptr)
23 | {
24 | delete lrcLabel;
25 | }
26 | }
27 |
28 | //开始歌词遮罩,以intervaltime(ms)为间隔时间
29 | void HiLrcWidget::hi_startLrcMask(qint64 intervaltime)
30 | {
31 | lrcLabel->hi_startLrcMask(intervaltime);
32 | }
33 |
34 | //停止歌词遮罩
35 | void HiLrcWidget::hi_stopLrcMask()
36 | {
37 | lrcLabel->hi_stopLrcMask();
38 | }
39 |
40 | QString HiLrcWidget::text()const
41 | {
42 | return lrcLabel->text();
43 | }
44 |
45 | void HiLrcWidget::hi_setLyricText(QString t)//设置歌词文本(无滚动效果)
46 | {
47 | lrcLabel->setText(t);
48 | }
49 |
50 | void HiLrcWidget::paintEvent(QPaintEvent * event)
51 | {
52 | QPainter p(this);
53 | p.drawPixmap(0, 0, QPixmap(":/hiplayer/resources/lrc_background.png"));
54 | lrcLabel->raise();
55 | QWidget::paintEvent(event);
56 | }
57 |
58 | void HiLrcWidget::enterEvent(QEvent *)
59 | {
60 | setCursor(Qt::PointingHandCursor);
61 | }
62 |
63 | void HiLrcWidget::mousePressEvent(QMouseEvent *event)
64 | {
65 | m_Moveing=true;
66 | //记录下鼠标相对于窗口的位置
67 | //event->globalPos()鼠标按下时,鼠标相对于整个屏幕位置
68 | //pos() this->pos()鼠标按下时,窗口相对于父窗口的位置
69 | m_MovePosition=event->globalPos() - pos();
70 | event->accept();
71 | }
72 |
73 | void HiLrcWidget::mouseMoveEvent(QMouseEvent *event)
74 | {
75 | //(event->buttons() && Qt::LeftButton)按下是左键
76 | //鼠标移动事件需要移动窗口,窗口移动到哪里呢?就是要获取鼠标移动中,窗口在整个屏幕的坐标,然后move到这个坐标,怎么获取坐标?
77 | //通过事件event->globalPos()知道鼠标坐标,鼠标坐标减去鼠标相对于窗口位置,就是窗口在整个屏幕的坐标
78 | if (m_Moveing && (event->buttons() && Qt::LeftButton)
79 | && (event->globalPos()-m_MovePosition).manhattanLength() > QApplication::startDragDistance())
80 | {
81 | move(event->globalPos()-m_MovePosition);//相对于桌面的位置.
82 | m_MovePosition = event->globalPos() - pos();
83 | }
84 | event->accept();
85 | }
86 |
87 | void HiLrcWidget::mouseReleaseEvent(QMouseEvent *)
88 | {
89 | m_Moveing=false;
90 | }
91 |
--------------------------------------------------------------------------------
/hiLrcWidget.h:
--------------------------------------------------------------------------------
1 | #ifndef HILRCWIDGET_H
2 | #define HILRCWIDGET_H
3 | #include
4 | #include "lrcLabel.h"
5 | #include
6 |
7 | class HiLrcWidget:public QWidget
8 | {
9 | public:
10 | HiLrcWidget(QWidget *parent = 0);
11 | ~HiLrcWidget();
12 |
13 | //开始歌词遮罩,以intervaltime为间隔时间
14 | void hi_startLrcMask(qint64 intervaltime);
15 |
16 | //停止歌词遮罩
17 | void hi_stopLrcMask();
18 |
19 | QString text()const;
20 |
21 | //void setText(QString t);
22 |
23 | void hi_setLyricText(QString t);
24 | private:
25 | void enterEvent(QEvent *);
26 | void paintEvent(QPaintEvent * event);
27 | //用于窗口位置拖动
28 | void mousePressEvent(QMouseEvent *event);
29 | void mouseMoveEvent(QMouseEvent *event);
30 | void mouseReleaseEvent(QMouseEvent *event);
31 | private:
32 | LrcLabel * lrcLabel;
33 |
34 | //用于窗口位置拖动
35 | bool m_Moveing;
36 | QPoint m_MovePosition;
37 |
38 | };
39 |
40 | #endif // HILRCWIDGET_H
41 |
--------------------------------------------------------------------------------
/hiVolBotton.cpp:
--------------------------------------------------------------------------------
1 | #include "hiVolBotton.h"
2 | #include
3 |
4 | HiVolBotton::HiVolBotton(QWidget *parent )
5 | :QWidget(parent)
6 | {
7 | volSlider = new QSlider(Qt::Horizontal, this);
8 | volSlider->setRange(0, 100);
9 | volSlider->setGeometry(QRect(26,0,75,25));
10 |
11 | //当音量条被拖动时发射音量改变的信号
12 | connect(volSlider, SIGNAL(valueChanged(int)), this, SIGNAL(hi_volumeChanged(int)));
13 |
14 | volSlider->setStyleSheet("QSlider::groove:horizontal{border:0px;height:4px;}"
15 | "QSlider::sub-page:horizontal{background:#0096ff;}"
16 | "QSlider::add-page:horizontal{background:lightgray;} "
17 | "QSlider::handle:horizontal{background:white;width:10px;border:#51b5fb 10px;border-radius:5px;margin:-3px 0px -3px 0px;}");
18 |
19 | volBtn = new HiButton(this);
20 |
21 | QIcon icon_button, icon_button_focus;
22 | icon_button.addFile(QStringLiteral(":/hiplayer/resources/Volumn_40_40.png"), QSize(), QIcon::Normal, QIcon::Off);
23 | icon_button_focus.addFile(QStringLiteral(":/hiPlayer/resources/音量调节2.png"), QSize(), QIcon::Normal, QIcon::Off);
24 | volBtn->hi_setButtonIcons(icon_button, icon_button);
25 |
26 | volBtn->setIconSize(QSize(25,25));
27 | volBtn->setFlat(true);
28 | volBtn->setFocusPolicy(Qt::NoFocus);
29 | volBtn->setStyleSheet("QPushButton{background-color:rgba(255,255,255,0);border-style:solid;border-width:0px;border-color:rgba(255,255,255,0);}");
30 | volBtn->setGeometry(QRect(0,0,25,25));
31 |
32 | connect(volBtn, SIGNAL(clicked()), this, SLOT(hi_buttonClicked()));
33 |
34 | menu = new QMenu(this);
35 |
36 | action = new QWidgetAction(this);
37 | action->setDefaultWidget(volSlider);
38 | menu->addAction(action);
39 |
40 | }
41 | void HiVolBotton::hi_setSliderVisiable(bool a)
42 | {
43 | volSlider->setVisible(a);
44 | }
45 |
46 | void HiVolBotton::hi_buttonClicked()
47 | {
48 | menu->exec(QCursor::pos());
49 | }
50 |
51 | void HiVolBotton::hi_increaseVolume()
52 | {
53 | volSlider->triggerAction(QSlider::SliderPageStepAdd);
54 | qDebug()<<"hi_increaseVolume";
55 | }
56 |
57 | void HiVolBotton::hi_descVolume()
58 | {
59 | volSlider->triggerAction(QSlider::SliderPageStepSub);
60 | qDebug()<<"hi_descVolume";
61 | }
62 |
63 | int HiVolBotton::hi_getVolume() const
64 | {
65 | return volSlider->value();
66 | }
67 |
68 | void HiVolBotton::hi_setVolume(int volume)
69 | {
70 | volSlider->setValue(volume);
71 | }
72 |
--------------------------------------------------------------------------------
/hiVolBotton.h:
--------------------------------------------------------------------------------
1 | #ifndef HIVOLBOTTON_H
2 | #define HIVOLBOTTON_H
3 |
4 | #include "hiButton.h"
5 | #include
6 |
7 | class HiVolBotton:public QWidget
8 | {
9 | public:
10 | Q_OBJECT
11 | Q_PROPERTY(int hi_getVolume READ hi_getVolume WRITE hi_setVolume NOTIFY hi_volumeChanged)
12 | public:
13 | HiVolBotton(QWidget *parent = 0);
14 |
15 | //返回音量值(0~100)
16 | int hi_getVolume() const;
17 |
18 | //设置音量条是否可见
19 | void hi_setSliderVisiable(bool);
20 |
21 | public slots:
22 |
23 | //点击音量条使音量增加一部分
24 | void hi_increaseVolume();
25 |
26 | //点击音量条使音量减少一部分
27 | void hi_descVolume();
28 |
29 | //设置音量
30 | void hi_setVolume(int volume);
31 |
32 | //按钮单击事件,弹出菜单
33 | void hi_buttonClicked();
34 |
35 | signals:
36 |
37 | //音量改变信号(当音量条被拖动时发射)
38 | void hi_volumeChanged(int volume);
39 |
40 | private:
41 | HiButton * volBtn;
42 | QSlider * volSlider;
43 | QMenu * menu;
44 | QWidgetAction * action;
45 | };
46 |
47 | #endif // HIVOLBOTTON_H
48 |
--------------------------------------------------------------------------------
/hiplayer.cpp:
--------------------------------------------------------------------------------
1 | #include "hiplayer.h"
2 | #include "miniWindow.h"
3 |
4 | HiPlayer::HiPlayer(QWidget *parent)
5 | : QWidget(parent)
6 | {
7 | hi_initUi();
8 | hi_initPlayer();
9 | hi_initConnections();
10 | hi_initWindows();
11 | hi_initMenuActions();
12 | hi_initNetwork();
13 | dirPath = QApplication::applicationDirPath();
14 | slotReadList();
15 | }
16 |
17 | HiPlayer::~HiPlayer()
18 | {}
19 |
20 | void HiPlayer::hi_initUi()//初始化界面
21 | {
22 | picLabel = new QLabel( this);
23 | picLabel->setGeometry(QRect(40, 45, 100, 100));
24 | picLabel->setScaledContents(true);
25 | picLabel->setPixmap(QPixmap(":/hiplayer/resources/album.png"));
26 |
27 | nameLabel = new HiLabel(this);
28 | nameLabel->setGeometry(QRect(150, 55, 220, 20));
29 |
30 | musicianLabel = new QLabel(this);
31 | musicianLabel->setGeometry(QRect(150, 85, 220, 15));
32 |
33 | albumLabel = new QLabel(this);
34 | albumLabel->setGeometry(QRect(150, 115, 220, 15));
35 |
36 | playSlider = new PlaySlider(this);
37 | playSlider->setObjectName(QStringLiteral("playSlider"));
38 | playSlider->setStyleSheet("QSlider::groove:horizontal{border:0px;height:4px;}"
39 | "QSlider::sub-page:horizontal{background:#0096ff;}"
40 | "QSlider::add-page:horizontal{background:lightgray;} "
41 | "QSlider::handle:horizontal{background:white;width:10px;border:#51b5fb 10px;border-radius:5px;margin:-3px 0px -3px 0px;}");
42 | playSlider->setGeometry(QRect(40, 150, 290, 20));
43 | playSlider->setOrientation(Qt::Horizontal);
44 | playSlider->setEnabled(false);
45 |
46 | timeLabel = new QLabel( this);
47 | timeLabel->setObjectName(QStringLiteral("timeLabel"));
48 | timeLabel->setGeometry(QRect(340, 150, 51, 16));
49 |
50 | playlistTable = new QTableWidget( this);
51 | playlistTable->setObjectName(QStringLiteral("playlistTable"));
52 | playlistTable->setGeometry(QRect(25, 240, 350, 320));
53 | playlistTable->setItemDelegate(new NoFocusDelegate());
54 |
55 | addButton = new HiButton( this);
56 | addButton->setObjectName(QStringLiteral("addButton"));
57 | addButton->setGeometry(QRect(40, 190, 31, 31));
58 | modeButton = new HiButton( this);
59 | modeButton->setObjectName(QStringLiteral("modeButton"));
60 | modeButton->setGeometry(QRect(290, 190, 31, 31));
61 | lastButton = new HiButton( this);
62 | lastButton->setObjectName(QStringLiteral("lastButton"));
63 | lastButton->setGeometry(QRect(120, 185, 41, 41));
64 | nextButton = new HiButton( this);
65 | nextButton->setObjectName(QStringLiteral("nextButton"));
66 | nextButton->setGeometry(QRect(240, 185, 41, 41));
67 | lyricButton = new HiButton( this);
68 | lyricButton->setObjectName(QStringLiteral("lyricButton"));
69 | lyricButton->setGeometry(QRect(80, 190, 31, 31));
70 | playButton = new HiButton( this);
71 | playButton->setObjectName(QStringLiteral("playButton"));
72 | playButton->setGeometry(QRect(170, 175, 61, 61));
73 | pauseButton = new HiButton( this);
74 | pauseButton->setObjectName(QStringLiteral("pauseButton"));
75 | pauseButton->setGeometry(QRect(170, 175, 61, 61));
76 | pauseButton->setVisible(false);
77 |
78 | volButton = new HiVolBotton(this);
79 | volButton->setObjectName(QStringLiteral("volButton"));
80 | volButton->setGeometry(QRect(333, 193, 31, 31));
81 | volButton->hi_setVolume(50);
82 |
83 | minButton = new HiButton( this);
84 | minButton->setObjectName(QStringLiteral("minButton"));
85 | minButton->setGeometry(QRect(307, 3, 29, 31));
86 | miniButton = new HiButton( this);
87 | miniButton->setObjectName(QStringLiteral("miniButton"));
88 | miniButton->setGeometry(QRect(337, 3, 29, 31));
89 | exitButton = new HiButton( this);
90 | exitButton->setObjectName(QStringLiteral("exitButton"));
91 | exitButton->setGeometry(QRect(364, 3, 29, 31));
92 | logoButton = new HiButton( this);
93 | logoButton->setObjectName(QStringLiteral("logoButton"));
94 | logoButton->setGeometry(QRect(8, 8, 38, 38));
95 |
96 | logoButton->raise();
97 | picLabel->raise();
98 | playSlider->raise();
99 | timeLabel->raise();
100 | playlistTable->raise();
101 | addButton->raise();
102 | modeButton->raise();
103 | nextButton->raise();
104 | lyricButton->raise();
105 | playButton->raise();
106 | volButton->raise();
107 | minButton->raise();
108 | miniButton->raise();
109 | exitButton->raise();
110 |
111 | timeLabel->setText(tr("00:00"));
112 | nameLabel->setText(tr("Name " ));
113 | musicianLabel->setText(tr("Musician" ));
114 | albumLabel->setText(tr("Album" ));
115 |
116 | //设置图标
117 | QIcon icon_play, icon_play_focus;
118 | icon_play.addFile(QStringLiteral(":/hiplayer/resources/Play_100_100.png"), QSize(), QIcon::Normal, QIcon::Off);
119 | icon_play_focus.addFile(QStringLiteral(":/hiPlayer/resources/播放按钮-主界面2.png"), QSize(), QIcon::Normal, QIcon::Off);
120 | playButton->hi_setButtonIcons(icon_play, icon_play);
121 | playButton->setIconSize(QSize(60,60));
122 | playButton->setFlat(true);
123 | playButton->setFocusPolicy(Qt::NoFocus);
124 | playButton->setStyleSheet("QPushButton{background-color:rgba(255,255,255,0);border-style:solid;border-width:0px;border-color:rgba(255,255,255,0);}");
125 |
126 | QIcon icon_pause, icon_pause_focus;
127 | icon_pause.addFile(QStringLiteral(":/hiplayer/resources/Pause_100_100.png"), QSize(), QIcon::Normal, QIcon::Off);
128 | icon_pause_focus.addFile(QStringLiteral(":/hiPlayer/resources/暂停按钮-主界面2.png"), QSize(), QIcon::Normal, QIcon::Off);
129 | pauseButton->hi_setButtonIcons(icon_pause, icon_pause);
130 | pauseButton->setIconSize(QSize(60,60));
131 | pauseButton->setFlat(true);
132 | pauseButton->setFocusPolicy(Qt::NoFocus);
133 | pauseButton->setStyleSheet("QPushButton{background-color:rgba(255,255,255,0);border-style:solid;border-width:0px;border-color:rgba(255,255,255,0);}");
134 |
135 |
136 | QIcon icon_lyric, icon_lyric_focus;
137 | icon_lyric.addFile(QStringLiteral(":/hiplayer/resources/Lyric_40_40.png"), QSize(), QIcon::Normal, QIcon::Off);
138 | icon_lyric_focus.addFile(QStringLiteral(":/hiPlayer/resources/歌词按钮2.png"), QSize(), QIcon::Normal, QIcon::Off);
139 | lyricButton->hi_setButtonIcons(icon_lyric, icon_lyric);
140 | lyricButton->setIconSize(QSize(25,25));
141 | lyricButton->setFlat(true);
142 | lyricButton->setFocusPolicy(Qt::NoFocus);
143 | lyricButton->setStyleSheet("QPushButton{background-color:rgba(255,255,255,0);border-style:solid;border-width:0px;border-color:rgba(255,255,255,0);}");
144 |
145 | QIcon icon_exit, icon_exit_focus;
146 | icon_exit.addFile(QStringLiteral(":/hiplayer/resources/关闭.png"), QSize(), QIcon::Normal, QIcon::Off);
147 | icon_exit_focus.addFile(QStringLiteral(":/hiPlayer/resources/关闭按钮2.png"), QSize(), QIcon::Normal, QIcon::Off);
148 | exitButton->hi_setButtonIcons(icon_exit, icon_exit);
149 | exitButton->setIconSize(QSize(18,18));
150 | exitButton->setFlat(true);
151 | exitButton->setFocusPolicy(Qt::NoFocus);
152 | exitButton->setStyleSheet("QPushButton{background-color:rgba(255,255,255,0);border-style:solid;border-width:0px;border-color:rgba(255,255,255,0);}");
153 |
154 | QIcon icon_min, icon_min_focus;
155 | icon_min.addFile(QStringLiteral(":/hiplayer/resources/缩小.png"), QSize(), QIcon::Normal, QIcon::Off);
156 | icon_min_focus.addFile(QStringLiteral(":/hiPlayer/resources/迷你模式按钮2.png"), QSize(), QIcon::Normal, QIcon::Off);
157 | miniButton->hi_setButtonIcons(icon_min, icon_min);
158 | miniButton->setIconSize(QSize(18,18));
159 | miniButton->setFlat(true);
160 | miniButton->setFocusPolicy(Qt::NoFocus);
161 | miniButton->setStyleSheet("QPushButton{background-color:rgba(255,255,255,0);border-style:solid;border-width:0px;border-color:rgba(255,255,255,0);}");
162 |
163 | QIcon icon_mmin, icon_mmin_focus;
164 | icon_mmin.addFile(QStringLiteral(":/hiplayer/resources/最小化.png"), QSize(), QIcon::Normal, QIcon::Off);
165 | icon_mmin_focus.addFile(QStringLiteral(":/hiPlayer/resources/缩小按钮2.png"), QSize(), QIcon::Normal, QIcon::Off);
166 | minButton->hi_setButtonIcons(icon_mmin, icon_mmin);
167 | minButton->setIconSize(QSize(18,18));
168 | minButton->setFlat(true);
169 | minButton->setFocusPolicy(Qt::NoFocus);
170 | minButton->setStyleSheet("QPushButton{background-color:rgba(255,255,255,0);border-style:solid;border-width:0px;border-color:rgba(255,255,255,0);}");
171 |
172 | QIcon icon_logo, icon_logo_focus;
173 | icon_logo.addFile(QStringLiteral(":/hiplayer/resources/HiPlayer_38_38.png"), QSize(), QIcon::Normal, QIcon::Off);
174 | icon_logo_focus.addFile(QStringLiteral(":/hiPlayer/resources/左上角logo按钮2.png"), QSize(), QIcon::Normal, QIcon::Off);
175 | logoButton->hi_setButtonIcons(icon_logo, icon_logo);
176 | logoButton->setIconSize(QSize(48, 48));
177 | logoButton->setFlat(true);
178 | logoButton->setFocusPolicy(Qt::NoFocus);
179 | logoButton->setStyleSheet("QPushButton{background-color:rgba(255,255,255,0);border-style:solid;border-width:0px;border-color:rgba(255,255,255,0);}");
180 |
181 | QIcon icon_next, icon_next_focus;
182 | icon_next.addFile(QStringLiteral(":/hiplayer/resources/Next_40_40.png"), QSize(), QIcon::Normal, QIcon::Off);
183 | icon_next_focus.addFile(QStringLiteral(":/hiPlayer/resources/下一曲2.png"), QSize(), QIcon::Normal, QIcon::Off);
184 | nextButton->hi_setButtonIcons(icon_next, icon_next);
185 | nextButton->setIconSize(QSize(40,40));
186 | nextButton->setFlat(true);
187 | nextButton->setFocusPolicy(Qt::NoFocus);
188 | nextButton->setStyleSheet("QPushButton{background-color:rgba(255,255,255,0);border-style:solid;border-width:0px;border-color:rgba(255,255,255,0);}");
189 |
190 | QIcon icon_last, icon_last_focus;
191 | icon_last.addFile(QStringLiteral(":/hiplayer/resources/Last_40_40.png"), QSize(), QIcon::Normal, QIcon::Off);
192 | icon_last_focus.addFile(QStringLiteral(":/hiPlayer/resources/上一曲2.png"), QSize(), QIcon::Normal, QIcon::Off);
193 | lastButton->hi_setButtonIcons(icon_last, icon_last);
194 | lastButton->setIconSize(QSize(40,40));
195 | lastButton->setFlat(true);
196 | lastButton->setFocusPolicy(Qt::NoFocus);
197 | lastButton->setStyleSheet("QPushButton{background-color:rgba(255,255,255,0);border-style:solid;border-width:0px;border-color:rgba(255,255,255,0);}");
198 |
199 | QIcon icon_mode, icon_mode_focus;
200 | icon_mode.addFile(QStringLiteral(":/hiplayer/resources/mode.png"), QSize(), QIcon::Normal, QIcon::Off);
201 | icon_mode_focus.addFile(QStringLiteral(":/hiPlayer/resources/播放模式2.png"), QSize(), QIcon::Normal, QIcon::Off);
202 | modeButton->hi_setButtonIcons(icon_mode, icon_mode);
203 | modeButton->setIconSize(QSize(25,25));
204 | modeButton->setFlat(true);
205 | modeButton->setFocusPolicy(Qt::NoFocus);
206 | modeButton->setStyleSheet("QPushButton{background-color:rgba(255,255,255,0);border-style:solid;border-width:0px;border-color:rgba(255,255,255,0);}");
207 |
208 | QIcon icon_add, icon_add_focus;
209 | icon_add.addFile(QStringLiteral(":/hiplayer/resources/addMusic_40_40.png"), QSize(), QIcon::Normal, QIcon::Off);
210 | icon_add_focus.addFile(QStringLiteral(":/hiPlayer/resources/添加歌曲2.png"), QSize(), QIcon::Normal, QIcon::Off);
211 | addButton->hi_setButtonIcons(icon_add, icon_add);
212 | addButton->setIconSize(QSize(25,25));
213 | addButton->setFlat(true);
214 | addButton->setFocusPolicy(Qt::NoFocus);
215 | addButton->setStyleSheet("QPushButton{background-color:rgba(255,255,255,0);border-style:solid;border-width:0px;border-color:rgba(255,255,255,0);}");
216 |
217 | //去除标题栏
218 | this->setWindowFlags(Qt::FramelessWindowHint);
219 | //半透明
220 | this->setWindowOpacity(1);
221 | setAttribute(Qt::WA_TranslucentBackground);
222 |
223 | //固定大小
224 | this->setFixedSize(400, 600);
225 |
226 | //设置音乐信息字体颜色
227 | QColor fontcolor(1, 149, 255);
228 | QPalette fontPalette;
229 | fontPalette.setColor(QPalette::WindowText, fontcolor);
230 | nameLabel->setPalette(fontPalette);
231 | musicianLabel->setPalette(fontPalette);
232 | albumLabel->setPalette(fontPalette);
233 |
234 | QColor timeColor(106, 182, 240);
235 | QPalette timePalette;
236 | timePalette.setColor(QPalette::WindowText, timeColor);
237 | timeLabel->setPalette(timePalette);
238 |
239 | nameLabel->setFont(QFont(QString::fromUtf8("微软雅黑"), 12));
240 |
241 | QFont othersfont(QString::fromUtf8("微软雅黑"), 9);
242 | musicianLabel->setFont(othersfont);
243 | albumLabel->setFont(othersfont);
244 | timeLabel->setFont(othersfont);
245 |
246 | if (playlistTable->columnCount() < 1)//列数默认为0
247 | playlistTable->setColumnCount(2);
248 |
249 | //设置列宽
250 | playlistTable->setColumnWidth(0,300);
251 | playlistTable->setColumnWidth(1,45);
252 | //禁止编辑单元格内容
253 | playlistTable->setEditTriggers(QAbstractItemView::NoEditTriggers);
254 | //选中一行
255 | playlistTable->setSelectionBehavior(QAbstractItemView::SelectRows);
256 | //去掉水平滚动条
257 | playlistTable->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
258 | //垂直滚动条按项移动
259 | playlistTable->setVerticalScrollMode(QAbstractItemView::ScrollPerItem);
260 | //去除水平表头
261 | playlistTable->horizontalHeader()->setFixedHeight(0);
262 | //去除垂直表头
263 | playlistTable->verticalHeader()->setFixedWidth(0);
264 | //设置无边框
265 | playlistTable->setFrameShape(QFrame::NoFrame);
266 | //设置不显示格子线
267 | playlistTable->setShowGrid(false);
268 | //设置右键菜单
269 | playlistTable->setContextMenuPolicy(Qt::CustomContextMenu);
270 | //设置背景颜色
271 | QPalette pal;
272 | pal.setBrush(QPalette::Base, QBrush(QColor(255, 255, 255)));
273 | playlistTable->setPalette(pal);
274 | //设置竖直滚动条样式
275 | playlistTable->setStyleSheet("QScrollBar{background:transparent; width: 5px;}"
276 | "QScrollBar::handle{background:lightgray; border:2px solid transparent; border-radius:5px;}"
277 | "QScrollBar::handle:hover{background:gray;}"
278 | "QScrollBar::sub-line{background:transparent;}"
279 | "QScrollBar::add-line{background:transparent;}");
280 | //使拖动操作生效
281 | playlistTable->setAcceptDrops(true);
282 | setAcceptDrops(true);
283 | }
284 |
285 | void HiPlayer::hi_initPlayer()//初始化播放器,设置播放模式为单曲播放
286 | {
287 | mediaPlayer = new QMediaPlayer(this);
288 | mediaList = new QMediaPlaylist(this);
289 | mediaPlayer->setPlaylist(mediaList);
290 |
291 | playMode = Play_Mode::SINGAL;
292 | //preIndex = -1;
293 | currentIndex = 0;
294 |
295 | mediaList->setPlaybackMode(QMediaPlaylist::CurrentItemOnce);
296 | }
297 |
298 | void HiPlayer::hi_initConnections()
299 | {
300 | connect(mediaPlayer, SIGNAL(positionChanged(qint64)), this, SLOT(slotUpdatePosition(qint64)));
301 | connect(mediaPlayer, SIGNAL(durationChanged(qint64)), this, SLOT(slotUpdateProcessbar(qint64)));
302 | connect(mediaPlayer, SIGNAL(stateChanged(QMediaPlayer::State)),this, SLOT(slotUpdateState(QMediaPlayer::State)));
303 | connect(mediaPlayer, SIGNAL(metaDataChanged()), this, SLOT(slotUpdateMetaData()));
304 | connect(playSlider, SIGNAL(sliderMoved(int)), this, SLOT(slotSetPlayPosition(int)));
305 | connect(playSlider, SIGNAL(sliderReleased()), this, SLOT(slotSetPosition()));
306 | //connect(playSlider,SIGNAL(valueChanged(int)),this,SLOT(slotPlayValueChanged(int)));
307 | connect(volButton, SIGNAL(hi_volumeChanged(int)), mediaPlayer, SLOT(setVolume(int)));
308 |
309 | connect(playlistTable, SIGNAL(cellDoubleClicked(int, int)), this, SLOT(slotPlaylistDoubleClicked(int, int)));
310 | connect(playlistTable, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(slotPlaylistMenuRequested(const QPoint &)));
311 |
312 | connect(addButton, SIGNAL(clicked()), this, SLOT(slotOpenMusic()));
313 | connect(exitButton, SIGNAL(clicked()), this, SLOT(close()));
314 | connect(playButton, SIGNAL(clicked()), this, SLOT(slotPlayButtonClicked()));
315 | connect(lyricButton, SIGNAL(clicked()), this, SLOT(slotLyricButtonClicked()));
316 | connect(logoButton, SIGNAL(clicked()), this, SLOT(slotLogoButtonClicked()));
317 | connect(modeButton, SIGNAL(clicked()), this, SLOT(slotModeButtonClicked()));
318 | connect(nextButton, SIGNAL(clicked()), this, SLOT(slotNextButtonClicked()));
319 | connect(lastButton, SIGNAL(clicked()), this, SLOT(slotLastButtonClicked()));
320 | connect(pauseButton, SIGNAL(clicked()), this, SLOT(slotPauseButtonClicked()));
321 | connect(miniButton, SIGNAL(clicked()), this, SLOT(slotMinButtonClicked()));
322 | connect(minButton, SIGNAL(clicked()), this, SLOT(showMinimized()));
323 |
324 | connect(playSlider,SIGNAL(sigValueClicked(int)),this,SLOT(slotSliderValueClicked(int)));
325 | }
326 |
327 |
328 | void HiPlayer::hi_initWindows()
329 | {
330 | aboutForm = new AboutDialog();
331 | aboutForm->hide();
332 | lrcWidget = new HiLrcWidget(this);
333 |
334 | miniForm = new MiniWindow(this);
335 | miniForm->hide();
336 | }
337 |
338 | void HiPlayer::hi_initMenuActions()
339 | {
340 | modeSingal = new QAction(QString::fromUtf8("单曲播放"), this);
341 | modeListCircle = new QAction(QString::fromUtf8("列表循环"), this);
342 | modeSingalCircle = new QAction(QString::fromUtf8("单曲循环"), this);
343 | modeRandom = new QAction(QString::fromUtf8("随机播放"), this);
344 |
345 | connect(modeSingal, SIGNAL(triggered()), this, SLOT(slotSetPlayMode()));
346 | connect(modeListCircle, SIGNAL(triggered()), this, SLOT(slotSetPlayMode()));
347 | connect(modeSingalCircle, SIGNAL(triggered()), this, SLOT(slotSetPlayMode()));
348 | connect(modeRandom, SIGNAL(triggered()), this, SLOT(slotSetPlayMode()));
349 |
350 | modeActionGroup = new QActionGroup(this);
351 | modeActionGroup->addAction(modeSingal);
352 | modeActionGroup->addAction(modeListCircle);
353 | modeActionGroup->addAction(modeSingalCircle);
354 | modeActionGroup->addAction(modeRandom);
355 |
356 |
357 | modeSingal->setCheckable(true);
358 | modeListCircle->setCheckable(true);
359 | modeSingalCircle->setCheckable(true);
360 | modeRandom->setCheckable(true);
361 | modeSingal->setChecked(true);
362 |
363 | playModeMenu = new QMenu(modeButton);
364 | playModeMenu->setStyleSheet(
365 | "QMenu{padding:5px;background:white;border:1px solid gray;}"
366 | "QMenu::item{padding:0px 40px 0px 30px;height:25px;}"
367 | "QMenu::item:selected:enabled{background:#0096ff;color:white;}"
368 | "QMenu::item:selected:!enabled{background:transparent;}"
369 | "QMenu::separator{height:1px;background:lightgray;margin:5px 0px 5px 0px;}");
370 | playModeMenu->addActions(modeActionGroup->actions());
371 |
372 |
373 | contextMenuLess = new QMenu(playlistTable);
374 | contextMenuMore = new QMenu(playlistTable);
375 | addMusic = new QAction(QString::fromUtf8("添加歌曲"),this);
376 | addFileDiv = new QAction(QString::fromUtf8("添加目录"),this);
377 | removeCurr = new QAction(QString::fromUtf8("移除本曲"),this);
378 | removeAll = new QAction(QString::fromUtf8("移除所有"),this);
379 |
380 | connect(addMusic, SIGNAL(triggered()), this, SLOT(slotOpenMusic()));
381 | connect(addFileDiv, SIGNAL(triggered()), this, SLOT(slotOpenDir()));
382 | connect(removeCurr, SIGNAL(triggered()), this, SLOT(slotRemoveCurrentMusic()));
383 | connect(removeAll, SIGNAL(triggered()), this, SLOT(slotClearList()));
384 |
385 | contextMenuLess->addAction(addMusic);
386 | contextMenuLess->addAction(addFileDiv);
387 | contextMenuLess->addSeparator();
388 | contextMenuLess->addAction(removeAll);
389 |
390 | contextMenuMore->addAction(addMusic);
391 | contextMenuMore->addAction(addFileDiv);
392 | contextMenuMore->addSeparator();
393 | contextMenuMore->addAction(removeCurr);
394 | contextMenuMore->addAction(removeAll);
395 |
396 | contextMenuLess->setStyleSheet(
397 | "QMenu{padding:5px;background:white;border:1px solid gray;}"
398 | "QMenu::item{padding:0px 40px 0px 30px;height:25px;}"
399 | "QMenu::item:selected:enabled{background:#0096ff;color:white;}"
400 | "QMenu::item:selected:!enabled{background:transparent;}"
401 | "QMenu::separator{height:1px;background:lightgray;margin:5px 0px 5px 0px;}");
402 |
403 | contextMenuMore->setStyleSheet(
404 | "QMenu{padding:5px;background:white;border:1px solid gray;}"
405 | "QMenu::item{padding:0px 40px 0px 30px;height:25px;}"
406 | "QMenu::item:selected:enabled{background:#0096ff;color:white;}"
407 | "QMenu::item:selected:!enabled{background:transparent;}"
408 | "QMenu::separator{height:1px;background:lightgray;margin:5px 0px 5px 0px;}");
409 |
410 | }
411 |
412 | void HiPlayer::dropEvent(QDropEvent *event)
413 | {
414 | QList urls = event->mimeData()->urls();
415 | if(urls.isEmpty())
416 | return;
417 |
418 | QStringList dropfilename;
419 | foreach(QUrl u, urls){
420 | if (u.toString().right(4) == QString(".mp3")){
421 | dropfilename.append(u.toLocalFile());
422 | }
423 | }
424 |
425 | if(!dropfilename.isEmpty()){
426 | hi_addList(dropfilename);
427 | }
428 | qDebug()<<"HiPlayer::dropEvent";
429 | }
430 |
431 | void HiPlayer::dragEnterEvent(QDragEnterEvent *event)
432 | {
433 | if(event->mimeData()->hasFormat("text/uri-list"))
434 | event->acceptProposedAction();
435 | }
436 |
437 | void HiPlayer::paintEvent(QPaintEvent * event)
438 | {
439 | QPainter p(this);
440 | p.drawPixmap(0, 0 , QPixmap(":/hiplayer/resources/background.png"));
441 | logoButton->raise();
442 | picLabel->raise();
443 | playSlider->raise();
444 | timeLabel->raise();
445 | playlistTable->raise();
446 | addButton->raise();
447 | modeButton->raise();
448 | nextButton->raise();
449 | lyricButton->raise();
450 | playButton->raise();
451 | volButton->raise();
452 | minButton->raise();
453 | miniButton->raise();
454 | exitButton->raise();
455 | QWidget::paintEvent(event);
456 | }
457 |
458 | void HiPlayer::slotPlaylistDoubleClicked(int row, int )//双击本地歌单列表
459 | {
460 | QFile file(playList.at(row));
461 | if (!file.open(QIODevice::ReadOnly))
462 | {
463 | playlistTable->item(row,1)->setText(QString::fromUtf8("失效"));
464 | return;
465 | }
466 | file.close();
467 | mediaList->setCurrentIndex(row);
468 | mediaPlayer->play();
469 | playlistTable->item(row, 1)->setText(QString::fromUtf8(""));
470 | }
471 |
472 | void HiPlayer::slotRemoveCurrentMusic()//清除当前列表中的音乐后更新本地用于记录列表的数据文件
473 | {
474 | playList.removeAt(currentIndex);
475 | playlistTable->removeRow(currentIndex);
476 | mediaList->removeMedia(currentIndex);
477 | hi_setTableColor();
478 | slotWriteList();
479 | }
480 |
481 | void HiPlayer::slotOpenMusic()//打开音乐菜单
482 | {
483 | QStringList fileList = QFileDialog::getOpenFileNames(this,QString::fromUtf8("添加音乐"),QString(),QString("MP3 (*.mp3)"));
484 | hi_addList(fileList);
485 | }
486 |
487 | void HiPlayer::slotOpenDir()//打开目录菜单
488 | {
489 | QString dirPath = QFileDialog::getExistingDirectory(this,QString::fromUtf8("选择目录"));
490 | if(dirPath.size() == 0)
491 | return;
492 | //if(QFileDialog::Reject) return;
493 | QDir dir(dirPath);
494 | QStringList fileList = dir.entryList(QStringList()<<"*.mp3",QDir::Files);
495 | for(int i = 0;i < fileList.size();i ++)
496 | fileList[i] = dir.absoluteFilePath(fileList.at(i));
497 | hi_addList(fileList);
498 | }
499 |
500 | void HiPlayer::slotClearList()//清除歌曲列表
501 | {
502 | mediaPlayer->stop();
503 | playList.clear();
504 | mediaList->clear();
505 | while(playlistTable->rowCount())
506 | playlistTable->removeRow(0);
507 |
508 | //清除记录歌曲列表的文件
509 | QFile file(dirPath + "/HiPlayerList.list");
510 | if (file.exists())
511 | {
512 | file.remove();
513 | }
514 |
515 | timeLabel->setText(tr("00:00"));
516 | nameLabel->setText(tr("Name " ));
517 | nameLabel->hi_stop();
518 | musicianLabel->setText(tr("Musician" ));
519 | albumLabel->setText(tr("Album" ));
520 | }
521 |
522 | void HiPlayer::hi_addList(QStringList list)//将文件列表list添加到界面列表上,并更新数据文件
523 | {
524 | foreach(QString fileName,list)
525 | {
526 | if(playList.contains(fileName))//默认大小写敏感
527 | continue;
528 | playList.append(fileName);
529 |
530 | mediaList->addMedia(QUrl::fromLocalFile(fileName));
531 | playlistTable->insertRow(playlistTable->rowCount());//playlistTable行号包括0
532 |
533 | for(int i = 0;i < playlistTable->columnCount();i++){
534 | QTableWidgetItem *item = new QTableWidgetItem;
535 | item->setFont(QFont(QString::fromUtf8("微软雅黑"), 10));
536 |
537 | playlistTable->setItem(playlistTable->rowCount() - 1,i,item);
538 | }
539 | playlistTable->item(playlistTable->rowCount() - 1,0)->setText(QFileInfo(fileName).baseName());
540 | }
541 | hi_setTableColor();
542 | slotWriteList();
543 | }
544 |
545 | void HiPlayer::slotPlaylistMenuRequested(const QPoint &pos)//请求右键菜单
546 | {
547 | if(playlistTable->itemAt(pos))
548 | {
549 | currentIndex = playlistTable->rowAt(pos.y());
550 | contextMenuMore->exec(QCursor::pos());
551 | }
552 | else contextMenuLess->exec(QCursor::pos());
553 | }
554 |
555 | void HiPlayer::slotSetPosition()//更新播放进度
556 | {
557 | int pos = slotGetPlayPosition();
558 | mediaPlayer->setPosition(pos);
559 | mediaPlayer->play();
560 | playButton->setVisible(false);
561 | pauseButton->setVisible(true);
562 |
563 | }
564 |
565 | void HiPlayer::slotUpdatePosition(qint64 position)//更新歌词、时间显示
566 | {
567 | if (!playSlider->isSliderDown()){//判断slider未被按下.
568 | playSlider->setValue(position);
569 | }
570 |
571 | //获取该音频文件的总时长参数,单位为毫秒
572 | qint64 total_time_value = mediaPlayer->duration();
573 |
574 | //传进来的time参数代表了当前的时间
575 | //这3个参数分别代表了时,分,秒;60000毫秒为1分钟,所以分钟第二个参数是先除6000,第3个参数是直接除1s
576 | QTime current_time(0, (position/60000)%60, (position/1000)%60);
577 | timeLabel->setText(current_time.toString(tr("mm:ss")));
578 |
579 | // 获取当期时间对应的歌词
580 | if(!lrcMap.isEmpty()) //QMap lrcMap;
581 | {
582 | // 获取当前时间在歌词中的前后两个时间点
583 | qint64 previous = 0;
584 | qint64 later = 0;
585 |
586 | //keys()方法返回lrcMap的keys列表
587 | foreach (qint64 value1, lrcMap.keys()) {//QMap lrcMap;
588 | if (position >= value1) {
589 | previous = value1;
590 | } else {
591 | later = value1;
592 | break;//获取该位置所在的歌词的前后时间点.
593 | }
594 | }
595 |
596 | // 到达最后一行,将later设置为歌曲总时间的值
597 | if (later == 0)
598 | later = total_time_value;
599 |
600 | // 获取当前时间所对应的歌词内容
601 | QString current_lrc = lrcMap.value(previous);
602 |
603 | // 如果是新的一行歌词,那么重新开始显示歌词遮罩
604 | QString tmp = lrcWidget->text();
605 | if(current_lrc != tmp)
606 | {
607 | lrcWidget->hi_setLyricText(current_lrc);
608 | tmp = lrcWidget->text();
609 | qint64 interval_time = later - previous;
610 | lrcWidget->hi_startLrcMask(interval_time);
611 | }
612 | }
613 | }
614 |
615 | void HiPlayer::slotUpdateProcessbar(qint64 duration)//更新进度条长度等信息
616 | {
617 | playSlider->setRange(0, duration);
618 | playSlider->setEnabled(duration > 0);
619 | playSlider->setPageStep(duration / 10);
620 | }
621 |
622 | void HiPlayer::slotUpdateMetaData()//更新显示在界面上的正在播放音乐的信息
623 | {
624 | currentIndex = mediaList->currentIndex();//正常情况下,返回值从0开始
625 | songName.clear();
626 | songArtist.clear();
627 | lrcMap.clear();
628 | picLabel->setPixmap(QPixmap(":/hiplayer/resources/album.png"));
629 |
630 | if(currentIndex<0)//单曲播放模式下,歌曲播放结束之后mediaList->currentIndex()返回-1
631 | {
632 |
633 | timeLabel->setText(tr("00:00"));
634 | nameLabel->setText(tr("Name " ));
635 | nameLabel->hi_stop();
636 | musicianLabel->setText(tr("Musician" ));
637 | albumLabel->setText(tr("Album" ));
638 | return;
639 | }
640 | playingFile = playList.at(currentIndex);
641 | songName = mediaPlayer->metaData(QMediaMetaData::Title).toString();//通过歌曲文件获取歌名
642 | if (songName.size() > 28)
643 | nameLabel->hi_setText(songName, TEXT_SPEED);//label中的文字滚动出现
644 | else{
645 | nameLabel->hi_stop();
646 | nameLabel->setText(songName);
647 | }
648 |
649 | songArtist = mediaPlayer->metaData(QMediaMetaData::Author).toString();
650 | musicianLabel->setText(songArtist);
651 | albumLabel->setText(mediaPlayer->metaData(QMediaMetaData::AlbumTitle).toString());
652 |
653 | lrcWidget->hi_setLyricText(songName);
654 |
655 | if (!songName.isEmpty())
656 | {//若歌曲名不为空,则搜索图片和歌词
657 | bool pic = hi_getPicFromFile();
658 | bool lrc = slotResolveLrc(playingFile);
659 | if (!(pic && lrc))
660 | {//本地均没有找到专辑图片和歌词
661 | receiveState = RECEIVE_INFO;
662 | hi_fetchNetData();//获取网络数据
663 | }
664 | }
665 |
666 | if(nameLabel->text() == "")
667 | nameLabel->setText(QString::fromUtf8("未知歌曲"));
668 | if(musicianLabel->text() == "")
669 | musicianLabel->setText(QString::fromUtf8("未知音乐家"));
670 | if(albumLabel->text() == "")
671 | albumLabel->setText(QString::fromUtf8("未知专辑"));
672 | }
673 |
674 | void HiPlayer::slotUpdateState(QMediaPlayer::State state)//更新播放状态
675 | {
676 | if (state == QMediaPlayer::PlayingState) {
677 | playSlider->setEnabled(true);
678 | playButton->setVisible(false);
679 | pauseButton->setVisible(true);
680 | } else {
681 | playButton->setVisible(true);
682 | pauseButton->setVisible(false);
683 | }
684 | if (state != QMediaPlayer::StoppedState){
685 | playingFile = playList.at(mediaList->currentIndex());
686 | slotResolveLrc(playingFile);
687 | }
688 | else
689 | {
690 | playSlider->setEnabled(false);
691 | }
692 | }
693 |
694 | void HiPlayer::slotSliderValueClicked(int value)//单击播放进度条触发
695 | {
696 | slotSetPlayPosition(value);
697 | slotSetPosition();
698 | }
699 |
700 | void HiPlayer::slotPlayButtonClicked()//单击播放按键触发
701 | {
702 | if(mediaPlayer->state() == QMediaPlayer::PausedState)
703 | {
704 | mediaPlayer->play();
705 | }
706 | }
707 |
708 | void HiPlayer::slotPauseButtonClicked()//单击暂停按键触发
709 | {
710 |
711 | if(mediaPlayer->state() == QMediaPlayer::PlayingState){
712 | mediaPlayer->pause();
713 | }
714 | }
715 |
716 | void HiPlayer::slotNextButtonClicked()//点击播放下一首按钮触发
717 | {
718 | mediaList->setPlaybackMode(QMediaPlaylist::Loop);
719 |
720 | mediaList->setCurrentIndex(mediaList->nextIndex());
721 | if (!mediaPlayer->isAudioAvailable()){
722 | playlistTable->item(mediaList->currentIndex(), 1)->setText(QString::fromUtf8("失效"));
723 | }
724 | mediaPlayer->play();
725 | playlistTable->item(mediaList->currentIndex(), 1)->setText(QString::fromUtf8(""));
726 | slotSetPlayMode();//恢复原有的播放模式
727 | }
728 |
729 | void HiPlayer::slotLastButtonClicked()//单击播放上一首按钮触发
730 | {
731 | mediaList->setPlaybackMode(QMediaPlaylist::Loop);
732 |
733 | mediaList->setCurrentIndex(mediaList->previousIndex());
734 | if (!mediaPlayer->isAudioAvailable()){
735 | playlistTable->item(mediaList->currentIndex(), 1)->setText(QString::fromUtf8("失效"));
736 | }
737 |
738 | mediaPlayer->play();
739 | playlistTable->item(mediaList->currentIndex(), 1)->setText(QString::fromUtf8(""));
740 | slotSetPlayMode();//恢复原有的播放模式
741 | }
742 |
743 | void HiPlayer::slotLyricButtonClicked()//单击歌词按键触发
744 | {
745 | if(lrcWidget->isHidden())
746 | {
747 | lrcWidget->show();
748 | QDesktopWidget* desktopWidget = QApplication::desktop();
749 |
750 | //获取设备屏幕大小
751 | QRect screenRect = desktopWidget->screenGeometry();
752 |
753 | int height=screenRect.height();
754 | int width=screenRect.width();
755 |
756 | int formheight=lrcWidget->height();
757 | int formwidth=lrcWidget->width();
758 | int newformx=width/2-formwidth/2;
759 | int newformy=height-formheight*2;
760 | lrcWidget->move(newformx,newformy);
761 |
762 | }
763 |
764 | else lrcWidget->hide();
765 | }
766 |
767 | void HiPlayer::slotLogoButtonClicked()//单击左上角logo触发
768 | {
769 | aboutForm->show();
770 | }
771 |
772 | void HiPlayer::slotModeButtonClicked()//单击播放模式按键触发
773 | {
774 | playModeMenu->exec(QCursor::pos());
775 | }
776 |
777 | void HiPlayer::slotMinButtonClicked()//单击缩小按键触发
778 | {
779 | miniForm->show();
780 | miniForm->hi_initPlayMode(volButton->hi_getVolume());
781 | this->hide();
782 | }
783 |
784 | void HiPlayer::slotSetPlayMode()//设置播放模式
785 | {
786 | if(modeSingal->isChecked()) {
787 | playMode = Play_Mode::SINGAL;
788 | mediaList->setPlaybackMode(QMediaPlaylist::CurrentItemOnce);
789 | }
790 | else if(modeListCircle->isChecked()) {
791 | playMode = Play_Mode::LISTCIRCLE;
792 | mediaList->setPlaybackMode(QMediaPlaylist::Loop);
793 | }
794 | else if(modeSingalCircle->isChecked()) {
795 | playMode = Play_Mode::SINGALCIRCLE;
796 | mediaList->setPlaybackMode(QMediaPlaylist::CurrentItemInLoop);
797 | }
798 | else if(modeRandom->isChecked()) {
799 | playMode = Play_Mode::RANDOM;
800 | mediaList->setPlaybackMode(QMediaPlaylist::Random);
801 | }
802 | }
803 |
804 | void HiPlayer::slotSetModeFromMini(int m)//从Mini窗口获取播放模式
805 | {
806 | switch(m){
807 | case 0:
808 | playMode = Play_Mode::SINGAL;
809 | mediaList->setPlaybackMode(QMediaPlaylist::CurrentItemOnce);
810 | modeSingal->setChecked(true);
811 | break;
812 | case 1:
813 | playMode = Play_Mode::LISTCIRCLE;
814 | mediaList->setPlaybackMode(QMediaPlaylist::Loop);
815 | modeListCircle->setChecked(true);
816 | break;
817 | case 2:
818 | playMode = Play_Mode::SINGALCIRCLE;
819 | mediaList->setPlaybackMode(QMediaPlaylist::CurrentItemInLoop);
820 | modeSingalCircle->setChecked(true);
821 | break;
822 | case 3:
823 | playMode = Play_Mode::RANDOM;
824 | mediaList->setPlaybackMode(QMediaPlaylist::Random);
825 | modeRandom->setChecked(true);
826 | break;
827 |
828 | }
829 | }
830 |
831 |
832 | void HiPlayer::slotSetVolFromMini(int a)//从Mini窗口获取音量
833 | {
834 | volButton->hi_setVolume(a);
835 | }
836 |
837 | bool HiPlayer::slotResolveLrc(const QString & source_file_name)//根据歌曲文件名解析本地lrc歌词
838 | {
839 | lrcMap.clear();
840 | if(source_file_name.isEmpty())
841 | return false;
842 | QString file_name = source_file_name;
843 | QString lrc_file_name = file_name.remove(file_name.right(3)) + "lrc";//把音频文件的后缀改成lrc后缀
844 |
845 | // 打开歌词文件
846 | QFile file(lrc_file_name);
847 | if(!file.open(QIODevice::ReadOnly))
848 | return false;
849 |
850 | QByteArray temp = file.readAll();
851 | QByteArray temp_text;
852 | for (int i = 0; i < temp.size(); i++)
853 | {
854 | if (temp.at(i) != 0)
855 | temp_text.append(temp.at(i));//去掉temp中的空格
856 | }
857 |
858 | QString all_text = QString::fromUtf8(temp_text);
859 |
860 | file.close();
861 | // 将歌词按行分解为歌词列表
862 | QStringList lines = all_text.split("\n");
863 |
864 | //这个是时间标签的格式[00:05.54]----[mm:ss.ff](分钟数:秒数.百分之一秒数 )
865 | //正则表达式\d{2}表示匹配2个数字
866 | QRegExp rx("\\[\\d{2}:\\d{2}\\.\\d{2}\\]");//实际的正则表达式为\[\d{2}:\d{2}\.\d{2}\]
867 | foreach(QString oneline, lines)//对歌词内容逐行操作
868 | {
869 | QString text = oneline;
870 | text.replace(rx, "");//用空字符串替换正则表达式中所匹配的地方,这样就获得了歌词文本
871 | // 然后依次获取当前行中的所有时间标签,并分别与歌词文本存入QMap中
872 | //indexIn()为返回第一个匹配的位置,如果返回为-1,则表示没有匹配成功
873 | //正常情况下pos后面应该对应的是歌词文件
874 | int pos = rx.indexIn(oneline, 0);
875 | //qDebug()<<"POS="<hi_setLyricText(mediaPlayer->metaData(QMediaMetaData::Title).toString());
902 | return false;
903 | }
904 |
905 | return true;
906 | }
907 |
908 | //在文件不存在的情况下,
909 | //WriteOnly模式打开文件会创建新的空白文件
910 | //ReadOnly模式打开文件则不会创建新的空白文件,会打开失败.
911 |
912 | void HiPlayer::slotReadList()//读取本地保存的记录歌曲列表的文件
913 | {
914 | QFile text(dirPath + "/HiPlayerList.list");
915 | QStringList inList;
916 |
917 | if(text.open(QIODevice::ReadOnly)){
918 | QDataStream in(&text);
919 | in.setVersion(QDataStream::Qt_5_8);
920 | in >> inList;
921 | hi_addList(inList);
922 | text.close();
923 | }else
924 | {
925 | qDebug()<<"list file open error:"<setCurrentIndex(playList.indexOf(filePath));
956 | mediaPlayer->play();
957 | }
958 | }
959 |
960 | void HiPlayer::hi_setTableColor()//设置列表颜色交替
961 | {
962 | for (int i = 0; i < playlistTable->rowCount(); i++)
963 | {
964 |
965 | if (i % 2 == 0){
966 | for (int j = 0; j < playlistTable->columnCount(); j++){
967 | QTableWidgetItem *item = playlistTable->item(i, j);
968 | if (item){
969 | const QColor color = QColor(255, 255, 255);
970 | item->setBackgroundColor(color);//设置深色背景
971 | }
972 | }
973 | }
974 | else{
975 | for (int j = 0; j < playlistTable->columnCount(); j++)
976 | {
977 | QTableWidgetItem *item = playlistTable->item(i, j);
978 | if (item){
979 | const QColor color = QColor(213, 228, 242);
980 | item->setBackgroundColor(color);//设置白色背景
981 | }
982 | }
983 | }
984 | }
985 | }
986 |
987 | void HiPlayer::hi_initNetwork()//初始化网络模块
988 | {
989 | networker = NetWorker::getInstance();
990 | receiveState = RECEIVE_INFO;
991 | /* lambda表达式
992 | 1.[var]表示值传递方式捕捉变量var;
993 | 2.[=]表示值传递方式捕捉所有父作用域的变量(包括this);
994 | 3.[&var]表示引用传递捕捉变量var;
995 | 4.[&]表示引用传递方式捕捉所有父作用域的变量(包括this);
996 | 5.[this]表示值传递方式捕捉当前的this指针。
997 | */
998 | connect(networker, &NetWorker::finished, [&](QNetworkReply *reply) {
999 | switch (receiveState){
1000 | case RECEIVE_INFO:
1001 | hi_recvInfo(reply);
1002 | hi_fetchNetData();
1003 | break;
1004 | case RECEIVE_LINK:
1005 | hi_recvLink(reply);
1006 | hi_fetchNetData();
1007 | break;
1008 | case RECEIVE_PIC:
1009 | hi_recvPic(reply);
1010 | hi_fetchNetData();
1011 | break;
1012 | case RECEIVE_LRC:
1013 | hi_recvLrc(reply);
1014 | receiveState = RECEIVE_INFO;
1015 | break;
1016 | default:
1017 | break;
1018 | }
1019 | reply->abort();
1020 | });
1021 | }
1022 |
1023 | void HiPlayer::hi_fetchNetData() //根据不同的标志获取不同的网络数据
1024 | {
1025 | qDebug()<<"hi_fetchNetData()";
1026 | QString query = QUrl::toPercentEncoding(songName + " " + songArtist);
1027 | switch (receiveState)
1028 | {
1029 | case RECEIVE_INFO:
1030 | networker->get(
1031 | QString("http://tingapi.ting.baidu.com/v1/restserver/ting?format=json&calback=&from=webapp_music&method=baidu.ting.search.catalogSug&query=" +
1032 | query ));
1033 | break;
1034 | case RECEIVE_LINK:
1035 | //networker->get(QString("http://ting.baidu.com/data/music/links?songIds=" + songId));
1036 | networker->get(QString("http://music.baidu.com/data/music/links?songIds=" +
1037 | songId));
1038 | break;
1039 | case RECEIVE_PIC:
1040 | networker->get(picUrl);
1041 | break;
1042 | case RECEIVE_LRC:
1043 | qDebug()<<"lrcUrl:"<get(lrcUrl);
1045 | break;
1046 | default:
1047 | break;
1048 | }
1049 | }
1050 |
1051 | void HiPlayer::hi_recvInfo(QNetworkReply *reply)//接收歌曲信息,主要是获取歌曲id
1052 | {
1053 | QJsonParseError Jsonerror;
1054 | QJsonDocument jsonDocument = QJsonDocument::fromJson(reply->readAll(), &Jsonerror);
1055 | if (Jsonerror.error == QJsonParseError::NoError)
1056 | {
1057 | if (!(jsonDocument.isNull() || jsonDocument.isEmpty()) && jsonDocument.isObject())
1058 | {
1059 | //QVariantMap----QMap
1060 | QVariantMap data = jsonDocument.toVariant().toMap();
1061 | SongInfo song;
1062 | song.set_order(data[QLatin1String("order")].toString());
1063 | song.set_error_code(data[QLatin1String("error_code")].toString());
1064 |
1065 | //QVariantList----QList
1066 | QVariantList result_list = data[QLatin1String("song")].toList();
1067 | QVariantList album_list = data[QLatin1String("album")].toList();
1068 |
1069 | if (result_list.size() == 0){
1070 | qDebug()<<"未找到搜索结果";
1071 | return;
1072 | }
1073 |
1074 | QList results;
1075 | foreach(QVariant s, result_list){
1076 | QVariantMap sm = s.toMap();
1077 | SongResult *result = new SongResult;
1078 | result->set_songid(sm[QLatin1String("songid")].toString());
1079 | result->set_songname(sm[QLatin1String("songname")].toString());
1080 | result->set_has_mv(sm[QLatin1String("has_mv")].toInt());
1081 | result->set_yyr_artist(sm[QLatin1String("yyr_artist")].toInt());
1082 | result->set_artistname(sm[QLatin1String("artistname")].toString());
1083 | results.append(result);
1084 | }
1085 | song.set_song_results(results);
1086 |
1087 | QList album_infos;
1088 | foreach(QVariant a, album_list)
1089 | {
1090 | QVariantMap ai = a.toMap();
1091 | AlbumInfo *info = new AlbumInfo;
1092 | info->set_albumid(ai[QLatin1String("albumid")].toString());
1093 | info->set_albumname(ai[QLatin1String("albumname")].toString());
1094 | info->set_artistname(ai[QLatin1String("artistname")].toString());
1095 | info->set_artistpic(ai[QLatin1String("artistpic")].toString());
1096 | album_infos.append(info);
1097 | }
1098 | song.set_album_infos(album_infos);
1099 |
1100 | if (results.count() > 0){
1101 | SongResult *temp = new SongResult;
1102 | temp = results[0];
1103 |
1104 | songId = temp->get_songid();
1105 | qDebug()<<"founded songId:"<deleteLater();
1111 | }
1112 |
1113 | void HiPlayer::hi_recvLink(QNetworkReply *reply)//接收歌词地址
1114 | {
1115 | QJsonParseError error;
1116 | QJsonDocument jsonDocument = QJsonDocument::fromJson(reply->readAll(), &error);
1117 | if (error.error == QJsonParseError::NoError)
1118 | {
1119 | if (!(jsonDocument.isNull() || jsonDocument.isEmpty()) && jsonDocument.isObject()) {
1120 | QVariantMap data = jsonDocument.toVariant().toMap();
1121 |
1122 | SongLink link;
1123 | link.set_errorcode(data[QLatin1String("errorCode")].toString());
1124 |
1125 | QVariantMap song_data_map = data[QLatin1String("data")].toMap();
1126 |
1127 | SongData sdata;
1128 | sdata.set_xcode(song_data_map[QLatin1String("xcode")].toString());
1129 |
1130 | QList slist = song_data_map[QLatin1String("songList")].toList();
1131 | QList slists;
1132 | foreach(QVariant s, slist)
1133 | {
1134 | QVariantMap sl = s.toMap();
1135 | SongList *list = new SongList;
1136 | list->set_songpic_radio(sl[QLatin1String("songPicRadio")].toString());
1137 | list->set_lrclink(sl[QLatin1String("lrcLink")].toString());
1138 | slists.append(list);
1139 | }
1140 | sdata.set_song_lists(slists);
1141 | link.set_song_data(sdata);
1142 |
1143 | SongData temp2 = link.get_song_data();
1144 | QList temp3 = temp2.get_song_lists();
1145 | if (temp3.count() > 0)
1146 | {
1147 | SongList *templist = temp3[0];
1148 | picUrl = templist->get_songpic_radio();//获取专辑图片网址
1149 | qDebug()<<"founded songpic_radio:"<get_lrclick();//获取歌词网址
1151 | qDebug()<<"founded lrclick:"<deleteLater();
1157 | }
1158 |
1159 | void HiPlayer::hi_recvLrc(QNetworkReply *reply)//接收网络歌词,保存歌词文件
1160 | {
1161 | if (reply->error() == QNetworkReply::NoError)
1162 | {
1163 | QByteArray data = reply->readAll();
1164 | qDebug()<<"founded lrc data:"<open(QIODevice::WriteOnly)) {
1171 | delete file;
1172 | file = 0;
1173 | return;
1174 | }
1175 |
1176 | QDataStream out(file);
1177 | out << data;
1178 | file->close();
1179 | delete file;
1180 | file = 0;
1181 | }
1182 | reply->deleteLater();
1183 |
1184 | slotResolveLrc(playingFile);
1185 | }
1186 |
1187 | void HiPlayer::hi_recvPic(QNetworkReply *reply)//接收专辑图片
1188 | {
1189 | if (reply->error() == QNetworkReply::NoError)
1190 | {
1191 | QByteArray data = reply->readAll();
1192 | if (data.size() < 50)//未获取到图片,直接跳过去获取歌词
1193 | {
1194 | qDebug()<<"未收到正确的图片!";
1195 | receiveState = RECEIVE_LRC;
1196 | return;
1197 | }
1198 | QPixmap currentPicture;
1199 |
1200 | if (currentPicture.loadFromData(data)){
1201 | picLabel->setPixmap(currentPicture);
1202 | }
1203 |
1204 | receiveState = RECEIVE_LRC;
1205 |
1206 | QString temp = playingFile;
1207 | QString fileName = temp.remove(temp.right(3)) + "jpg";
1208 | currentPicture.save(fileName);//将图片保存到文件中
1209 | }
1210 | reply->deleteLater();
1211 | }
1212 |
1213 | bool HiPlayer::hi_getPicFromFile() //从磁盘中读取专辑图片
1214 | {
1215 | if (playingFile.isEmpty())
1216 | return false;
1217 | QString file_name = playingFile;
1218 | QString pic_file_name = file_name.remove(file_name.right(3)) + "jpg";//把音频文件的后缀改成jpg后缀
1219 |
1220 | // 打开图片文件
1221 | QFile file(pic_file_name);
1222 | if (!file.open(QIODevice::ReadOnly))
1223 | return false;
1224 | QByteArray temp = file.readAll();
1225 | QPixmap currentPicture;
1226 |
1227 | if (currentPicture.loadFromData(temp))
1228 | {
1229 | picLabel->setPixmap(currentPicture);
1230 | }
1231 | file.close();
1232 | return true;
1233 | }
1234 |
1235 | void HiPlayer::closeEvent(QCloseEvent *) //窗口关闭之前需要的操作
1236 | {
1237 | slotWriteList();
1238 | }
1239 |
1240 |
1241 | void HiPlayer::slotSetPlayPosition(int pos)
1242 | {
1243 | playPosition = pos;
1244 | }
1245 |
1246 | int HiPlayer::slotGetPlayPosition()
1247 | {
1248 | return playPosition;
1249 | }
1250 |
1251 | void HiPlayer::mousePressEvent(QMouseEvent *event)
1252 | {
1253 | m_Moveing=true;
1254 | //记录下鼠标相对于窗口的位置
1255 | //event->globalPos()鼠标按下时,鼠标相对于整个屏幕位置
1256 | //pos() this->pos()鼠标按下时,窗口相对于父窗口的位置
1257 | m_MovePosition=event->globalPos() - pos();
1258 | //event->accept();
1259 | return QWidget::mousePressEvent(event);
1260 | }
1261 |
1262 | void HiPlayer::mouseMoveEvent(QMouseEvent *event)
1263 | {
1264 | //(event->buttons() && Qt::LeftButton)按下是左键
1265 | //鼠标移动事件需要移动窗口,窗口移动到哪里呢?就是要获取鼠标移动中,窗口在整个屏幕的坐标,然后move到这个坐标,怎么获取坐标?
1266 | //通过事件event->globalPos()知道鼠标坐标,鼠标坐标减去鼠标相对于窗口位置,就是窗口在整个屏幕的坐标
1267 | if (m_Moveing && (event->buttons() && Qt::LeftButton)
1268 | && (event->globalPos()-m_MovePosition).manhattanLength() > QApplication::startDragDistance())
1269 | {
1270 | move(event->globalPos()-m_MovePosition);//相对于桌面的位置.
1271 | m_MovePosition = event->globalPos() - pos();
1272 | }
1273 | return QWidget::mouseMoveEvent(event);
1274 | //event->accept();
1275 | }
1276 |
1277 | void HiPlayer::mouseReleaseEvent(QMouseEvent *)
1278 | {
1279 | m_Moveing=false;
1280 | }
1281 |
1282 | void HiPlayer::slotRecvMessage(QString message)
1283 | {
1284 | qDebug()<<"Tips:"<showNormal();
1286 | this->raise();
1287 | this->activateWindow();
1288 | }
1289 |
--------------------------------------------------------------------------------
/hiplayer.h:
--------------------------------------------------------------------------------
1 | #ifndef HIPLAYER_H
2 | #define HIPLAYER_H
3 |
4 |
5 | //文字滚动速度
6 | #define TEXT_SPEED 500
7 |
8 | #include "hiLrcWidget.h"
9 | #include "hiButton.h"
10 | #include "aboutDialog.h"
11 | #include "hiVolBotton.h"
12 | #include "hiLabel.h"
13 | #include "nofocusdelegate.h"
14 | #include "network.h"
15 | #include "songinfo.h"
16 | #include "playslider.h"
17 |
18 | #include
19 | #include
20 | #include
21 | #include
22 | #include
23 | #include
24 | #include
25 | #include
26 | #include
27 | #include
28 | #include
29 | #include
30 |
31 | //枚举播放模式
32 | enum Play_Mode{SINGAL, LISTCIRCLE, SINGALCIRCLE, RANDOM};
33 |
34 | //网络音乐信息,专辑图片,歌词获取状态
35 | //网络歌词、专辑图片获取(保存在歌曲目录下,文件名与歌曲同名)
36 | enum { RECEIVE_INFO, RECEIVE_LINK, RECEIVE_PIC, RECEIVE_LRC };
37 |
38 | class MiniWindow;
39 |
40 | class HiPlayer : public QWidget
41 | {
42 | //设置mini窗口类为主窗口类的友元类,从而可以调用主窗口类的私有函数和私有对象
43 | friend class MiniWindow;
44 |
45 | Q_OBJECT
46 |
47 | public:
48 | explicit HiPlayer(QWidget *parent = 0);
49 | ~HiPlayer();
50 |
51 | //通过命令行打开指定音乐文件
52 | void hi_openMusic(const QString& filePath);
53 |
54 | public slots:
55 |
56 | //接受mini窗口传来的参数设置播放模式
57 | void slotSetModeFromMini(int mode);
58 |
59 | //接受mini窗口传来的参数设置音量
60 | void slotSetVolFromMini(int val);
61 |
62 | public slots:
63 |
64 | //访问目录结构
65 | void slotOpenDir();
66 |
67 | //添加mp3格式的文件
68 | void slotOpenMusic();
69 |
70 | //删除指定行的歌曲
71 | void slotRemoveCurrentMusic();
72 |
73 | //清空播放列表
74 | void slotClearList();
75 |
76 | //请求右键菜单
77 | void slotPlaylistMenuRequested(const QPoint &pos);
78 |
79 | //双击播放歌曲
80 | void slotPlaylistDoubleClicked(int row, int);
81 |
82 | //更新音乐信息
83 | void slotUpdateMetaData();
84 |
85 | //更新进度条
86 | void slotUpdateProcessbar(qint64 duration);
87 |
88 | //更新播放状态
89 | void slotUpdateState(QMediaPlayer::State state);
90 |
91 | //更新播放进度
92 | void slotSetPosition(/*int position*/);
93 |
94 | //更新歌词、时间显示
95 | void slotUpdatePosition(qint64 position);
96 |
97 | //设置各按钮的单击事件,激活各按钮
98 | void slotPlayButtonClicked();
99 | void slotLyricButtonClicked();
100 | void slotLogoButtonClicked();
101 | void slotModeButtonClicked();
102 | void slotPauseButtonClicked();
103 | void slotMinButtonClicked();
104 | void slotNextButtonClicked();
105 | void slotLastButtonClicked();
106 |
107 | //设置播放模式
108 | void slotSetPlayMode();
109 |
110 | //解析LRC歌词
111 | bool slotResolveLrc(const QString &source_file_name);
112 |
113 | //程序打开时读取播放列表文件
114 | void slotReadList();
115 |
116 | //把现有播放列表写入列表文件
117 | void slotWriteList();
118 |
119 | //设置当前播放位置
120 | void slotSetPlayPosition(int pos);
121 |
122 | //获取当前播放位置
123 | int slotGetPlayPosition();
124 |
125 | //处理鼠标点击PlaySlider的信号
126 | void slotSliderValueClicked(int value);
127 |
128 | //实现只允许唯一程序执行
129 | void slotRecvMessage(QString message);
130 | protected:
131 | void closeEvent(QCloseEvent *event); //窗口关闭之前需要的操作
132 | private:
133 |
134 | //绘制窗体(也用于窗口位置拖动)
135 | void paintEvent(QPaintEvent *event);
136 |
137 | //拖拽添加,拖拽加歌现在可以一次性添加多首,且可以自动识别文件类型,只添加mp3文件 .
138 | void dragEnterEvent(QDragEnterEvent *event);
139 | void dropEvent(QDropEvent *event);
140 |
141 | //用于窗口位置拖动
142 | void mousePressEvent(QMouseEvent *event);
143 | void mouseMoveEvent(QMouseEvent *event);
144 | void mouseReleaseEvent(QMouseEvent *event);
145 |
146 | //初始化主界面
147 | void hi_initUi();
148 |
149 | //初始化播放模块
150 | void hi_initPlayer();
151 |
152 | //初始化信号-槽连接
153 | void hi_initConnections();
154 |
155 | //初始化窗口
156 | void hi_initWindows();
157 |
158 | //初始化菜单项
159 | void hi_initMenuActions();
160 |
161 | //添加到播放列表
162 | void hi_addList(QStringList list);
163 |
164 | //定制tablewidget外观
165 | void hi_setTableColor();
166 |
167 | //初始化网络模块
168 | void hi_initNetwork();
169 |
170 | //获取网络数据
171 | void hi_fetchNetData();
172 |
173 | //接收专辑图片
174 | void hi_recvPic(QNetworkReply *reply);
175 |
176 | //接收歌曲信息
177 | void hi_recvInfo(QNetworkReply *reply);
178 |
179 | //接收网络歌词
180 | void hi_recvLrc(QNetworkReply *reply);
181 |
182 | //接收歌词地址
183 | void hi_recvLink(QNetworkReply *reply);
184 |
185 | //从磁盘中读取专辑图片
186 | bool hi_getPicFromFile();
187 |
188 |
189 | private:
190 | HiLrcWidget *lrcWidget;
191 | QMap lrcMap;
192 |
193 | QStringList playList;
194 | QString playingFile;
195 | QString dirPath;
196 |
197 | HiButton *miniButton;
198 | HiButton *exitButton;
199 | HiButton *addButton;
200 | HiButton *lyricButton;
201 | HiButton *lastButton;
202 | HiButton *nextButton;
203 | HiButton *playButton;
204 | HiButton *pauseButton;
205 | HiButton *modeButton;
206 | HiButton *minButton;
207 | HiButton *logoButton;
208 |
209 | HiLabel *nameLabel;
210 | QLabel *musicianLabel;
211 | QLabel *albumLabel;
212 | QLabel *timeLabel;
213 | QLabel *picLabel;
214 |
215 | PlaySlider *playSlider;
216 | // QSlider *volSlider;
217 |
218 | QTableWidget *playlistTable;
219 |
220 | QMediaPlayer *mediaPlayer;
221 | QMediaPlaylist *mediaList;
222 |
223 | QMenu *contextMenuLess;
224 | QMenu *contextMenuMore;
225 | QMenu *playModeMenu;
226 |
227 | QActionGroup *modeActionGroup;
228 |
229 | //enum ICE_Play_Mode{SINGAL, LISTCIRCLE, SINGALCIRCLE, RANDOM};
230 | QAction *modeSingal;
231 | QAction *modeListCircle;
232 | QAction *modeSingalCircle;
233 | QAction *modeRandom;
234 | QAction *addMusic;
235 | QAction *addFileDiv;
236 | QAction *removeCurr;
237 | QAction *removeAll;
238 |
239 | HiVolBotton *volButton;
240 |
241 | MiniWindow * miniForm;
242 | AboutDialog *aboutForm;
243 |
244 | NetWorker * networker;
245 | QString songName;
246 | QString songArtist;
247 | QString songId;
248 | QString picUrl;
249 | QString lrcUrl;
250 |
251 | //int preIndex;//未使用
252 | int currentIndex;//当前播放歌曲在列表中的index
253 | int playMode;//当前播放模式
254 |
255 | int receiveState;//接收状态
256 | int playPosition;//当前歌曲播放位置
257 |
258 | //用于窗口位置拖动
259 | bool m_Moveing;
260 | QPoint m_MovePosition;
261 | };
262 |
263 | #endif // HIPLAYER_H
264 |
--------------------------------------------------------------------------------
/icon.qrc:
--------------------------------------------------------------------------------
1 |
2 |
3 | resources/about.png
4 | resources/addMusic_40_40.png
5 | resources/HiPlayer_16_16_2.png
6 | resources/HiPlayer_32_32_2.png
7 | resources/HiPlayer_38_38.png
8 | resources/HiPlayer_48_48_2.png
9 | resources/HiPlayer_80_80_2.png
10 | resources/HiPlayer_256_256_2.png
11 | resources/Last_40_40.png
12 | resources/Lyric_40_40.png
13 | resources/mode.png
14 | resources/Next_40_40.png
15 | resources/Pause_60_60.png
16 | resources/Pause_100_100.png
17 | resources/Play_60_60.png
18 | resources/Play_100_100.png
19 | resources/Volumn_40_40.png
20 | resources/background.png
21 | resources/default_album.jpg
22 | resources/关闭.png
23 | resources/缩小.png
24 | resources/最小化.png
25 | resources/lrc_background.png
26 | resources/album.png
27 | resources/播放按钮mini.png
28 | resources/mini_back.png
29 | resources/play_mini.png
30 | resources/pause_mini.png
31 | resources/max_mini.png
32 | resources/next_mini.png
33 | resources/last_mini.png
34 |
35 |
36 |
--------------------------------------------------------------------------------
/lrcLabel.cpp:
--------------------------------------------------------------------------------
1 | #include "lrcLabel.h"
2 |
3 | LrcLabel::LrcLabel(QWidget *parent)
4 | : HiLabel(parent)
5 | {
6 | setText(QString::fromUtf8("HiPlayer"));
7 | // 固定显示区域大小
8 | setMaximumSize(800, 60);
9 | setMinimumSize(800, 60);
10 |
11 | //歌词的线性渐变填充
12 | linearGradient.setStart(0, 10);//填充的起点坐标
13 | linearGradient.setFinalStop(0, 40);//填充的终点坐标
14 | //第一个参数终点坐标,相对于我们上面的区域而言,按照比例进行计算
15 | linearGradient.setColorAt(0.1, QColor(0, 148, 255));
16 | linearGradient.setColorAt(0.5, QColor(114, 232, 255));
17 | linearGradient.setColorAt(0.9, QColor(0, 148, 255));
18 |
19 |
20 | // 遮罩的线性渐变填充
21 | maskLinearGradient.setStart(0, 0);
22 | maskLinearGradient.setFinalStop(0, 40);
23 | maskLinearGradient.setColorAt(0.1, QColor(222, 54, 4));
24 | maskLinearGradient.setColorAt(0.5, QColor(255, 72, 16));
25 | maskLinearGradient.setColorAt(0.9, QColor(222, 54, 4));
26 |
27 | // 设置字体
28 | lrcFont.setFamily(QString::fromUtf8("微软雅黑"));
29 | //lrcFont.setBold(true);//字体加粗
30 | lrcFont.setPointSize(25);
31 |
32 | // 设置定时器
33 | lrcTimer = new QTimer(this);
34 | connect(lrcTimer, SIGNAL(timeout()), this, SLOT(slotTimeout()));
35 | lrcMaskWidth = 0;
36 | lrcMaskWidthInterval = 0;
37 | }
38 |
39 | // 开启遮罩,需要指定当前歌词开始与结束之间的时间间隔(ms)
40 | void LrcLabel::hi_startLrcMask(qint64 intervaltime)
41 | {
42 | // 这里设置每隔30毫秒更新一次遮罩的宽度,因为如果更新太频繁
43 | // 会增加CPU占用率,而如果时间间隔太大,则动画效果就不流畅了
44 | qreal count = intervaltime / 30;
45 | //获取遮罩每次需要增加的宽度,这里的800是部件的固定宽度
46 | lrcMaskWidthInterval = 800 / count;
47 | lrcMaskWidth = 0;
48 | lrcTimer->start(30);
49 | }
50 |
51 | void LrcLabel::hi_stopLrcMask()
52 | {
53 | lrcTimer->stop();
54 | lrcMaskWidth = 0;
55 | update();
56 | }
57 |
58 | void LrcLabel::paintEvent(QPaintEvent *)
59 | {
60 |
61 | QPainter painter(this);
62 | painter.setFont(lrcFont);
63 |
64 | if(text().size() < 2){
65 | setText("Music...");
66 | }
67 | QString tmp = text();
68 | tmp.toUtf8();
69 | QColor(0, 0, 0, 200);//90, 105, 115, 200
70 | // 先绘制底层文字,作为阴影,这样会使显示效果更加清晰,且更有质感
71 | painter.setPen(QColor(0, 0, 0, 200));
72 | painter.drawText(31, 1, 800, 60, Qt::AlignLeft, tmp);
73 |
74 | // 再在上面绘制渐变文字
75 | painter.setPen(QPen(linearGradient, 0));
76 | painter.drawText(30, 0, 800, 60, Qt::AlignLeft, tmp);
77 |
78 | // 设置歌词遮罩
79 | painter.setPen(QPen(maskLinearGradient, 0));
80 | painter.drawText(30, 0, lrcMaskWidth+30, 60, Qt::AlignLeft, tmp);
81 | }
82 |
83 |
84 | //右击事件
85 | void LrcLabel::contextMenuEvent(QContextMenuEvent *event)
86 | {
87 | QMenu menu;
88 | menu.addAction(QString::fromUtf8("隐藏"), this->parent(), SLOT(hide()));
89 | menu.exec(event->globalPos());//globalPos()为当前鼠标的位置坐标
90 | }
91 |
92 |
93 | void LrcLabel::slotTimeout()
94 | {
95 |
96 | //每隔一段固定的时间笼罩的长度就增加一点
97 | lrcMaskWidth += lrcMaskWidthInterval;
98 | update();//更新widget,但是并不立即重绘,而是安排一个Paint事件,当返回主循环时由系统来重绘
99 | }
100 |
101 | void LrcLabel::hi_setFontSize(int size)//设置字体
102 | {
103 | lrcFont.setPointSize(size);
104 | }
105 |
--------------------------------------------------------------------------------
/lrcLabel.h:
--------------------------------------------------------------------------------
1 | #ifndef LRCLABEL_H
2 | #define LRCLABEL_H
3 |
4 | #include
5 | #include "hiLabel.h"
6 |
7 | //带有歌词遮罩的label
8 | class LrcLabel : public HiLabel
9 | {
10 |
11 | Q_OBJECT
12 | public:
13 | explicit LrcLabel(QWidget *parent = 0);
14 |
15 | //开始歌词遮罩
16 | void hi_startLrcMask(qint64 intervaltime);
17 |
18 | //停止歌词遮罩
19 | void hi_stopLrcMask();
20 |
21 | //调整字体大小
22 | void hi_setFontSize(int size);
23 |
24 | protected:
25 |
26 | //绘制窗体
27 | void paintEvent(QPaintEvent *);
28 |
29 | //菜单事件
30 | void contextMenuEvent(QContextMenuEvent *event);
31 |
32 | private slots:
33 |
34 | void slotTimeout();
35 |
36 | private:
37 |
38 | QLinearGradient linearGradient;
39 | QLinearGradient maskLinearGradient;
40 | QFont lrcFont;
41 | QTimer * lrcTimer;
42 | qreal lrcMaskWidth;
43 | qreal lrcMaskWidthInterval;
44 | QPoint offSet;
45 | };
46 |
47 | #endif // LRCLABEL_H
48 |
--------------------------------------------------------------------------------
/main.cpp:
--------------------------------------------------------------------------------
1 | #include "singleApp.h"
2 | #include "hiplayer.h"
3 |
4 | #include
5 |
6 | //已添加的歌曲列表记录在文件HiPlayerList.list中
7 |
8 | int main(int argc, char *argv[])
9 | {
10 | SingleApp app(argc, argv, "hiplayer");
11 |
12 | if(app.isRunning())
13 | {
14 | app.sendMessage("The program is running!");
15 | return 0;
16 | }
17 | HiPlayer w;
18 | QObject::connect(&app,SIGNAL(sigMsgAvailable(QString)),&w,SLOT(slotRecvMessage(QString)));
19 | w.show();
20 |
21 | return app.exec();
22 | }
23 |
--------------------------------------------------------------------------------
/miniWindow.cpp:
--------------------------------------------------------------------------------
1 | #include "miniWindow.h"
2 | #include "hiplayer.h"
3 |
4 | MiniWindow::MiniWindow(HiPlayer *hiplayer,QWidget *parent):QWidget(parent)
5 | {
6 | mainWindow = hiplayer;
7 |
8 | setWindowFlags(Qt::FramelessWindowHint | Qt::Tool | Qt::WindowStaysOnTopHint);
9 | setAttribute(Qt::WA_TranslucentBackground);
10 | //半透明
11 | this->setWindowOpacity(0.9);
12 |
13 | //固定大小
14 | this->setFixedSize(100, 100);
15 |
16 | miniPlayButton = new HiButton( this);
17 | miniPlayButton->setObjectName(QStringLiteral("miniPlayButton"));
18 | miniPlayButton->setGeometry(QRect(35, 30, 33, 33));
19 |
20 | miniPauseButton = new HiButton( this);
21 | miniPauseButton->setObjectName(QStringLiteral("miniPauseButton"));
22 | miniPauseButton->setGeometry(QRect(31, 30, 33, 33));
23 | miniPauseButton->setVisible(false);
24 |
25 | miniNextButton = new HiButton( this);
26 | miniNextButton->setObjectName(QStringLiteral("nextButton"));
27 | miniNextButton->setGeometry(QRect(70, 64, 16, 16));
28 |
29 | miniLastButton = new HiButton(this);
30 | miniLastButton->setObjectName(QStringLiteral("lastButton"));
31 | miniLastButton->setGeometry(QRect(8,57,12,12));
32 |
33 | miniMaxButton=new HiButton(this);
34 | miniMaxButton->setObjectName(QStringLiteral("maxButton"));
35 | miniMaxButton->setGeometry(QRect(70,14,14,14));
36 |
37 | //设置图标
38 | QIcon icon_play;
39 | icon_play.addFile(QStringLiteral(":/hiplayer/resources/play_mini.png"));
40 | miniPlayButton->hi_setButtonIcons(icon_play,icon_play);
41 |
42 | miniPlayButton->setIconSize(QSize(36,36));
43 | miniPlayButton->setFlat(true);
44 | miniPlayButton->setFocusPolicy(Qt::NoFocus);
45 | miniPlayButton->setStyleSheet("QPushButton{background-color:rgba(255,255,255,0);border-style:solid;border-width:0px;border-color:rgba(255,255,255,0);}");
46 |
47 | QIcon icon_pause;
48 | icon_pause.addFile(QStringLiteral(":/hiplayer/resources/pause_mini.png"));
49 | miniPauseButton->hi_setButtonIcons(icon_pause);
50 |
51 | miniPauseButton->setIconSize(QSize(36,36));
52 | miniPauseButton->setFlat(true);
53 | miniPauseButton->setFocusPolicy(Qt::NoFocus);
54 | miniPauseButton->setStyleSheet("QPushButton{background-color:rgba(255,255,255,0);border-style:solid;border-width:0px;border-color:rgba(255,255,255,0);}");
55 |
56 | QIcon icon_next;
57 | icon_next.addFile(QStringLiteral(":/hiplayer/resources/next_mini.png"));
58 | miniNextButton->hi_setButtonIcons(icon_next);
59 |
60 | miniNextButton->setIconSize(QSize(16,16));
61 | miniNextButton->setFlat(true);
62 | miniNextButton->setFocusPolicy(Qt::NoFocus);
63 | miniNextButton->setStyleSheet("QPushButton{background-color:rgba(255,255,255,0);border-style:solid;border-width:0px;border-color:rgba(255,255,255,0);}");
64 |
65 | QIcon icon_last;
66 | icon_last.addFile(QStringLiteral(":/hiplayer/resources/last_mini.png"));
67 | miniLastButton->hi_setButtonIcons(icon_last);
68 |
69 | miniLastButton->setIconSize(QSize(12,12));
70 | miniLastButton->setFlat(true);
71 | miniLastButton->setFocusPolicy(Qt::NoFocus);
72 | miniLastButton->setStyleSheet("QPushButton{background-color:rgba(255,255,255,0);border-style:solid;border-width:0px;border-color:rgba(255,255,255,0);}");
73 |
74 | QIcon icon_max;
75 | icon_max.addFile(QStringLiteral(":/hiplayer/resources/max_mini.png"));
76 | miniMaxButton->hi_setButtonIcons(icon_max);
77 |
78 | miniMaxButton->setIconSize(QSize(14,14));
79 | miniMaxButton->setFlat(true);
80 | miniMaxButton->setFocusPolicy(Qt::NoFocus);
81 | miniMaxButton->setStyleSheet("QPushButton{background-color:rgba(255,255,255,0);border-style:solid;border-width:0px;border-color:rgba(255,255,255,0);}");
82 |
83 |
84 | hi_initMenuActions();
85 | connect(miniPlayButton, SIGNAL(clicked()), this, SLOT(slotPlay()));
86 | connect(miniPauseButton, SIGNAL(clicked()), this, SLOT(slotPause()));
87 | connect(miniNextButton, SIGNAL(clicked()), this, SLOT(slotNextMusic()));
88 | connect(miniLastButton,SIGNAL(clicked()),this,SLOT(slotLastMusic()));
89 | connect(miniMaxButton,SIGNAL(clicked()),this,SLOT(slotBackToMain()));
90 | }
91 |
92 | MiniWindow::~MiniWindow()
93 | {
94 |
95 | }
96 |
97 | void MiniWindow::paintEvent(QPaintEvent *event)//绘制窗体背景
98 | {
99 | qDebug()<<"paintEvent";
100 | QPainter p(this);
101 | p.drawPixmap(0, 0 , QPixmap(":/hiplayer/resources/mini_back.png"));
102 | QWidget::paintEvent(event);
103 | }
104 |
105 | void MiniWindow::hi_initMenuActions()//设置右键菜单
106 | {
107 | mode0 = new QAction(QString::fromUtf8("单曲播放"), this);
108 | mode1 = new QAction(QString::fromUtf8("列表循环"), this);
109 | mode2 = new QAction(QString::fromUtf8("单曲循环"), this);
110 | mode3 = new QAction(QString::fromUtf8("随机播放"), this);
111 |
112 | modeGroup = new QActionGroup(this);
113 | modeGroup->addAction(mode0);
114 | modeGroup->addAction(mode1);
115 | modeGroup->addAction(mode2);
116 | modeGroup->addAction(mode3);
117 |
118 | mode0->setCheckable(true);
119 | mode1->setCheckable(true);
120 | mode2->setCheckable(true);
121 | mode3->setCheckable(true);
122 | mode0->setChecked(true);
123 |
124 | mainForm = new QAction(QString::fromUtf8("返回主界面"),this);
125 | next = new QAction(QString::fromUtf8("下一曲"),this);
126 | last = new QAction(QString::fromUtf8("上一曲"),this);
127 | lyric = new QAction(QString::fromUtf8("桌面歌词"), this);
128 | exit = new QAction(QString::fromUtf8("退出"),this);
129 |
130 | volSlider = new QSlider(Qt::Horizontal, this);
131 | volSlider->setRange(0, 100);
132 | volSlider->setGeometry(QRect(26,0,75,25));
133 | connect(volSlider, SIGNAL(valueChanged(int)), this, SLOT(slotUpdateVol(int)));
134 |
135 | volSlider->setStyleSheet("QSlider::groove:horizontal{border:0px;height:4px;}"
136 | "QSlider::sub-page:horizontal{background:#0096ff;}"
137 | "QSlider::add-page:horizontal{background:lightgray;} "
138 | "QSlider::handle:horizontal{background:white;width:10px;border:#51b5fb 10px;border-radius:5px;margin:-3px 0px -3px 0px;}");
139 |
140 | setVolumn = new QWidgetAction(this);
141 | setVolumn->setDefaultWidget(volSlider);
142 |
143 | contextMenu = new QMenu(this);
144 | contextMenu->addAction(mainForm);
145 | contextMenu->addSeparator();
146 | contextMenu->addAction(setVolumn);
147 | contextMenu->addSeparator();
148 | contextMenu->addAction(next);
149 | contextMenu->addAction(last);
150 | contextMenu->addSeparator();
151 | contextMenu->addActions(modeGroup->actions());
152 | contextMenu->addSeparator();
153 | contextMenu->addAction(lyric);
154 | contextMenu->addSeparator();
155 | contextMenu->addAction(exit);
156 |
157 | contextMenu->setStyleSheet(
158 | "QMenu{padding:5px;background:white;border:1px solid gray;}"
159 | "QMenu::item{padding:0px 40px 0px 30px;height:25px;}"
160 | "QMenu::item:selected:enabled{background:#0096ff;color:white;}"
161 | "QMenu::item:selected:!enabled{background:transparent;}"
162 | "QMenu::separator{height:1px;background:lightgray;margin:5px 0px 5px 0px;}");
163 |
164 |
165 | connect(mode0, SIGNAL(triggered()), this, SLOT(slotSetMode()));
166 | connect(mode1, SIGNAL(triggered()), this, SLOT(slotSetMode()));
167 | connect(mode2, SIGNAL(triggered()), this, SLOT(slotSetMode()));
168 | connect(mode3, SIGNAL(triggered()), this, SLOT(slotSetMode()));
169 |
170 | connect(mainForm, SIGNAL(triggered()), this, SLOT(slotBackToMain()));
171 | connect(next, SIGNAL(triggered()), this, SLOT(slotNextMusic()));
172 | connect(last, SIGNAL(triggered()), this, SLOT(slotLastMusic()));
173 | connect(lyric, SIGNAL(triggered()), this, SLOT(slotLyricAction()));
174 | connect(exit, SIGNAL(triggered()), this, SLOT(slotExit()));
175 | }
176 |
177 | void MiniWindow::hi_initPlayMode(int vol)//初始化播放模式和音量
178 | {
179 | switch(mainWindow->playMode){
180 | case 0:
181 | mode0->setChecked(true);
182 | break;
183 | case 1:
184 | mode1->setChecked(true);
185 | break;
186 | case 2:
187 | mode2->setChecked(true);
188 | break;
189 | case 3:
190 | mode3->setChecked(true);
191 | break;
192 | }
193 |
194 | if(mainWindow->playButton->isVisible()){
195 | miniPlayButton->setVisible(true);
196 | miniPauseButton->setVisible(false);
197 | }
198 | else {
199 | miniPlayButton->setVisible(false);
200 | miniPauseButton->setVisible(true);
201 | }
202 |
203 | volSlider->setValue(vol);
204 | }
205 |
206 | void MiniWindow::contextMenuEvent(QContextMenuEvent *)//鼠标右键触发
207 | {
208 | contextMenu->exec(QCursor::pos());
209 | }
210 |
211 | void MiniWindow::slotExit()
212 | {
213 | mainWindow->close();
214 | this->close();
215 | }
216 |
217 | void MiniWindow::slotBackToMain()
218 | {
219 | mainWindow->show();
220 | this->hide();
221 | }
222 |
223 | void MiniWindow::slotNextMusic()
224 | {
225 |
226 | mainWindow->slotNextButtonClicked();
227 | }
228 |
229 | void MiniWindow::slotLastMusic()
230 | {
231 | mainWindow->slotLastButtonClicked();
232 | }
233 |
234 | void MiniWindow::slotPlay()
235 | {
236 | mainWindow->slotPlayButtonClicked();
237 | miniPauseButton->setVisible(true);
238 | miniPlayButton->setVisible(false);
239 | }
240 |
241 | void MiniWindow::slotPause()
242 | {
243 | mainWindow->slotPauseButtonClicked();
244 | miniPauseButton->setVisible(false);
245 | miniPlayButton->setVisible(true);
246 | }
247 |
248 | void MiniWindow::slotSetMode()
249 | {
250 | if(mode0->isChecked()) {
251 | mainWindow->slotSetModeFromMini(0);
252 | }
253 | else if(mode1->isChecked()) {
254 | mainWindow->slotSetModeFromMini(1);
255 | }
256 | else if(mode2->isChecked()) {
257 | mainWindow->slotSetModeFromMini(2);
258 | }
259 | else if(mode3->isChecked()) {
260 | mainWindow->slotSetModeFromMini(3);
261 | }
262 | }
263 |
264 | void MiniWindow::slotUpdateVol(int a)
265 | {
266 | mainWindow->slotSetVolFromMini(a);
267 | }
268 |
269 | void MiniWindow::slotLyricAction()
270 | {
271 | mainWindow->slotLyricButtonClicked();
272 | }
273 |
274 | void MiniWindow::mousePressEvent(QMouseEvent *event)
275 | {
276 | m_Moveing=true;
277 | //记录下鼠标相对于窗口的位置
278 | //event->globalPos()鼠标按下时,鼠标相对于整个屏幕位置
279 | //pos() this->pos()鼠标按下时,窗口相对于父窗口的位置
280 | m_MovePosition=event->globalPos() - pos();
281 | return QWidget::mousePressEvent(event);
282 | }
283 |
284 | void MiniWindow::mouseMoveEvent(QMouseEvent *event)
285 | {
286 | //(event->buttons() && Qt::LeftButton)按下是左键
287 | //鼠标移动事件需要移动窗口,窗口移动到哪里呢?就是要获取鼠标移动中,窗口在整个屏幕的坐标,然后move到这个坐标,怎么获取坐标?
288 | //通过事件event->globalPos()知道鼠标坐标,鼠标坐标减去鼠标相对于窗口位置,就是窗口在整个屏幕的坐标
289 | if (m_Moveing && (event->buttons() && Qt::LeftButton)
290 | && (event->globalPos()-m_MovePosition).manhattanLength() > QApplication::startDragDistance())
291 | {
292 | move(event->globalPos()-m_MovePosition);//相对于桌面的位置.
293 | m_MovePosition = event->globalPos() - pos();
294 | }
295 | return QWidget::mouseMoveEvent(event);
296 | }
297 |
298 | void MiniWindow::mouseReleaseEvent(QMouseEvent *)
299 | {
300 | m_Moveing=false;
301 | }
302 |
303 |
--------------------------------------------------------------------------------
/miniWindow.h:
--------------------------------------------------------------------------------
1 | #ifndef MINIWINDOW_H
2 | #define MINIWINDOW_H
3 |
4 | #include
5 | #include "hiButton.h"
6 | //#include "hiplayer.h"
7 |
8 | class HiPlayer;
9 |
10 | class MiniWindow : public QWidget
11 | {
12 | Q_OBJECT
13 | public:
14 | MiniWindow(HiPlayer * hiplayer,QWidget *parent = 0);
15 | ~MiniWindow();
16 |
17 | void hi_initPlayMode(int vol);
18 |
19 |
20 | private slots:
21 | void slotBackToMain();
22 |
23 | void slotNextMusic();
24 |
25 | void slotLastMusic();
26 |
27 | void slotPlay();
28 |
29 | void slotPause();
30 |
31 | void slotSetMode();
32 |
33 | void slotExit();
34 |
35 | void slotLyricAction();
36 |
37 | void slotUpdateVol(int);
38 | private:
39 | void paintEvent(QPaintEvent *event);
40 | void contextMenuEvent(QContextMenuEvent *event);
41 |
42 | void hi_initMenuActions();
43 |
44 | //用于窗口位置拖动
45 | void mousePressEvent(QMouseEvent *event);
46 | void mouseMoveEvent(QMouseEvent *event);
47 | void mouseReleaseEvent(QMouseEvent *event);
48 |
49 | HiButton *miniPlayButton;
50 | HiButton *miniPauseButton;
51 | HiButton *miniNextButton;
52 | HiButton *miniLastButton;
53 | HiButton *miniMaxButton;
54 |
55 | QMenu *contextMenu;
56 | QActionGroup *modeGroup;
57 | QAction *mode0;
58 | QAction *mode1;
59 | QAction *mode2;
60 | QAction *mode3;
61 | QAction *mainForm;
62 | QAction *next;
63 | QAction *last;
64 | QAction *lyric;
65 | QAction *exit;
66 |
67 | QWidgetAction *setVolumn;
68 | QSlider *volSlider;
69 |
70 | HiPlayer *mainWindow;
71 |
72 | //用于窗口位置拖动
73 | bool m_Moveing;
74 | QPoint m_MovePosition;
75 |
76 | };
77 | #endif // MINIWINDOW_H
78 |
--------------------------------------------------------------------------------
/network.cpp:
--------------------------------------------------------------------------------
1 | #include "network.h"
2 |
3 | class NetWorker::Private
4 | {
5 | public:
6 | Private(NetWorker * q)
7 | : manager(new QNetworkAccessManager(q))
8 | {}
9 | QNetworkAccessManager *manager;
10 | };
11 |
12 | NetWorker * NetWorker::getInstance()
13 | {
14 | static NetWorker netWorker;
15 | return &netWorker;
16 | }
17 |
18 | NetWorker::NetWorker(QObject *parent )
19 | : QObject(parent)
20 | , d(new NetWorker::Private(this))
21 | {
22 | connect(d->manager, &QNetworkAccessManager::finished, this,
23 | &NetWorker::finished);
24 | }
25 |
26 | NetWorker::~NetWorker()
27 | {
28 | delete d;
29 | d = 0;
30 | }
31 |
32 | void NetWorker::get(const QString &url)
33 | {
34 | d->manager->get(QNetworkRequest(QUrl(url)));
35 | }
36 |
--------------------------------------------------------------------------------
/network.h:
--------------------------------------------------------------------------------
1 | #ifndef NETWORK_H
2 | #define NETWORK_H
3 |
4 | //网络模块,实现网络功能
5 | //使用单例模式,封装网络接口
6 | //使用instance()获取唯一的NetWorker对象
7 | //使用内部类Private封装私有变量
8 |
9 | #include
10 | #include
11 | #include
12 |
13 | class NetWorker : public QObject
14 | {
15 |
16 | Q_OBJECT
17 |
18 | public:
19 |
20 | //获取唯一实例
21 | static NetWorker * getInstance();
22 |
23 | ~NetWorker();
24 |
25 | //向url发送get请求
26 | void get(const QString &url);
27 |
28 | signals:
29 | //操作完成后发射finished信号
30 | void finished(QNetworkReply *reply);
31 |
32 | private:
33 | class Private;//在类中定义另一个类
34 | friend class Private;
35 | Private * d;
36 |
37 | //使用单例模式,类的构造函数,复制构造函数和赋值运算符都声明为私有
38 | //若编译器支持c++ 11,Q_DECL_EQ_DELETE宏替换为 =delete
39 | explicit NetWorker(QObject *parent = 0);
40 | NetWorker(const NetWorker &) Q_DECL_EQ_DELETE;
41 | NetWorker &operator=(NetWorker rhs) Q_DECL_EQ_DELETE;
42 | //对于 C++ 的类,如果程序员没有为其定义特殊成员函数,那么
43 | //在需要用到某个特殊成员函数的时候,编译器会隐式的自动生成一个默认的特殊成员函数,
44 | //比如默认的构造函数、析构函数、拷贝构造函数以及拷贝赋值运算符。
45 | };
46 |
47 | #endif // NETWORK_H
48 |
--------------------------------------------------------------------------------
/nofocusdelegate.cpp:
--------------------------------------------------------------------------------
1 | #include "nofocusdelegate.h"
2 |
3 | void NoFocusDelegate::paint(QPainter* painter, const QStyleOptionViewItem & option, const QModelIndex &index) const
4 | {
5 | QStyleOptionViewItem itemOption(option);
6 | if (itemOption.state & QStyle::State_HasFocus)
7 | itemOption.state = itemOption.state ^ QStyle::State_HasFocus;
8 | QStyledItemDelegate::paint(painter, itemOption, index);
9 | }
10 |
--------------------------------------------------------------------------------
/nofocusdelegate.h:
--------------------------------------------------------------------------------
1 | #ifndef NOFOCUSDELEGATE_H
2 | #define NOFOCUSDELEGATE_H
3 |
4 | #include
5 | #include
6 | #include
7 | #include
8 |
9 | class NoFocusDelegate : public QStyledItemDelegate{
10 |
11 | protected:
12 |
13 | void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const;
14 | };
15 |
16 |
17 | #endif
18 |
--------------------------------------------------------------------------------
/playslider.cpp:
--------------------------------------------------------------------------------
1 | #include "playslider.h"
2 | #include
3 | #include
4 |
5 | PlaySlider::PlaySlider(QWidget *parent)
6 | : QSlider(parent)
7 | {
8 |
9 | }
10 | void PlaySlider::mousePressEvent(QMouseEvent *event)
11 | {
12 | //注意应先调用父类的鼠标点击处理事件,这样可以不影响拖动的情况
13 | QSlider::mousePressEvent(event);
14 | //获取鼠标的位置,这里并不能直接从ev中取值(因为如果是拖动的话,鼠标开始点击的位置没有意义了)
15 | double pos = event->pos().x() / (double)width();
16 | double value = pos * (maximum() - minimum()) + minimum();
17 | //value + 0.5 四舍五入
18 | setValue(value + 0.5);
19 | emit sigValueClicked(this->value());
20 | }
21 |
--------------------------------------------------------------------------------
/playslider.h:
--------------------------------------------------------------------------------
1 | #ifndef PLAYSLIDER_H
2 | #define PLAYSLIDER_H
3 |
4 | #include
5 |
6 | class PlaySlider : public QSlider
7 | {
8 | Q_OBJECT
9 | public:
10 | explicit PlaySlider(QWidget *parent = Q_NULLPTR);
11 | protected:
12 | void mousePressEvent(QMouseEvent *event);//实现鼠标点击改变滑块位置
13 | signals:
14 | void sigValueClicked(int value);
15 | public slots:
16 | };
17 |
18 | #endif // PLAYSLIDER_H
19 |
--------------------------------------------------------------------------------
/readme.md:
--------------------------------------------------------------------------------
1 | **HiPlay** 是一款精致小巧的音乐播放器。
2 | 其主要功能如下:
3 | 添加本地歌曲到播放列表;
4 | 自动通过网络获取专辑图片和歌词;
5 | 歌词桌面显示,且带有歌词遮罩效果;
6 | Mini模式显示。
7 | 以下是部分软件截图:
8 | 播放器主界面:
9 | 
10 | 歌词显示效果:
11 | 
12 | Mini窗口:
13 | 
14 | About界面:
15 | 
16 |
17 |
18 | HiPlayer播放器基于Qt技术开发,作者开发环境为Qt5.8.0,MinGW5.3.0(32-bit),欢迎大家下载、讨论。
19 | 源代码下载地址:[HiPlayer播放器源代码Github下载地址](https://github.com/xiaolong361/HiPlayer)
20 |
21 | 可执行程序下载地址(绿色免安装):[HiPlayer播放器软件百度网盘下载地址](https://pan.baidu.com/s/17VScymfjDAfltKyH3KTxvA)
22 |
--------------------------------------------------------------------------------
/resources/HiLogo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiaolong361/HiPlayer/441f1cab106a1c5c3f80c8cc07d6b286034e13ea/resources/HiLogo.png
--------------------------------------------------------------------------------
/resources/HiLogo4.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiaolong361/HiPlayer/441f1cab106a1c5c3f80c8cc07d6b286034e13ea/resources/HiLogo4.ico
--------------------------------------------------------------------------------
/resources/HiLogo_2.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiaolong361/HiPlayer/441f1cab106a1c5c3f80c8cc07d6b286034e13ea/resources/HiLogo_2.ico
--------------------------------------------------------------------------------
/resources/HiPlayer_16_16_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiaolong361/HiPlayer/441f1cab106a1c5c3f80c8cc07d6b286034e13ea/resources/HiPlayer_16_16_2.png
--------------------------------------------------------------------------------
/resources/HiPlayer_256_256_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiaolong361/HiPlayer/441f1cab106a1c5c3f80c8cc07d6b286034e13ea/resources/HiPlayer_256_256_2.png
--------------------------------------------------------------------------------
/resources/HiPlayer_32_32_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiaolong361/HiPlayer/441f1cab106a1c5c3f80c8cc07d6b286034e13ea/resources/HiPlayer_32_32_2.png
--------------------------------------------------------------------------------
/resources/HiPlayer_38_38.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiaolong361/HiPlayer/441f1cab106a1c5c3f80c8cc07d6b286034e13ea/resources/HiPlayer_38_38.png
--------------------------------------------------------------------------------
/resources/HiPlayer_48_48_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiaolong361/HiPlayer/441f1cab106a1c5c3f80c8cc07d6b286034e13ea/resources/HiPlayer_48_48_2.png
--------------------------------------------------------------------------------
/resources/HiPlayer_80_80_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiaolong361/HiPlayer/441f1cab106a1c5c3f80c8cc07d6b286034e13ea/resources/HiPlayer_80_80_2.png
--------------------------------------------------------------------------------
/resources/Last_40_40.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiaolong361/HiPlayer/441f1cab106a1c5c3f80c8cc07d6b286034e13ea/resources/Last_40_40.png
--------------------------------------------------------------------------------
/resources/Lyric_40_40.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiaolong361/HiPlayer/441f1cab106a1c5c3f80c8cc07d6b286034e13ea/resources/Lyric_40_40.png
--------------------------------------------------------------------------------
/resources/Next_40_40.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiaolong361/HiPlayer/441f1cab106a1c5c3f80c8cc07d6b286034e13ea/resources/Next_40_40.png
--------------------------------------------------------------------------------
/resources/Pause_100_100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiaolong361/HiPlayer/441f1cab106a1c5c3f80c8cc07d6b286034e13ea/resources/Pause_100_100.png
--------------------------------------------------------------------------------
/resources/Pause_60_60.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiaolong361/HiPlayer/441f1cab106a1c5c3f80c8cc07d6b286034e13ea/resources/Pause_60_60.png
--------------------------------------------------------------------------------
/resources/Play_100_100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiaolong361/HiPlayer/441f1cab106a1c5c3f80c8cc07d6b286034e13ea/resources/Play_100_100.png
--------------------------------------------------------------------------------
/resources/Play_60_60.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiaolong361/HiPlayer/441f1cab106a1c5c3f80c8cc07d6b286034e13ea/resources/Play_60_60.png
--------------------------------------------------------------------------------
/resources/Volumn_40_40.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiaolong361/HiPlayer/441f1cab106a1c5c3f80c8cc07d6b286034e13ea/resources/Volumn_40_40.png
--------------------------------------------------------------------------------
/resources/about.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiaolong361/HiPlayer/441f1cab106a1c5c3f80c8cc07d6b286034e13ea/resources/about.png
--------------------------------------------------------------------------------
/resources/addMusic_40_40.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiaolong361/HiPlayer/441f1cab106a1c5c3f80c8cc07d6b286034e13ea/resources/addMusic_40_40.png
--------------------------------------------------------------------------------
/resources/album.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiaolong361/HiPlayer/441f1cab106a1c5c3f80c8cc07d6b286034e13ea/resources/album.png
--------------------------------------------------------------------------------
/resources/background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiaolong361/HiPlayer/441f1cab106a1c5c3f80c8cc07d6b286034e13ea/resources/background.png
--------------------------------------------------------------------------------
/resources/default_album.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiaolong361/HiPlayer/441f1cab106a1c5c3f80c8cc07d6b286034e13ea/resources/default_album.jpg
--------------------------------------------------------------------------------
/resources/last_mini.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiaolong361/HiPlayer/441f1cab106a1c5c3f80c8cc07d6b286034e13ea/resources/last_mini.png
--------------------------------------------------------------------------------
/resources/lrc_background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiaolong361/HiPlayer/441f1cab106a1c5c3f80c8cc07d6b286034e13ea/resources/lrc_background.png
--------------------------------------------------------------------------------
/resources/max_mini.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiaolong361/HiPlayer/441f1cab106a1c5c3f80c8cc07d6b286034e13ea/resources/max_mini.png
--------------------------------------------------------------------------------
/resources/mini_back.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiaolong361/HiPlayer/441f1cab106a1c5c3f80c8cc07d6b286034e13ea/resources/mini_back.png
--------------------------------------------------------------------------------
/resources/mode.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiaolong361/HiPlayer/441f1cab106a1c5c3f80c8cc07d6b286034e13ea/resources/mode.png
--------------------------------------------------------------------------------
/resources/next_mini.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiaolong361/HiPlayer/441f1cab106a1c5c3f80c8cc07d6b286034e13ea/resources/next_mini.png
--------------------------------------------------------------------------------
/resources/pause_mini.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiaolong361/HiPlayer/441f1cab106a1c5c3f80c8cc07d6b286034e13ea/resources/pause_mini.png
--------------------------------------------------------------------------------
/resources/play_mini.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiaolong361/HiPlayer/441f1cab106a1c5c3f80c8cc07d6b286034e13ea/resources/play_mini.png
--------------------------------------------------------------------------------
/resources/关闭.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiaolong361/HiPlayer/441f1cab106a1c5c3f80c8cc07d6b286034e13ea/resources/关闭.png
--------------------------------------------------------------------------------
/resources/播放按钮mini.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiaolong361/HiPlayer/441f1cab106a1c5c3f80c8cc07d6b286034e13ea/resources/播放按钮mini.png
--------------------------------------------------------------------------------
/resources/最小化.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiaolong361/HiPlayer/441f1cab106a1c5c3f80c8cc07d6b286034e13ea/resources/最小化.png
--------------------------------------------------------------------------------
/resources/缩小.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiaolong361/HiPlayer/441f1cab106a1c5c3f80c8cc07d6b286034e13ea/resources/缩小.png
--------------------------------------------------------------------------------
/singleApp.cpp:
--------------------------------------------------------------------------------
1 | #include "singleApp.h"
2 | #include
3 |
4 | SingleApp::SingleApp(int &argc, char *argv[], const QString uniqueKey)
5 | : QApplication(argc, argv), _uniqueKey(uniqueKey)
6 | {
7 | _sharedMemory.setKey(_uniqueKey);
8 | if (_sharedMemory.attach())//读取数据,必须调用attach(),绑定_uniqueKey标志的共享内存区域
9 | _isRunning = true;//绑定成功,证明已经有进程创建了共享内存,有进程正在运行.
10 | else
11 | {
12 | _isRunning = false;
13 | // create shared memory.
14 | if (!_sharedMemory.create(1))//Creates a shared memory segment of 1 byte and attaches to the new shared memory segment
15 | {
16 | qDebug()<<"Unable to create single instance:"<<_sharedMemory.errorString().toLatin1();
17 | return;
18 | }
19 |
20 | // create local server and listen to incomming messages from other instances.
21 | _localServer = new QLocalServer(this);
22 | connect(_localServer, SIGNAL(newConnection()), this, SLOT(receiveMessage()));
23 | _localServer->listen(_uniqueKey);
24 | }
25 | }
26 |
27 | // public slots.
28 | void SingleApp::receiveMessage()
29 | {
30 | QLocalSocket * localSocket = _localServer->nextPendingConnection();
31 | if (!localSocket->waitForReadyRead(timeout))
32 | {
33 | qDebug(localSocket->errorString().toLatin1());
34 | return;
35 | }
36 |
37 | QByteArray byteArray = localSocket->readAll();
38 | QString message = QString::fromUtf8(byteArray.constData());
39 | emit sigMsgAvailable(message);
40 | localSocket->disconnectFromServer();
41 | //qDebug()<<"receive message:"<
6 | #include
7 | #include
8 |
9 | class SingleApp : public QApplication{
10 | Q_OBJECT
11 | public:
12 |
13 | SingleApp(int &argc, char *argv[], const QString uniqueKey);
14 | bool isRunning();
15 | bool sendMessage(const QString &message);
16 |
17 | public slots:
18 | void receiveMessage();
19 |
20 | signals:
21 | void sigMsgAvailable(QString message);
22 | private:
23 | static const int timeout = 1000;
24 |
25 | bool _isRunning;
26 | QString _uniqueKey;
27 | QSharedMemory _sharedMemory;
28 | QLocalServer * _localServer;
29 |
30 | };
31 | #endif // SINGLEAPP_H
32 |
--------------------------------------------------------------------------------
/songinfo.h:
--------------------------------------------------------------------------------
1 | #ifndef SONG_INFO_H
2 | #define SONG_INFO_H
3 |
4 | #include
5 | #include
6 |
7 | class SongResult
8 | {
9 | public:
10 | SongResult(){}
11 | ~SongResult(){}
12 |
13 | void set_songid(QString songid){
14 | _songid = songid;
15 | }
16 | QString get_songid(){
17 | return _songid;
18 | }
19 | void set_songname(QString songname){
20 | _songname = songname;
21 | }
22 | QString get_songname(){
23 | return _songname;
24 | }
25 | void set_has_mv(int has_mv){
26 | _has_mv = has_mv;
27 | }
28 | int get_has_mv(){
29 | return _has_mv;
30 | }
31 | void set_yyr_artist(int yyr_artist){
32 | _yyr_artist = yyr_artist;
33 | }
34 | int get_yyr_artist(){
35 | return _yyr_artist;
36 | }
37 | void set_artistname(QString artistname){
38 | _artistname = artistname;
39 | }
40 | QString get_artistname(){
41 | return _artistname;
42 | }
43 | private:
44 | QString _songid;
45 | QString _songname;
46 | QString _encrypted_songid;
47 | int _has_mv;
48 | int _yyr_artist;
49 | QString _artistname;
50 | };
51 |
52 | class AlbumInfo
53 | {
54 | public:
55 | AlbumInfo(){}
56 | ~AlbumInfo(){}
57 |
58 | void set_albumid(QString albumid){
59 | _albumid = albumid;
60 | }
61 | QString get_albumid(){
62 | return _albumid;
63 | }
64 | void set_albumname(QString albumname){
65 | _albumname = albumname;
66 | }
67 | QString get_albumname(){
68 | return _albumname;
69 | }
70 | void set_artistname(QString artistname){
71 | _artistname = artistname;
72 | }
73 | QString get_artistname(){
74 | return _artistname;
75 | }
76 | void set_artistpic(QString artistpic){
77 | _artistpic = artistpic;
78 | }
79 | QString get_artistpic(){
80 | return _artistpic;
81 | }
82 | private:
83 | QString _albumid;
84 | QString _albumname;
85 | QString _artistname;
86 | QString _artistpic;
87 | };
88 |
89 | class SongInfo
90 | {
91 | public:
92 | SongInfo(){}
93 | ~SongInfo(){}
94 |
95 | void set_order(QString order){
96 | _order = order;
97 | }
98 | QString get_order(){
99 | return _order;
100 | }
101 | void set_error_code(QString error_code){
102 | _error_code = error_code;
103 | }
104 | QString get_error_code(){
105 | return _error_code;
106 | }
107 | void set_song_results(QList song_results){
108 | _song_results = song_results;
109 | }
110 | QList get_song_results(){
111 | return _song_results;
112 | }
113 | void set_album_infos(QList album_infos){
114 | _album_infos = album_infos;
115 | }
116 | QList get_album_infos(){
117 | return _album_infos;
118 | }
119 | private:
120 | QString _order;
121 | QString _error_code;
122 |
123 | QList _song_results;
124 | QList _album_infos;
125 | };
126 |
127 | class SongList;
128 | class SongLink;
129 |
130 | class SongData
131 | {
132 | public:
133 | SongData(){}
134 | ~SongData(){}
135 |
136 | void set_xcode(QString xcode){
137 | _xcode = xcode;
138 | }
139 | QString get_xcode(){
140 | return _xcode;
141 | }
142 | void set_song_lists(QList song_lists){
143 | _song_lists = song_lists;
144 | }
145 | QList get_song_lists(){
146 | return _song_lists;
147 | }
148 | private:
149 | QString _xcode;
150 | QList _song_lists;
151 | };
152 |
153 | class SongList{
154 | public:
155 | SongList(){}
156 | ~SongList(){}
157 |
158 | void set_songpic_radio(QString songpic_radio){
159 | _songpic_radio = songpic_radio;
160 | }
161 |
162 | QString get_songpic_radio(){
163 | return _songpic_radio;
164 | }
165 |
166 | void set_lrclink(QString lrclink){
167 | _lrclick = lrclink;
168 | }
169 |
170 | QString get_lrclick(){
171 | return _lrclick;
172 | }
173 |
174 | private:
175 | QString _queryid;
176 | QString _songid;
177 | QString _songname;
178 | QString _artistid;
179 | QString _artistname;
180 | QString _albumid;
181 | QString _songpic_small;
182 | QString _songpic_big;
183 | QString _songpic_radio;//
184 | QString _lrclick;//
185 | QString _version;
186 | QString _copytype;
187 | QString _time;
188 | QString _linkcode;
189 | QString _songlink;
190 | QString _format;
191 | QString _rate;
192 | QString _size;
193 | QString _relatestatus;
194 | QString _resourcetype;
195 |
196 | };
197 |
198 | class SongLink{
199 | public:
200 | SongLink(){}
201 | ~SongLink(){}
202 |
203 | void set_errorcode(QString errorcode){
204 | _errorcode = errorcode;
205 | }
206 | QString get_errorcode(){
207 | return _errorcode;
208 | }
209 | void set_song_data(SongData sdata){
210 | _song_datas = sdata;
211 | }
212 | SongData get_song_data(){
213 | return _song_datas;
214 | }
215 |
216 | private:
217 |
218 | QString _errorcode;
219 | SongData _song_datas;
220 |
221 | };
222 |
223 | #endif //SONG_INFO_H
224 |
--------------------------------------------------------------------------------