[PySide] QThread crash before emitting finished signal

William Dias william.dias at gmail.com
Fri Jun 8 02:28:03 CEST 2012


Thanks, Sebastian.

I did what you've said. The only thing is that I must keep the references
to both photoWorker and photoThread, otherwise it won't work. I thought
about keeping the reference to the thread object inside the photoWorker and
keep a list of photoWorkers in the main thread. Is it a good approach?

Should I call thread.quit() to finish the thread execution?

Regards,

2012/6/7 Sebastian Elsner <sebastian at risefx.com>

>  Hi,
>
> 1) I'd add an __init__ like this.
>
> def __init__(self,parent=None):
>     QObject.__init__(self,parent)
>
> 2) I'd move the work method stuff to the init. It looks like you are doing
> the setup there. init is the place to be for this.
>
> 3) QMetaObject.invokeMethod(photoWorker, "work", Qt.QueuedConnection)
> looks very strange
> use:
> photoThread.started.connect(photoWorker.doWork)
> instead. place before photoThread.start().
>
>
>  Apart from that, my threads are being destroyed as photoWorker and
> photoThread objects run out of scope. How can I prevent python from doing
> this? Making them instance objects is not an option since every time my
> program reenters the method where they are declared it spawns new threads.
>
>
> Make a list and add the photoWorker instances to the list. Clean the list
> up now and then.
>
>
>
>  Thanks,
>
>
> 2012/6/7 William Dias <william.dias at gmail.com>
>
>> Thank you, Sebastian. I followed the procedures described in the document
>> and it worked. But I have another question.
>> Take a look at the code bellow:
>>
>>  class PhotoWorker(QObject):
>>
>>  photoStatus = Signal(str, str)
>>
>>  @Slot()
>>  def work(self):
>>  self.db = sqlite_database.SQLiteDatabase("db1")
>>  self.timer = QTimer()
>>  self.timer.timeout.connect(self.__resendPhoto)
>>  logger.info("photo worker started")
>>  self.timer.start(10000)
>>
>>  @Slot()
>>  def __resendPhoto(self):
>>  data = self.db.selectPhoto()
>>  if data != None:
>>  self.filename = data[0]
>>  self.tags = data[1]
>>  logger.info("trying to resend photo " + self.filename)
>>  status = sendPhoto(self.tags, self.filename)
>>  self.photoStatus.emit(self.filename, status)
>>
>>  And in a GUI class, I do the following:
>>
>>   photoWorker = http_connection.PhotoWorker(self)
>>  photoWorker.photoStatus.connect(self.photoStatus)
>>  photoThread = QThread()
>>  photoWorker.moveToThread(photoThread)
>>  photoThread.start()
>>  QMetaObject.invokeMethod(photoWorker, "work", Qt.QueuedConnection)
>>
>>  I realized that when I create the photoWorker object, if I don't set
>> its parent to self, my thread dies. Is this because my photoWorker doesn't
>> have its own event loop? I am bit confused here. How should I proceed?
>>
>>  Thank you.
>>
>> 2012/6/7 Sebastian Elner <sebastian at risefx.com>
>>
>>>  Although it is in the documentation, QThread is not meant to be used
>>> this way (subclassing). Have a look at this:
>>> http://labs.qt.nokia.com/2010/06/17/youre-doing-it-wrong/ It helped me
>>> a lot. Also a complete stripped down example would greatly help in a case
>>> of a segfault.
>>>
>>>
>>>
>>> On 06/07/2012 09:59 AM, William Dias wrote:
>>>
>>>  Hi,
>>>
>>>  I have a subclass of QThread which uploads pictures to a webserver.
>>> For each new picture created in the main thread, the program spawns a new
>>> thread to handle the job. I've override the __init__ method to be able to
>>> pass some parameters to the thread object, as you can see bellow.
>>>
>>>  class PhotoConnection(QThread):
>>>>  photoStatus = Signal(str, str)
>>>
>>>  def __init__(self, tags, filename, parent=None):
>>>>  QThread.__init__(self, parent)
>>>>  self.tags = tags
>>>>  self.filename = filename
>>>
>>>  def run(self):
>>>>  status = sendPhoto(self.tags, self.filename)
>>>>  self.photoStatus.emit(self.filename, status)
>>>
>>>
>>>  In the GUI thread, the method responsible dor creating the threads is
>>> the following:
>>>
>>>  def sendPhoto(self):
>>>>  photoConnection = PhotoConnection(self.tags_to_string, self.filename,
>>>> self)
>>>>  photoConnection.photoStatus.connect(self.photoStatus)
>>>>  photoConnection.finished.connect(self.threadFinished)
>>>>  photoConnection.start()
>>>>
>>>
>>>  In the PhotoConnection, if I don't set the parent of my Qthread object
>>> to self (for example, if I set to None) or if I don't override the __init__
>>> method and create another method to pass the arguments, when the thread
>>> finishes the execution I got a segfault.
>>> Why is this happening? Can you help me?
>>>
>>>  Thanks,
>>>
>>>
>>>  _______________________________________________
>>> PySide mailing listPySide at qt-project.orghttp://lists.qt-project.org/mailman/listinfo/pyside
>>>
>>>
>>>
>>> --
>>> Sebastian Elsner    -    pipeline td   -   r i s e |  fx
>>>
>>> t:  +49 30 20180300                 sebastian at risefx.com
>>>                                           www.risefx.com
>>>
>>> r i s e |  fx  GmbH
>>> Schlesische Strasse 28 Aufgang B, 10997 Berlin
>>> Geschäftsführer: Sven Pannicke, Robert Pinnow
>>>
>>> Handelsregister Berlin HRB 106667 B
>>>
>>>
>>> _______________________________________________
>>> PySide mailing list
>>> PySide at qt-project.org
>>> http://lists.qt-project.org/mailman/listinfo/pyside
>>>
>>>
>>
>>
>>  --
>>  William Marques Dias
>>
>
>
>
>  --
> William Dias
>
>
>
>
> _______________________________________________
> PySide mailing list
> PySide at qt-project.org
> http://lists.qt-project.org/mailman/listinfo/pyside
>
>


-- 
William Dias
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.qt-project.org/pipermail/pyside/attachments/20120607/cf4b649c/attachment.html>


More information about the PySide mailing list