Qt MediaPlayer按键触发音乐仅首次生效问题求助
按键触发音乐播放仅首次有效问题排查与解决
希望实现用户按键时播放音乐的功能,但目前仅第一次按键时音乐能正常播放,后续按键无法触发播放,请求技术帮助。
用户提供的代码如下:
#include <QApplication> #include <QGraphicsView> #include <QMediaPlayer> #include <QAudioOutput> #include <QGraphicsRectItem> #include <QGraphicsScene> #include <QKeyEvent> #include <QDebug> class Rect : public QGraphicsRectItem { public: Rect() { player = new QMediaPlayer(); output = new QAudioOutput(); player->setAudioOutput(output); output->setVolume(50); player->setSource(QUrl("qrc:/sounds/gun.mp3")); player->play(); } void keyPressEvent(QKeyEvent* ev) { player->play(); } private: QMediaPlayer* player; QAudioOutput* output; }; int main(int argc, char *argv[]) { QApplication a(argc, argv); QGraphicsScene* scene= new QGraphicsScene(); Rect* rect = new Rect(); rect->setFlags(QGraphicsItem::ItemIsFocusable); rect->setFocus(); rect->setRect(0, 0, 300, 400); scene->addItem(rect); QGraphicsView* view = new QGraphicsView(scene); view->show(); return a.exec(); delete view; delete scene; delete rect; }
问题原因
QMediaPlayer播放完音频后会停在末尾位置,再次调用play()时若当前位置已到达音频结尾,不会触发重新播放。此外,构造函数中提前调用了play(),首次按键时音频可能尚未播放完毕能正常响应,但后续音频播放结束后,play()调用就不再生效。
解决方法
核心修复
每次按键触发播放前,将QMediaPlayer的播放位置重置到开头,确保每次按键都从音频起始点播放:
player->setPosition(0); player->play();
额外优化
- 内存泄漏修复:添加析构函数释放QMediaPlayer和QAudioOutput实例,避免内存泄漏。
- 资源释放顺序调整:原代码中
delete语句位于return a.exec();之后,永远不会执行,需调整到exec()调用之后。
修改后的完整代码
#include <QApplication> #include <QGraphicsView> #include <QMediaPlayer> #include <QAudioOutput> #include <QGraphicsRectItem> #include <QGraphicsScene> #include <QKeyEvent> #include <QDebug> class Rect : public QGraphicsRectItem { public: Rect() { player = new QMediaPlayer(); output = new QAudioOutput(); player->setAudioOutput(output); output->setVolume(50); player->setSource(QUrl("qrc:/sounds/gun.mp3")); // 若不需要构造时自动播放,可删除下面这行 // player->play(); } void keyPressEvent(QKeyEvent* ev) { // 重置播放位置到音频开头 player->setPosition(0); // 触发播放 player->play(); } // 析构函数释放资源 ~Rect() { delete player; delete output; } private: QMediaPlayer* player; QAudioOutput* output; }; int main(int argc, char *argv[]) { QApplication a(argc, argv); QGraphicsScene* scene= new QGraphicsScene(); Rect* rect = new Rect(); rect->setFlags(QGraphicsItem::ItemIsFocusable); rect->setFocus(); rect->setRect(0, 0, 300, 400); scene->addItem(rect); QGraphicsView* view = new QGraphicsView(scene); view->show(); int appResult = a.exec(); // 按正确顺序释放资源 delete rect; delete scene; delete view; return appResult; }
内容的提问来源于stack exchange,提问作者Bobr
相关产品推荐
相关产品推荐

