如何同步制作QSound?

时间:2017-07-15 13:42:58

标签: c++ qt audio exit

如何同步制作QSound?

我有一个退出按钮。如果我点击它我想播放声音,然后退出程序。 QSound是异步的,我不知道如何同步它。

1 个答案:

答案 0 :(得分:2)

你真的不需要同步播放声音。任何可能阻止GUI线程超过0.10秒的事情都不应该在那里完成,看看here以获取更多信息。

由于您愿意在用户点击退出按钮时发出声音,我认为使用QSoundEffect更适合您的情况,来自docs

  

此类允许您以通常较低延迟的方式播放未压缩的音频文件(通常为WAV文件),适合响应用户操作的“反馈”类型声音(例如虚拟键盘声音)弹出对话框或游戏声音的正面或负面反馈。

QSoundEffect有一个信号playingChanged(),只有在声音播放完毕后才能用来关闭应用程序。我不知道为什么QSound没有类似的信号。

这是一个解释如何完成的最小例子:

#include <QtWidgets>
#include <QtMultimedia>

class Widget : public QWidget {
public:
    explicit Widget(QWidget* parent= nullptr):QWidget(parent) {
        //set up layout
        layout.addWidget(&exitButton);
        //initialize sound effect with a sound file
        exitSoundEffect.setSource(QUrl::fromLocalFile("soundfile.wav"));
        //play sound effect when Exit is pressed
        connect(&exitButton, &QPushButton::clicked, &exitSoundEffect, &QSoundEffect::play);
        //close the widget when the sound effect finishes playing
        connect(&exitSoundEffect, &QSoundEffect::playingChanged, this, [this]{
            if(!exitSoundEffect.isPlaying()) close();
        });
    }
    ~Widget() = default;
private:
    QVBoxLayout layout{this};
    QPushButton exitButton{"Exit"};
    QSoundEffect exitSoundEffect;
};

//sample application
int main(int argc, char* argv[]){
    QApplication a(argc, argv);

    Widget w;
    w.show();

    return a.exec();
}

请注意,上述解决方案在声音效果播放完毕之前不会关闭窗口。

对应用程序用户来说似乎更敏感的另一种方法是关闭窗口,在窗口关闭时播放声音,然后在完成播放时退出应用程序。但这需要在应用程序级别(quitOnLastWindowClosed)关闭最后一个窗口时禁用隐式退出。

由于禁用隐式退出,您必须在程序的每个可能的退出路径上添加qApp->quit();。以下是显示第二种方法的示例:

#include <QtWidgets>
#include <QtMultimedia>

class Widget : public QWidget {
public:
    explicit Widget(QWidget* parent= nullptr):QWidget(parent) {
        //set up layout
        layout.addWidget(&exitButton);
        //initialize sound effect with a sound file
        exitSoundEffect.setSource(QUrl::fromLocalFile("soundfile.wav"));
        //play sound effect and close widget when exit button is pressed
        connect(&exitButton, &QPushButton::clicked, &exitSoundEffect, &QSoundEffect::play);
        connect(&exitButton, &QPushButton::clicked, this, &Widget::close);
        //quit application when the sound effect finishes playing
        connect(&exitSoundEffect, &QSoundEffect::playingChanged, this, [this]{
            if(!exitSoundEffect.isPlaying()) qApp->quit();
        });
    }
    ~Widget() = default;
private:
    QVBoxLayout layout{this};
    QPushButton exitButton{"Exit"};
    QSoundEffect exitSoundEffect;
};

//sample application
int main(int argc, char* argv[]){
    QApplication a(argc, argv);
    //disable implicit quit when last window is closed
    a.setQuitOnLastWindowClosed(false);

    Widget w;
    w.show();

    return a.exec();
}