PDA

View Full Version : Need help with creating and deleting a background thread for processing



agerlach
27th December 2010, 22:24
Hello all,

I have a GUI application that functions like a wizard. Because QWizard didn't offer the flexibility I need, I decided to build a wizard comprised of multiple QDialog forms and a class that controls the logic of the wizard including the construction and destruction of forms. This wizard has the user input some data and then the application uses 3D scanner hardware to capture and display a 3D image (mesh). If the image is suitable to the user the user clicks finished and the wizard goes back to the beginning. Depending on the inputs of the user, some processing may need to be performed on the captured image (this processing is substantial > 20 min). I would like this to be performed in the background without the users knowledge.

This is what I have now that does not work. I created a class called trainer that inherits from QThread. I also reimplemented the run() method in the trainer class. This class works fine. In my final wizard form which displays the scan results (we'll call this the results class), I create a trainer object when finished is click and start that thread. The problem occurs when the form returns back to the object that is controlling the wizard logic. Because the wizard needs to go back to the first page I delete the results object resulting in a crash. If I don't delete the results object everything functions fine.

How do I have the trainer class and then results class delete itself once the trainer is done processing? My plan was to create thread for each scan to be processed at then let that thread delete itself, but what I really need is a queue that will let say 4 threads operate in parallel and then have a waiting list behind that.

bothorsen
28th December 2010, 22:37
You need to avoid setting the wizard object as the qparent, since the thread would be deleted if you delete your wizard. You do not want to keep your wizard in memory just to avoid this.

Connect a signal from your thread to something in your application (this must be a queued connection) and get the results from the thread in the slot somehow - depends on what it is, of course.

To delete your thread object, you should use deleteLater(). You can either call this at the end of your run method or connect it to finished(). I usually don't like connecting to finished(), as I might stop and start threads later in the project, and that's a really hard bug to find. But sometimes it's the simplest way. In any case, deleteLater() is your friend.

I hope this helps.

agerlach
30th December 2010, 22:38
Thank you this was a huge help. I can now delete my wizard form and still have the thread process it also deletes itself. Lucky the thread the wizard does not need to know the results of the computation and the results are pushed to a mySQL database so I didn't have to worry about creating a signal for the results.