Question

I have a Phonon.MediaObject that is connected to a web source through Phonon.AudioOutput. Therefore, when running play(), the main GUI freezes until the player starts playing (5 seconds at worst case).

This could be fixed by moving the player, or at least it's web fetching task. I've read online about moveToThread() function, but it doesn't seem to work.

I tried making a thread out of it, but without luck: http://pastebin.com/1iXdQD8Y (written in PyQt)

Any ideas?

Was it helpful?

Solution

This will require a bit more coding on your side.

I don't know python all that well, but from looking at your code I think that one mistake you are making is to assume that your PhononThread class is living in it's own thread, but it's actually living in thread in which it has been created.

I wouldn't even try to move objects like MediaObject between threads. One way to do it would be to create your own QObject descendant, then in it's constructor create all objects that you will need to play music. You will also need to add slots to your class to access every phonon function you will need to call from main thread. REMEMBER to create this object WITHOUT parent object. Then you need to move it to newly created QThread and connect all signals/slots between threads.

I don't use python, but here is pseudo-C++ outline of how it should look like:

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.
};

Then in your application you do:

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);

For stopping your thread, just connect signal from your main thread to th's quit() slot, and emit it when needed.

OTHER TIPS

Subclass QThread, reimplement run() with the stuff you want to happen in your thread, and then create an instance of your thread and call start() on it.

Just be careful about when you connect to things in your thread or from your thread, because you don't want to do a direct or auto connection, you want to do a queued connection in most cases.

This link shows two ways to use QThread, one as I just described, and it links to another producer consumer example using moveToThread().

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

Hope that helps.

Have you tried QtConcurrent::run? It runs function in a separate thread.

http://qt-project.org/doc/qt-4.8/qtconcurrentrun.html#run or check it here https://stackoverflow.com/search?q=QtConcurrent%3A%3Arun

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top