0

I am looking for clarification to help me understand Qt multi threading and event loops with Qt 4.8. I would also add I am new to threading in general so that is part of my problem.

My current situation is I have a Qt app that needs to play sounds every so often using QTMultiMedia- QAudioOutput. I have two classes, MainGui and AudioWorker. I wish to call AudioWorker to "play()" a sound quite often.

Apparently QAudioOutput must have an event loop so the process doesn't end before the sound is played, and if this is done in the main class it will hold everything up. So I understand that threads will help.

Now if I understand threading correctly, the spawned thread cannot live longer than the function which created it unless it is detached somehow? So if I receive notification in my MainGui class to play a sound and I spawn a new thread via slot connection which calls play() in AudioWorker, wont the thread with the event loop just die once my MainGui notification function ends? If this is the case what is the point, either way the MainGui would need the event loop?

Surely I am missing something? Do I need to detach the thread somehow?I don't see much in Qt documentation on detaching. This whole process seems excessive just to play a simple sound.


updated

Resolved problem by creating QThread in play() function. Thread is does not prematurely exit until I emit signal.

Found a hidden but great example to follow at: https://nachtimwald.com/2015/05/02/effective-threading-using-qt/

scopchanov
  • 7,966
  • 10
  • 40
  • 68
JavaBeast
  • 766
  • 3
  • 11
  • 28
  • 1
    I think you may be misinterpreting some of the comments in the `Qt` documentation. `QAudioOutput` does need an active event loop to function but it doesn't need its *own* event loop on a dedicated thread. – G.M. Jan 07 '18 at 12:52
  • Hmm then maybe my code is wrong? I currently am looping the sound to play 30 times while the gui is starting up playing 2 second long audio clips each loop. This process is currently preventing my widgets from loading while playing sound. Are you saying i can fix that another way? – JavaBeast Jan 07 '18 at 13:21
  • You need to show your code. – G.M. Jan 07 '18 at 13:41
  • @G.M. i have posted my code. Really tired though so hopefully i didn't miss anything – JavaBeast Jan 07 '18 at 14:55
  • @JavaBeast If you found the answer, then publish the steps and add the necessary code of your answer, do not delete the code that generates the error as it makes your question unusable for the community. – eyllanesc Jan 08 '18 at 02:18
  • @eyllanesc My specific code is irrelevant to the question as I never had any that matched the question. I only added some at request, but it wasn't related at all to my posted question as it was somewhat off topic. My problem was in theory. I didn't think creating a thread would work but after finding a good example and testing it, it worked. So I updated question with the information confusion I initially had and where I found my answer. – JavaBeast Jan 08 '18 at 02:28
  • @JavaBeast then create a response where you detail it and not only show a link, since this link can be broken and make your "answer" useless. – eyllanesc Jan 08 '18 at 02:31
  • @eyllanesc you misunderstand. The question was will based on a misunderstanding of qthreads lifetime. The answer was realizing it would not terminate until complete signal is emitted as I initially misunderstood. The link is just an additional resource, not the answer. This is all outlined in my initial update – JavaBeast Jan 08 '18 at 02:59

1 Answers1

1

You currently have...

startPlaying();
addWidgetandContainers();

The problem is that startPlaying blocks with an explicit QEventLoop until playing is complete thus delaying the call to addWidgetandContainers.

As you already connect the QAudioOutput::stateChanged to your finishedPlaying slot you can probably simply remove the following code from startPlaying...

QEventLoop loop;
do {
  loop.exec();
} while(audioOutput->state() == QAudio::ActiveState);

As long as your main GUI thread starts its event loop (QApplication::exec() or whatever) then I think that should work as you expect.

G.M.
  • 12,232
  • 2
  • 15
  • 18
  • If I remove the code suggested my sound plays once and the last state entered in stateChanged is ActiveState.The HCI never opens but the code never errors. – JavaBeast Jan 07 '18 at 21:04
  • I presume because the processing of events is terminated early by the end of the function and therefore the premature exit leaves my code in a bad state. – JavaBeast Jan 07 '18 at 22:13
  • Thanks for your help, I resolved problem with QThread though. I removed code from question as I didn't think its relevant to future viewers, question was more aimed toward understanding theory than my specific code. Unfortunately that kind of degrades your answer though, apologize for that. – JavaBeast Jan 08 '18 at 02:16