QT (C++) 中的简单声音 (.wav) 播放应用程序

Posted

技术标签:

【中文标题】QT (C++) 中的简单声音 (.wav) 播放应用程序【英文标题】:Simple sound (.wav) playing application in QT (C++) 【发布时间】:2012-03-31 18:52:11 【问题描述】:

我是 Qt 新手,正在尝试编写一个可以规划 wav 文件的简单 qt 类。 经过一番阅读和环顾后,我编写了课程,代码如下。代码后有问题

#include <QtGui/QApplication>
#include "playsound.h"
#include <iostream>

using namespace std;

int main(int argc, char *argv[])

     QApplication a(argc, argv);
     playSound w;
     int ch = 2;
     int ready = 1;
     cout<<"ready"<<ready<<endl;
     // w.show();
     w.playwav(ch);
     return a.exec();   

playsound.cpp的源代码

#include "playsound.h"

playSound::playSound(QWidget *parent): QWidget(parent) 

playSound::~playSound() 

void playSound::playwav(int ch)


    switch (ch)
    
        case 1: QSound::play("/home/alok/qtworkspace/sounds/abc.wav"); break;
        case 2: QSound::play("/home/alok/qtworkspace/sounds/xyz.wav"); break;
        case 3: QSound::play("/home/alok/qtworkspace/sounds/abc.wav"); break;
        case 4: QSound::play("/home/alok/qtworkspace/sounds/aaa.wav"); break;
        case 5: QSound::play("/home/alok/qtworkspace/sounds/nnn.wav"); break;
    

问题和疑问:

1)我想在播放声音后关闭应用程序。到目前为止,它说程序正在运行,我必须使用 Qt 创建器中“应用程序输出”区域中的红色按钮强制关闭它。我尝试使用来自 Qwidget 的 close() 和来自 QApplication 的 quit() 但可能我做错了。怎么解决这个问题?

2) 这个功能有更简单的实现吗?你知道一些不涉及事件循环的东西。我试图用老式的 C++ 风格来做,当我需要播放声音并完成它但无法完成时,我会调用一个函数。最欢迎对此提出建议。

谢谢

【问题讨论】:

【参考方案1】:

我可以使用 PyQt4 提供答案(因为我是 python 编码器),但想法是一样的。

1) QSound 是一个非常基础的声音播放界面。它没有任何有用的信号(尽管我认为它确实应该)。为了知道 QSound 何时完成,您必须不断检查其isFinished() 方法。您可以在主线程的循环中执行此操作,或者更高级并创建一个 QThread 来播放您的声音,进入循环,然后在完成时发出自己的自定义信号。 QThread 是首选,因为你不应该阻塞你的主线程。然后,您将能够连接此自定义 soundIsFinished() SIGNAL 来说出您的小部件的 close() SLOT 或任何其他处理程序。

如果您想要更高级的选项,可以使用phonon module,它确实内置了所有这些不同的信号。设置起来有点烦人,但您不需要 QThread。

2) 事件循环是 Qt 功能的核心概念。您的主应用程序始终进入事件循环,以便小部件可以发布其事件并对其进行处理。从技术上讲,您可以在没有事件循环的情况下使用 Qt,但这真的毫无意义,因为您只是在与框架作斗争,并失去了它所能做的一切。

【讨论】:

谢谢!!您能否指出一个简单的 QThread 或 phonon 实现的示例,以方便您并且可能类似于我所解释的内容。同时,我会尝试自己从 Qt 文档中理解一些东西。【参考方案2】:

要退出应用程序,您必须关闭***小部件(如果您的应用程序将属性详细命名为 quitOnLastWindowClosed 设置为 true,但这是默认设置,因此您不必担心)或向您创建的 QCoreApplication 发出退出信号。 在下面的示例中,我采用了简单的方法:发出关闭信号。 正如jdi所说,创建一个Thread会更好,但我明白你只是学习Qt并写了这个作为例子,所以忙着等待isFinished就足够了。下面是一个应该如何进行的示例:

#include "playsound.h"

playSound::playSound(QWidget *parent): QWidget(parent) 

playSound::~playSound() 

void playSound::playwav(int ch)

    QSound *player = 0; // Creates an object so that you can call player.isFinished()
                   // the isFinished function is not static.
    switch (ch)
    
    case 1: player = new QSound("/home/alok/qtworkspace/sounds/abc.wav"); break;
    // other cases
    
    if(!player)
       this->close();

    while(!player->isFinished()); // waits until the player has finished playing
    delete player;
    this->close(); // closes this widget, and
                   // as this Widget has no parent, i.e. it's the "top-level" widget,
                   // it'll close the app.

edit:我很惭愧没有阅读我应该拥有的文档。 QSound 没有默认构造函数,我已经编辑了代码。 一些注意事项:由于这只是一个测试你学习如何使用 Qt,我创建了一个指向 QSound 的指针,然后将其删除。这不是一个好方法,你不应该像我那样玩指针,一个更好的解决方案是只实例化你将使用的对象。必须手动删除东西并不好,最好依靠好的 ol' 堆栈来做到这一点。

【讨论】:

谢谢!我会试试这个,也许还有声子。 令人惊讶的是,这不起作用。我注意到的一件事是 QSound 没有 void 构造函数。考虑到这一点,尽管构建没有问题,但仍然没有声音。如果我将它恢复到早期版本,声音会起作用.... 为什么没有声音?输入数字后应用程序会立即关闭吗? 玩了一段时间后,我得到了声音。我之前的做法导致了范围问题。我在每个案例中都声明了一个 QSound 对象。现在,我包含了一个指向 QSound 对象的指针作为私有成员,在每种情况下使用“new”分配内存,然后调用 play() 函数。现在声音工作正常。但小部件仍在继续运行。我必须使用 qtCreator 中丑陋的 RED 停止按钮强制关闭它 通过我之前的更改,即包含一个指向 QSound 对象的指针作为私有成员,声音可以正常工作。关闭功能仍然无法正常工作。

以上是关于QT (C++) 中的简单声音 (.wav) 播放应用程序的主要内容,如果未能解决你的问题,请参考以下文章

C++如何播放wav声音文件.Linux系统

用 Qt 的 QAudioOutput 类播放 WAV 音频文件

如何从 Qt 中的资源文件中重复/循环声音?

用 Qt 的 QAudioOutput 类播放 WAV 音频文件(使用了libsndfile外部库)

【c++】怎样才能使程序播放文件中的声音?

如何使用 PlaySound() 或任何基本函数/方法在 C++ 中同时播放 1 个以上的 .wav 声音?