0 程序界面布局
主要包含自定义标题栏 TitleBar、自定义播放器 PlayControlBar、自定义侧边栏 SideBar 和 主窗口界面 MusicPlayer。
同时还自定义了进度条 Slider 以及弹出音量调节器 VolumePopup。
目前大致的整体界面:

😭😭😭界面暂时还比较丑!
1 标题栏信号与槽

1.1 标题栏最大化/最小化窗口按钮信号与槽设计
这部分功能在创建的主窗口类 MusicPlayer 中包含以下信号与槽连接:
1 2
| connect(ui->titleBar, &TitleBar::minimizeClicked, this, &MusicPlayer::onMinimizeClicked); connect(ui->titleBar, &TitleBar::maximizeClicked, this, &MusicPlayer::onMaximizeClicked);
|
titleBar 是一个自定义 TitleBar 类,父类是 QWidget,类中设置了自定义信号:
1 2 3
| signals: void minimizeClicked(); void maximizeClicked();
|
这 2 个自定义信号通过点击 titleBar 中的 btnMinimize 和 btnMaximize 发出。在 TitleBar 自定义类中的信号与槽连接设计为:
1 2
| connect(ui->btnMinimize, &QPushButton::clicked, this, &TitleBar::onMinimizeClicked); connect(ui->btnMaximize, &QPushButton::clicked, this, &TitleBar::onMaximizeClicked);
|
涉及的槽函数为:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| void TitleBar::onMinimizeClicked() { emit minimizeClicked(); }
void TitleBar::onMaximizeClicked() { emit maximizeClicked(); }
void TitleBar::setMaximized(bool maximized) { if (maximized) { ui->btnMaximize->setText("❐"); } else { ui->btnMaximize->setText("□"); } }
|
当点击 btnMinimize 时,会调用 TitleBar::onMinimizeClicked 函数,进而由 titleBar 发出自定义信号 minimizeClicked()。然后主窗口类 MusicPlayer 接收到该信号,会调用 MusicPlayer::onMinimizeClicked 函数,实现窗口的最小化。
对应的 MusicPlayer::onMinimizeClicked 处理函数如下:
1 2 3 4
| void MusicPlayer::onMinimizeClicked() { showMinimized(); }
|
类似的逻辑,主窗口类 MusicPlayer 接收到 titleBar 发出自定义信号 maximizeClicked(),会调用 MusicPlayer::onMaximizeClicked 函数,实现窗口的最大化。
对应的 MusicPlayer::onMaximizeClicked 处理函数如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| void MusicPlayer::onMaximizeClicked() { if (m_isMaximized) { setGeometry(m_normalGeometry); m_isMaximized = false; ui->titleBar->setMaximized(false); } else { m_normalGeometry = geometry();
QScreen *screen = QGuiApplication::primaryScreen(); QRect availableGeometry = screen->availableGeometry(); setGeometry(availableGeometry);
m_isMaximized = true; ui->titleBar->setMaximized(true); } }
|
m_isMaximized 是 MusicPlayer 的成员变量,用于判断当前窗口是否已经处于最大化;
m_normalGeometry 是 MusicPlayer 中用于记录窗口大小的变量。
ui->titleBar->setMaximized(bool); 是调用 TitleBar 类的最大化按钮图标更改函数。
- 当参数为
true 时,说明窗口被最大化,图标被改为 ❐;
- 当参数为
false 时,说明窗口不是最大化状态,图标被改为 □。
1.2 标题栏关闭窗口、双击按钮信号与槽设计
这部分功能在创建的主窗口类 MusicPlayer 中包含以下信号与槽连接:
1 2
| connect(ui->titleBar, &TitleBar::closeClicked, this, &MusicPlayer::onCloseClicked); connect(ui->titleBar, &TitleBar::doubleClicked, this, &MusicPlayer::onMaximizeClicked);
|
TitleBar::closeClicked 和 TitleBar::doubleClicked 是自定义 TitleBar 类的自定义信号,分别通过点击 titleBar 中的 btnClose 按钮和双击标题栏区域时发出:
1
| connect(ui->btnClose, &QPushButton::clicked, this, &TitleBar::onCloseClicked);
|
1 2 3 4
| void TitleBar::onCloseClicked() { emit closeClicked(); }
|
重写一下 mouseDoubleClickEvent 事件,使其在鼠标左键双击当前组件(标题栏)时,可以发出自定义 doubleClicked() 信号,进而实现双击标题栏来回切换窗口最大化和非最大化状态:
1 2 3 4 5 6 7
| void TitleBar::mouseDoubleClickEvent(QMouseEvent *event) { if (event->button() == Qt::LeftButton) { emit doubleClicked(); } QWidget::mouseDoubleClickEvent(event); }
|
2 添加音乐信号与槽
2.1 导入文件夹

