[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