Запустить фононный плеер в другой ветке?

У меня есть Phonon.MediaObject который подключен к веб-источнику через Phonon.AudioOutput, Поэтому при запуске play()основной графический интерфейс останавливается до тех пор, пока игрок не начнет играть (в худшем случае 5 секунд).

Это можно исправить перемещением плеера или, по крайней мере, его задачей по извлечению из Интернета. Я читал в Интернете о moveToThread() функция, но это не похоже на работу.

Я попытался создать поток из этого, но без удачи: http://pastebin.com/1iXdQD8Y (написанный на PyQt)

Есть идеи?

3 ответа

Решение

Это потребует немного больше кодирования на вашей стороне.

Я не очень хорошо знаю 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() слот, и испустить его, когда это необходимо.

Ты пытался QtConcurrent::run? Он запускает функцию в отдельном потоке.

http://qt-project.org/doc/qt-4.8/qtconcurrentrun.html или проверьте его здесь https://stackru.com/search?q=QtConcurrent%3A%3Arun

Подкласс QThread, переопределение run() с вещами, которые вы хотите, чтобы происходить в вашей теме, а затем создайте экземпляр своей темы и вызовите start() в теме.

Просто будьте осторожны, когда вы подключаетесь к вещам в вашем потоке или из вашего потока, потому что вы не хотите делать прямое или автоматическое соединение, вы хотите сделать соединение с очередями в большинстве случаев.

Эта ссылка показывает два способа использования QThreadодин, как я только что описал, и он ссылается на другой пример потребителя производителя с помощью moveToThread(),

Как правильно реализовать QThread... (пример, пожалуйста...)

Надеюсь, это поможет.

Другие вопросы по тегам