在窗口类 MusicPlayer 中,有一个 btnImportFolder 按钮,用于导入文件夹中所有的音频文件。相关信号与槽连接如下:
1
| connect(ui->btnImportFolder, &QPushButton::clicked, this, &MusicPlayer::onImportFolder);
|
调用的槽函数 MusicPlayer::onImportFolder:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| void MusicPlayer::onImportFolder() { QString folderPath = QFileDialog::getExistingDirectory( this, "选择音乐文件夹", "", QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks ); if (!folderPath.isEmpty()) { QDir dir(folderPath); dir.setSorting(QDir::Name); QStringList filters; filters << "*.mp3" << "*.wav" << "*.flac" << "*.ogg" << "*.m4a" << "*.aac" << "*.wma" << "*.opus"; QStringList files = dir.entryList(filters, QDir::Files); m_playlist.clear(); for (const QString &fileName : files) { m_playlist.append(dir.absoluteFilePath(fileName)); } if (!m_playlist.isEmpty()) { m_currentIndex = 0; QList<MusicInfo> list; for (const QString &path : m_playlist) { list.append(MusicListModel::fromFilePath(path)); } ui->musicListView->setMusicList(list); m_metadataLoader->loadMetadataForFiles(m_playlist); loadAndPlayMusic(m_playlist.at(m_currentIndex)); } } }
|
当点击这个按钮时,会弹出一个选择文件夹的窗口,并过滤 .mp3、.wav 等格式的音频文件。在 MusicPlayer 类中,有一个 QStringList 类型的 m_playerlist 列表,用于临时存储加载的音乐列表。这些经过过滤的音频文件路径被加入到 m_playerlist 中。
ui->musicListView->setMusicList(list); // 设置音乐列表
m_metadataLoader->loadMetadataForFiles(m_playlist);
这部分是有关音乐列表和音乐元数据显示的,后续有解析
m_currentIndex 用于记录播放的索引(播放到第几首音乐)。
当加载完音乐数据后,会调用 loadAndPlayMusic 播放加载的第一首音乐。loadAndPlayMusic 函数如下:
1 2 3 4 5
| void MusicPlayer::loadAndPlayMusic(const QString &filePath) { m_player->setMedia(QMediaContent(QUrl::fromLocalFile(filePath))); m_player->play(); }
|
loadAndPlayMusic 函数会加载指定路径 filePath 的音乐文件音频数据,然后开始播放。
2.2 添加音乐

添加音乐其实和导入音乐文件夹差不多,区别在于加载的是打开的文件。可以批量选择一些文件打开加载到音乐列表中。
在窗口类中相关信号与槽连接:
1
| connect(ui->btnImportFiles, &QPushButton::clicked, this, &MusicPlayer::onImportFiles);
|
MusicPlayer::onImportFiles 函数如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| void MusicPlayer::onImportFiles() { QStringList fileNames = QFileDialog::getOpenFileNames( this, "选择音频文件", "", "音频文件 (*.mp3 *.wav *.flac *.ogg *.m4a *.aac *.wma *.opus);;MP3 文件 (*.mp3);;WAV 文件 (*.wav);;FLAC 文件 (*.flac);;所有文件 (*)" ); if (!fileNames.isEmpty()) { m_playlist = fileNames; m_currentIndex = 0; QList<MusicInfo> list; for (const QString &path : m_playlist) { list.append(MusicListModel::fromFilePath(path)); } ui->musicListView->setMusicList(list); m_metadataLoader->loadMetadataForFiles(m_playlist); loadAndPlayMusic(m_playlist.at(m_currentIndex)); } }
|
3 播放控制栏信号与槽
3.1 音乐的播放和暂停

