在另一个线程中启动声子播放器?

时间:2013-02-22 22:26:36

标签: qt pyqt phonon

我有Phonon.MediaObject通过Phonon.AudioOutput连接到网络来源。因此,当运行play()时,主GUI会冻结,直到播放器开始播放(最坏情况下为5秒)。

这可以通过移动播放器来修复,或者至少是它的网络抓取任务。我在网上看过有关moveToThread()功能的内容,但似乎没有用。

我尝试了一个线程,但没有运气:http://pastebin.com/1iXdQD8Y(用PyQt编写)

有什么想法吗?

3 个答案:

答案 0 :(得分:1)

这需要您提供更多编码。

我不太了解python,但是从查看你的代码我认为你犯的一个错误是假设你的PhononThread类生活在它自己的线程中,但它实际上生活在已创建它的线程。

我甚至不会尝试在线程之间移动MediaObject之类的对象。一种方法是创建自己的QObject后代,然后在它的构造函数中创建播放音乐所需的所有对象。您还需要在类中添加插槽以访问需要从主线程调用的每个声子函数。请记住在没有父对象的情况下创建此对象。 然后,您需要将其移动到新创建的QThread并连接线程之间的所有信号/插槽。

我不使用python,但这里是伪C ++概述它应该是什么样的:

class MyPlayer: public QObject{
    Q_OBJECT

public:

    AudioOutput* ao;
    MediaObject* mo;

    MyPlayer() : QObject(0) {    // note no parent QObject instance
        ao = new AudioOutput();
        ... // Create and connect all objects
    }

public slots:

    void setCurrentSource ( const MediaSource & source ){
        mo->setCurrentSource(source);
    }
    // And other methods that are not slots already.
};

然后在您的应用程序中执行:

MyPlayer* mp = new MyPlayer();
QThread* th = new QThread();

connect(th, SIGNAL(finished()), mp, SLOT(deleteLater()));

connect( mainThreadObj, SIGNAL(setPlayerSource ( const MediaSource & ) ), mp, SLOT(setPlayerSource ( const MediaSource & ) ) );
... // and other signals; note that methods that are signals already can be conected witout wrappers:
connect( mainThreadObj, SIGNAL(playerPlay() ), mp->mo, SLOT(play()) );

mp->moveToThread(th);

要停止线程,只需将主线程中的信号连接到quit()插槽,然后在需要时发出。

答案 1 :(得分:0)

子类QThread,重新实现run()包含您想要在线程中发生的内容,然后创建线程的实例并在其上调用start()

当你连接线程或线程中的东西时要小心,因为你不想进行直接或自动连接,你想在大多数情况下进行排队连接。

此链接显示了两种使用QThread的方法,一种如我刚才所述,并使用moveToThread()链接到另一个生产者消费者示例。

what is the correct way to implement a QThread... (example please...)

希望有所帮助。

答案 2 :(得分:0)

你试过QtConcurrent::run吗?它在一个单独的线程中运行函数。

http://qt-project.org/doc/qt-4.8/qtconcurrentrun.html#run 或者在这里查看https://stackoverflow.com/search?q=QtConcurrent%3A%3Arun