Запустить фононный плеер в другой ветке?
У меня есть 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... (пример, пожалуйста...)
Надеюсь, это поможет.