这部分功能在窗口类 MusicPlayer 中包含如下信号与槽链接:
1 2 3 4 5 6 7
| connect(ui->playControlBar, &PlayControlBar::playPauseClicked, this, [this](){ if(m_player->state() == QMediaPlayer::PlayingState){ m_player->pause(); }else{ m_player->play(); } });
|
m_player 是创建的窗口类中一个 QMediaPlayer 类型的播放器成员变量,用于加载音频,进行音频的播放。
playControlBar 是一个自定义 PlayControlBar 类。PlayControlBar::playPauseClicked 信号在点击 playControlBar 中的 btnPlayPause 按钮时发出。
在 PlayControlBar 中相关的信号与槽连接如下:
1
| connect(ui->btnPlayPause, &QPushButton::clicked, this, &PlayControlBar::onPlayPauseClicked);
|
1 2 3 4
| void PlayControlBar::onPlayPauseClicked() { emit playPauseClicked(); }
|
当点击这个播放控制栏中的 btnPlayPause 按钮时,会发出 QPushButton::clicked 信号,然后当前播放控制栏会调用 PlayControlBar::onPlayPauseClicked() 函数。这个函数的行为就是发出自定义 PlayControlBar::playPauseClicked 信号。
上述这些信号与槽连接实现了点击 播放控制栏中的 btnPlayPause 按钮 来控制播放器 播放状态 和 暂停状态的切换。
在 PlayControlBar 类中,还有一个用于切换 btnPlayPause 按钮图标的函数。当播放器 m_player 处于播放状态时,点击按钮后需要播放器暂停,此时需要切换成暂停的图标;反之亦然。
用于切换 btnPlayPause 按钮图标的成员函数 PlayControlBar::updatePlayState 如下:
1 2 3 4 5 6 7 8 9
| void PlayControlBar::updatePlayState(bool isPlaying) { if (isPlaying) { ui->btnPlayPause->setIcon(QIcon(":/icons/play.svg")); } else { ui->btnPlayPause->setIcon(QIcon(":/icons/pause.svg")); } }
|
在窗口的 m_player 成员发生状态变化时,需要调用函数以切换 playControlBar 中的 btnPlayPause 按钮的图标。涉及的信号与槽连接如下:
1 2 3 4
| connect(m_player, &QMediaPlayer::stateChanged, this, [this](QMediaPlayer::State state){ ui->playControlBar->updatePlayState(state == QMediaPlayer::PlayingState); ui->musicListView->setCurrentPlaying(m_currentIndex, state == QMediaPlayer::PlayingState); });
|
ui->musicListView->setCurrentPlaying(m_currentIndex, state == QMediaPlayer::PlayingState); 是和音乐列表相关的内容,后续会有解析。
窗口的 m_player 成员发生状态变化发出 QMediaPlayer::stateChanged 信号,携带一个 QMediaPlayer::State 类型的状态参数,然后调用 playControlBar 的 updatePlayState 成员函数,以切换播放控制栏中的播放按钮图标。
3.2 播放模式的切换

