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

Posted

技术标签:

【中文标题】如何从 Qt 中的资源文件中重复/循环声音?【英文标题】:How to repetitive / looping Sound from Resource file in Qt? 【发布时间】:2015-01-10 16:49:43 【问题描述】:

有没有什么简单的方法可以在 Qt 中播放 Resource 文件中的重复/循环声音?

对于单音播放,我使用它并且效果很好:

QSound::play(":/Sounds/swoop.wav");

(WORKS)

但这不是:

QSound sound(":/Sounds/swoop.wav");
sound.play();

(DOES NOT WORK)

甚至这个:

QSound sound (":/Sounds/swoop.wav");
sound.setLoops(QSound::Infinite);
sound.play();

(DOES NOT WORK)

我认为我应该使用 QSoundEffect 类:

QSoundEffect effect;
effect.setSource(":/Sounds/swoop.wav");
effect.setLoopCount(QSoundEffect::Infinite);
effect.setVolume(0.25f);
effect.play();

但是 QSoundEffect 类不适用于我必须使用的资源文件。 我试图找到使用 QFile 的方法,但没有成功。 我使用 Qt 5.3.1 有什么想法吗?

【问题讨论】:

请提供完整的功能/方法,或者最好是完整的MSVC。 另外,要使用 C++ 编写代码,您需要了解变量和对象的生命周期。否则你将很难理解任何 C++ 代码。 使用 QSoundEffect 您必须使用“qrc:/Sounds/swoop.wav”而不是“:/Sounds/swoop.wav”才能使其与资源一起使用。我只是用这个把头撞在墙上。 【参考方案1】:

很难从这个有限的代码片段中猜到,但您确定创建的QSound 的寿命足够长吗?毕竟QSound::~QSound 调用QSound::stop

编辑:

有 3 种使用 QSound 的方法,让我们看看所有这些方法的实际效果:

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QtDebug>
#include <QSound>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)

    ui->setupUi(this);
    connect(ui->pushButton,SIGNAL(clicked()), this, SLOT(first()));
    connect(ui->pushButton_2,SIGNAL(clicked()), this, SLOT(second()));
    connect(ui->pushButton_3,SIGNAL(clicked()), this, SLOT(third()));



MainWindow::~MainWindow()

    delete ui;


void MainWindow::first()

    const QString path = ui->lineEdit->text();
    qDebug() << __PRETTY_FUNCTION__ << ": " << path;
    QSound sound(path);
    sound.play();

MainWindow::first 的问题在于,在创建 sound 对象并调用其方法 play 之后,它被销毁(超出范围)。由于在析构函数中调用了QSound,因此很可能没有机会播放声音的任何部分。

void MainWindow::third()

    const QString path = ui->lineEdit->text();
    qDebug() << __PRETTY_FUNCTION__ << ": " << path;
    QSound* sound = new QSound(path);
    sound->play();

这样你会播放你的声音,但存在内存泄漏,所以你需要添加某种形式的内存管理来销毁sound对象声音播放完毕后。如果您转到QSound 源,您将看到有一个名为deleteOnComplete 的插槽。不幸的是,它是私人的,所以你自己在这里。

void MainWindow::second()

    const QString path = ui->lineEdit->text();
    qDebug() << __PRETTY_FUNCTION__ << ": " << path;
    QSound::play(path);

最后一种情况是使用静态play函数。这也是最简单的方法。如果您检查它是如何实现的,它会使用我之前提到的私有插槽并将其连接到来自私有QSoundEffect 实例数据成员的信号。您可以找到工作示例here。

因此,如果您想使用 QSound 播放声音,这是您的选择。如果你想使用QSoundEffect,在QSound::QSound 中有很好的example 如何构造QSoundEffect 以便它使用资源。

【讨论】:

它们不是sn-ps,这是我自己的方法“void MainWindow::PlaySound()”的内容无论如何主要问题是,如何在代码中的任何位置执行此操作。我发现 QSound 类不是很推荐,所以我尝试使用 QSoundEffect @TomaszKlak 这就是您的方法中的全部内容,那么我所写的是真实的-您的实例sound 将在退出该方法后立即被销毁,您很可能听不到任何声音。在堆上分配该对象并稍后将其删除将解决您的问题。 你知道,我是初学者,这并没有告诉我太多,代码会更好。你能给我举个例子吗? @TomaszKlak @OndřejKrál 那些 sn-ps。如果你将它们保存在 .cpp 文件中并尝试构建,你会得到编译器错误,毕竟...... 感谢您的更正,因为这正是这里的重点。 @hyde

以上是关于如何从 Qt 中的资源文件中重复/循环声音?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Qt 资源中打包图片以便从静态 HTML 资源访问

官方认可的从 Qt5.x 下的资源播放音频的方式

如何获取存储在 .qrc Qt 资源文件中的文件列表?

资源文件中的 Qt 图标不显示

从 Qt Designer 上的不同项目中读取“资源”文件

[UE4]声音系统概述