在 playControlBar 中有一个切换播放模式的按钮 btnPlayMode,可以切换三种播放模式,包括 顺序播放(默认)、随机播放 和 单曲循环。对应的信号与槽连接如下:
1
| connect(ui->btnPlayMode, &QPushButton::clicked, this, &PlayControlBar::onPlayModeClicked);
|
点击按钮会调用函数 PlayControlBar::onPlayModeClicked,该函数会发出自定义信号:
1 2 3 4
| void PlayControlBar::onPlayModeClicked() { emit playModeClicked(); }
|
playControlBar 发出的自定义信号被主窗口接收,并调用对应的播放模式切换函数:
1
| connect(ui->playControlBar, &PlayControlBar::playModeClicked, this, &MusicPlayer::onPlayModeClicked);
|
MusicPlayer::onPlayModeClicked 函数内容如下:
1 2 3 4 5
| void MusicPlayer::onPlayModeClicked() { m_playbackMode = static_cast<PlaybackMode>((m_playbackMode + 1) % 3); updatePlayModeIcon(); }
|
-
m_playbackMode 是 MusicPlayer 类中的 PlaybackMode 类(一个自定义枚举类)成员变量(数值从 0~2);
-
PlaybackMode 自定义枚举类如下:
1 2 3 4 5 6
| enum PlaybackMode { SequentialLoop, SingleLoop, Shuffle };
|
-
updatePlayModeIcon() 用于更新播放模式按钮的图标:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| void MusicPlayer::updatePlayModeIcon() { QIcon icon; QString tooltip; switch (m_playbackMode) { case SequentialLoop: icon = QIcon(":/icons/list_loop.svg"); tooltip = tr("顺序循环"); break; case SingleLoop: icon = QIcon(":/icons/single_loop.svg"); tooltip = tr("单曲循环"); break; case Shuffle: icon = QIcon(":/icons/random.svg"); tooltip = tr("随机播放"); break; } ui->playControlBar->setPlayModeIcon(icon, tooltip); }
|
在该函数中,会先根据 m_playbackMode 判断需要更改的图标和按钮提示是什么样的,然后再调用 playControlBar 的 setPlayModeIcon 成员函数进行更改。
1 2 3 4 5 6 7 8
| void PlayControlBar::setPlayModeIcon(const QIcon &icon, const QString &tooltip) { ui->btnPlayMode->setIcon(icon); ui->btnPlayMode->setIconSize(QSize(20, 20)); if (!tooltip.isEmpty()) { ui->btnPlayMode->setToolTip(tooltip); } }
|
3.3 上一首/下一首音乐

在 PlayControlBar 类中,对应的信号与槽连接如下:
1 2
| connect(ui->btnPrevious, &QPushButton::clicked, this, &PlayControlBar::onPreviousClicked); connect(ui->btnNext, &QPushButton::clicked, this, &PlayControlBar::onNextClicked);
|
当点击播放控制栏中的上一首按钮 btnPrevious / 下一首按钮 btnNext,会调用 PlayControlBar::onPreviousClicked / PlayControlBar::onNextClicked 函数。这两个函数会发出自定义信号,在主窗口 MusicPlayer 中被接收再进行后续的上一首/下一首音乐的处理:
1 2 3 4 5 6 7 8 9
| void PlayControlBar::onPreviousClicked() { emit previousClicked(); }
void PlayControlBar::onNextClicked() { emit nextClicked(); }
|
在 MusicPlayer 类中,对应的信号与槽连接如下:
1 2
| connect(ui->playControlBar, &PlayControlBar::previousClicked, this, &MusicPlayer::playPrevious); connect(ui->playControlBar, &PlayControlBar::nextClicked, this, &MusicPlayer::playNext);
|
MusicPlayer::playPrevious 函数如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| void MusicPlayer::playPrevious() { if (m_playlist.isEmpty()) return;
switch (m_playbackMode) { case SequentialLoop: m_currentIndex--; if (m_currentIndex < 0) m_currentIndex = m_playlist.size() - 1; break; case SingleLoop: m_currentIndex--; if (m_currentIndex < 0) m_currentIndex = m_playlist.size() - 1; break; case Shuffle: if (m_playlist.size() == 1) break; m_currentIndex = QRandomGenerator::global()->bounded(m_playlist.size()); break; } loadAndPlayMusic(m_playlist.at(m_currentIndex)); }
|
- 当播放模式为顺序播放或者单曲循环时,通过
m_currentIndex-- 来改变播放的索引;
- 当播放模式为随机播放时,会通过
QRandomGenerator 随机生成一个小于 m_playlist.size() 的索引大小。
最后调用 loadAndPlayMusic 加载对应索引的音乐文件路径并播放音乐。
MusicPlayer::playNext 函数如下,基本思路也是差不多的:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| void MusicPlayer::playNext() { if (m_playlist.isEmpty()) return;
switch (m_playbackMode) { case SequentialLoop: m_currentIndex++; if (m_currentIndex >= m_playlist.size()) m_currentIndex = 0; break; case SingleLoop: m_currentIndex++; if (m_currentIndex >= m_playlist.size()) m_currentIndex = 0; break; case Shuffle: if (m_playlist.size() == 1) break; m_currentIndex = QRandomGenerator::global()->bounded(m_playlist.size()); break; } loadAndPlayMusic(m_playlist.at(m_currentIndex)); }
|
3.4 音量的控制

在播放控制栏 playControlBar 中,有一个按钮 btnVolume。点击这个按钮会弹出一个自定义音量调节弹窗,这个音量调节弹窗是一个自定义 VolumePopup 类的成员,在 playControlBar 构造函数中被初始化:
1 2 3 4
| connect(ui->btnVolume, &QPushButton::clicked, this, &PlayControlBar::onVolumeButtonClicked);
m_volumePopup = new VolumePopup(this);
|
PlayControlBar::onVolumeButtonClicked 函数内容如下:
1 2 3 4 5 6 7
| void PlayControlBar::onVolumeButtonClicked() { if (m_volumePopup) { QPoint pos = ui->btnVolume->mapToGlobal(QPoint(ui->btnVolume->width() / 2, 0)); m_volumePopup->showAt(pos); } }
|
点击 btnVolume 按钮后,会在指定的位置显示这个自定义弹窗。
VolumePopup 类自定义弹窗包含一个按钮 m_btnMute,用于调节是否静音;一个 Slider 类音量调节条 m_slider,用于调节音量。
在 VolumePopup 类中相关的信号与槽连接如下:
1 2 3
| connect(m_btnMute, &QPushButton::toggled, this, &VolumePopup::onMuteToggled); connect(m_slider, &QSlider::valueChanged, this, &VolumePopup::onSliderValueChanged); connect(m_slider, &Slider::sliderClicked, this, &VolumePopup::onVolumeSliderClicked);
|
在这里使用的是 QPushButton::toggled 信号,使得按钮状态发生改变时,就会出发槽函数(而不是用 clicked,只能点击才会触发槽函数)。主要是因为当音量条调节为 0 时,m_btnMute 也需要改变为静音的状态。
VolumePopup::onMuteToggled 函数如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| void VolumePopup::onMuteToggled(bool checked) { if (checked) { m_volumeBeforeMute = m_slider->value(); m_slider->blockSignals(true); m_slider->setValue(0); m_slider->blockSignals(false); m_btnMute->setIcon(QIcon(":/icons/slient.svg")); m_btnMute->setToolTip(tr("取消静音")); emit valueChanged(0); } else { int restore = m_volumeBeforeMute > 0 ? m_volumeBeforeMute : 70; m_slider->blockSignals(true); m_slider->setValue(restore); m_slider->blockSignals(false); m_btnMute->setIcon(QIcon(":/icons/volume.svg")); m_btnMute->setToolTip(tr("静音")); emit valueChanged(restore); } emit muteToggled(checked); }
|
VolumePopup::onMuteToggled 函数会先将 m_volumePopup 内的音量条和静音按钮进行修改,然后发出自定义 valueChanged 和 muteToggled 信号。这些信号在 playControlBar 中被接收:
1 2
| connect(m_volumePopup, &VolumePopup::valueChanged, this, &PlayControlBar::onVolumeChanged); connect(m_volumePopup, &VolumePopup::muteToggled, this, &PlayControlBar::onVolumeMuteToggled);
|
触发的槽函数如下,用于再次发出信号传递给主窗口类:
1 2 3 4 5 6 7 8 9 10 11
| void PlayControlBar::onVolumeMuteToggled(bool muted) { emit volumeMuteToggled(muted); }
void PlayControlBar::onVolumeChanged(int value) { ui->btnVolume->setIcon(value > 0 ? QIcon(":/icons/volume.svg") : QIcon(":/icons/slient.svg")); emit volumeChanged(value); }
|
在主窗口类 MusicPlayer 中接收到这些信号时,对播放器 m_player 进行修改:
1 2 3 4 5 6 7 8
| connect(ui->playControlBar, &PlayControlBar::volumeChanged, this, [this](int volume){ m_player->setVolume(volume); }); connect(ui->playControlBar, &PlayControlBar::volumeMuteToggled, this, [this](bool muted){ if (muted) { m_player->setVolume(0); } });
|

在 VolumePopup 类中有一个 Slider 自定义类(重写了点击轨道事件 「Qt5 开发日记」极简音乐播放 Demo 3.2 点击进度条功能的实现)音量条 m_slider,相关信号与槽连接如下:
1 2
| connect(m_slider, &QSlider::valueChanged, this, &VolumePopup::onSliderValueChanged); connect(m_slider, &Slider::sliderClicked, this, &VolumePopup::onVolumeSliderClicked);
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| void VolumePopup::onSliderValueChanged(int value) { if (value > 0) { m_volumeBeforeMute = value; } updateMuteButtonFromValue(value); emit valueChanged(value); }
void VolumePopup::onVolumeSliderClicked(qint64 value) { int v = qBound(0, static_cast<int>(value), 100); m_slider->blockSignals(true); m_slider->setValue(v); m_slider->blockSignals(false); if (v > 0) { m_volumeBeforeMute = v; } updateMuteButtonFromValue(v); emit valueChanged(v); }
|
音量条被调节后,会发出 VolumePopup 中的自定义 valueChanged 信号,由 playControlBar 接收。
3.5 播放进度条

PlayControlBar 中有一个 progressSlider 音乐进度条,用于调节音乐的播放进度。这个进度条是一个 Slider 类,同样重写了鼠标点击事件,进而能够点击进度条位置实现播放位置的跳转。
在 PlayControlBar 类中的音乐进度条相关信号与槽连接如下:
1 2 3 4 5 6 7 8
| connect(ui->progressSlider, &Slider::sliderClicked, this, &PlayControlBar::onSliderClicked); connect(ui->progressSlider, &QSlider::sliderPressed, this, [this](){ m_sliderPressed = true; }); connect(ui->progressSlider, &QSlider::sliderReleased, this, [this](){ m_sliderPressed = false; emit progressChanged(ui->progressSlider->value()); });
|
connect(ui->progressSlider, &Slider::sliderClicked, this, &PlayControlBar::onSliderClicked); 用于音乐进度条的位置点击跳转;
connect(ui->progressSlider, &QSlider::sliderPressed ... 用于当点住进度条滑块时,将 m_sliderPressed 设置为正在拖拽的状态。(m_sliderPressed 用于判断当前是否正在拖拽进度条滑块)
connect(ui->progressSlider, &QSlider::sliderReleased ... 用于释放进度条滑块时,将 m_sliderPressed 设置为未拖拽的状态,并发出一个自定义信号 progressChanged。这个信号被主窗口 MusicPlayer 接收,然后调节 m_player 播放器的音量。
在 MusicPlayer 中,接收到 PlayControlBar 发出的 自定义信号 progressChanged 时,触发播放器播放位置的修改:
1 2 3
| connect(ui->playControlBar, &PlayControlBar::progressChanged, this, [this](qint64 position){ m_player->setPosition(position); });
|
反过来播放器播放位置的变化也要促成 playControlBar 中进度条的修改。因此,在 MusicPlayer 中需要如下信号与槽连接:
1 2 3 4 5 6 7 8 9 10 11 12 13
| connect(m_player, &QMediaPlayer::durationChanged, this, [this](qint64 duration){ ui->playControlBar->updateDuration(duration); });
connect(m_player, &QMediaPlayer::positionChanged, this, [this](qint64 position){ ui->playControlBar->updateProgress(position); });
connect(m_player, &QMediaPlayer::stateChanged, this, [this](QMediaPlayer::State state){ ui->playControlBar->updatePlayState(state == QMediaPlayer::PlayingState); ui->musicListView->setCurrentPlaying(m_currentIndex, state == QMediaPlayer::PlayingState); });
|
对应的处理函数如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| void PlayControlBar::updateDuration(qint64 duration) { ui->progressSlider->setRange(0, duration); ui->lblTotalTime->setText(formatTime(duration)); ui->lblCurrentTime->setText("0:00"); }
void PlayControlBar::updateProgress(qint64 position) { if (!m_sliderPressed) { ui->progressSlider->blockSignals(true); ui->progressSlider->setValue(position); ui->progressSlider->blockSignals(false); }
ui->lblCurrentTime->setText(formatTime(position)); }
void PlayControlBar::updatePlayState(bool isPlaying) { if (isPlaying) { ui->btnPlayPause->setIcon(QIcon(":/icons/play.svg")); } else { ui->btnPlayPause->setIcon(QIcon(":/icons/pause.svg")); } }
|