<div dir="ltr"><div class="markdown-here-wrapper" style><p style="margin:1.2em 0px!important">All,</p>
<p style="margin:1.2em 0px!important">I’m confused when it comes to the proper way to mesh Qt’s model of creating a tree of parented objects which destroy themselves when no longer used with Python’s “delete it when I feel like it” garbage collector. In particular, I’d like to shut down threads when the underlying Qt objects are destroyed, but I can’t figure out how to do that. Any advice and wisdom would be appreciated. I've attached same code with my thoughts.</p>
<p style="margin:1.2em 0px!important">Bryan</p>
<pre style="font-size:0.85em;font-family:Consolas,Inconsolata,Courier,monospace;font-size:1em;line-height:1.2em;margin:1.2em 0px"><code style="font-size:0.85em;font-family:Consolas,Inconsolata,Courier,monospace;margin:0px 0.15em;padding:0px 0.3em;white-space:pre-wrap;border:1px solid rgb(234,234,234);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px;display:inline;background-color:rgb(248,248,248);white-space:pre;overflow:auto;border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px;border:1px solid rgb(204,204,204);padding:0.5em 0.7em;display:block!important"># Test program to ask about destructors and PyQt4.

import sys, time
from PyQt4.QtGui import QApplication
from PyQt4.QtCore import QThread, QTimer, QObject

class Worker(QObject):
    def run(self):
        time.sleep(1)

class ThreadController(QObject):
    def __init__(self, parent):
        QObject.__init__(self, parent)
        # No parent object provided; if so, we get the error
        # "QObject::moveToThread: Cannot move objects with a parent".
        # Who will deallocate this object, since it has no parent? I
        # assume the answer is "Python, maybe". Is that good enough?
        self.worker = Worker()
        self.workerThread = QThread(self)
        self.worker.moveToThread(self.workerThread)
        # Use method #2 below. Commnet out for a crash.
        parent.aboutToQuit.connect(self.del_)
        self.workerThread.start()

    # I'd like to run when when ~ThreadController is invoked. That's quite
    # differentfrom when __del__ is invoked. How?
    #
    # 1. Give up. Just invoke it manually. However, this is error-prone (i.e.
    #    I'll forget to do it at some point).
    # 2. Connect app.aboutToQuit to this. This seems fairly reasonable, but
    #    it would feel cleaner to invoke when the destructor is invoked,
    #    rather than earlier. Also, this means that the QApplication would
    #    need to be passed to every thread, which might involve awkwardness
    #    in passing it through several intervening subclasses.
    # 3. Connect destroyed(), which doesn't work -- this isn't emitted until
    #    the object is mostly dead, far after ~ThreadController was invoked,
    #    and won't be executed.
    # 4. Have __del__ invoke this, which doesn't work -- it only happens after
    #    ~ThreadController has finihed.
    def del_(self):
        print('del_')
        self.workerThread.quit()
        self.workerThread.wait()

    def __del__(self):
        print('__del__')
        # Crash when uncommented.
        #self.del_()

if __name__ == '__main__':
    app = QApplication(sys.argv)

    # Exit the program shortly after the event loop starts up, but before the
    # thread finishes.
    QTimer.singleShot(200, app.exit)

    # Start a thread
    tm = ThreadController(app)

    # Run the main event loop.
    ret = app.exec_()
    print('done')
    sys.exit(ret)
</code></pre><div title="MDH:QWxsLDxkaXY+PGJyPjwvZGl2PjxkaXY+SSdtIGNvbmZ1c2VkIHdoZW4gaXQgY29tZXMgdG8gdGhl
IHByb3BlciB3YXkgdG8gbWVzaCBRdCdzIG1vZGVsIG9mIGNyZWF0aW5nIGEgdHJlZSBvZiBwYXJl
bnRlZCBvYmplY3RzIHdoaWNoIGRlc3Ryb3kgdGhlbXNlbHZlcyB3aGVuIG5vIGxvbmdlciB1c2Vk
IHdpdGggUHl0aG9uJ3MgImRlbGV0ZSBpdCB3aGVuIEkgZmVlbCBsaWtlIGl0IiBnYXJiYWdlIGNv
bGxlY3Rvci4gSW4gcGFydGljdWxhciwgSSdkIGxpa2UgdG8gc2h1dCBkb3duIHRocmVhZHMgd2hl
biB0aGUgdW5kZXJseWluZyBRdCBvYmplY3RzIGFyZSBkZXN0cm95ZWQsIGJ1dCBJIGNhbid0IGZp
Z3VyZSBvdXQgaG93IHRvIGRvIHRoYXQuIEFueSBhZHZpY2UgYW5kIHdpc2RvbSB3b3VsZCBiZSBh
cHByZWNpYXRlZC48L2Rpdj48ZGl2Pjxicj48L2Rpdj48ZGl2PkJyeWFuPC9kaXY+PGRpdj48YnI+
PC9kaXY+PGRpdj48ZGl2PiZuYnNwOyAmbmJzcDsgIyBUZXN0IHByb2dyYW0gdG8gYXNrIGFib3V0
IGRlc3RydWN0b3JzIGFuZCBQeVF0NC48L2Rpdj48ZGl2PiZuYnNwOyAmbmJzcDsmbmJzcDs8L2Rp
dj48ZGl2PiZuYnNwOyAmbmJzcDsgaW1wb3J0IHN5cywgdGltZTwvZGl2PjxkaXY+Jm5ic3A7ICZu
YnNwOyBmcm9tIFB5UXQ0LlF0R3VpIGltcG9ydCBRQXBwbGljYXRpb248L2Rpdj48ZGl2PiZuYnNw
OyAmbmJzcDsgZnJvbSBQeVF0NC5RdENvcmUgaW1wb3J0IFFUaHJlYWQsIFFUaW1lciwgUU9iamVj
dDwvZGl2PjxkaXY+Jm5ic3A7ICZuYnNwOyZuYnNwOzwvZGl2PjxkaXY+Jm5ic3A7ICZuYnNwOyBj
bGFzcyBXb3JrZXIoUU9iamVjdCk6PC9kaXY+PGRpdj4mbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJz
cDsgZGVmIHJ1bihzZWxmKTo8L2Rpdj48ZGl2PiZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAm
bmJzcDsgJm5ic3A7IHRpbWUuc2xlZXAoMSk8L2Rpdj48ZGl2PiZuYnNwOyAmbmJzcDsmbmJzcDs8
L2Rpdj48ZGl2PiZuYnNwOyAmbmJzcDsgY2xhc3MgVGhyZWFkQ29udHJvbGxlcihRT2JqZWN0KTo8
L2Rpdj48ZGl2PiZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyBkZWYgX19pbml0X18oc2VsZiwg
cGFyZW50KTo8L2Rpdj48ZGl2PiZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5i
c3A7IFFPYmplY3QuX19pbml0X18oc2VsZiwgcGFyZW50KTwvZGl2PjxkaXY+Jm5ic3A7ICZuYnNw
OyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgIyBObyBwYXJlbnQgb2JqZWN0IHByb3ZpZGVk
OyBpZiBzbywgd2UgZ2V0IHRoZSBlcnJvcjwvZGl2PjxkaXY+Jm5ic3A7ICZuYnNwOyAmbmJzcDsg
Jm5ic3A7ICZuYnNwOyAmbmJzcDsgIyAiUU9iamVjdDo6bW92ZVRvVGhyZWFkOiBDYW5ub3QgbW92
ZSBvYmplY3RzIHdpdGggYSBwYXJlbnQiLjwvZGl2PjxkaXY+Jm5ic3A7ICZuYnNwOyAmbmJzcDsg
Jm5ic3A7ICZuYnNwOyAmbmJzcDsgIyBXaG8gd2lsbCBkZWFsbG9jYXRlIHRoaXMgb2JqZWN0LCBz
aW5jZSBpdCBoYXMgbm8gcGFyZW50PyBJPC9kaXY+PGRpdj4mbmJzcDsgJm5ic3A7ICZuYnNwOyAm
bmJzcDsgJm5ic3A7ICZuYnNwOyAjIGFzc3VtZSB0aGUgYW5zd2VyIGlzICJQeXRob24sIG1heWJl
Ii4gSXMgdGhhdCBnb29kIGVub3VnaD88L2Rpdj48ZGl2PiZuYnNwOyAmbmJzcDsgJm5ic3A7ICZu
YnNwOyAmbmJzcDsgJm5ic3A7IHNlbGYud29ya2VyID0gV29ya2VyKCk8L2Rpdj48ZGl2PiZuYnNw
OyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7IHNlbGYud29ya2VyVGhyZWFkID0g
UVRocmVhZChzZWxmKTwvZGl2PjxkaXY+Jm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNw
OyAmbmJzcDsgc2VsZi53b3JrZXIubW92ZVRvVGhyZWFkKHNlbGYud29ya2VyVGhyZWFkKTwvZGl2
PjxkaXY+Jm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgIyBVc2UgbWV0
aG9kICMyIGJlbG93LiBDb21tbmV0IG91dCBmb3IgYSBjcmFzaC48L2Rpdj48ZGl2PiZuYnNwOyAm
bmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7IHBhcmVudC5hYm91dFRvUXVpdC5jb25u
ZWN0KHNlbGYuZGVsXyk8L2Rpdj48ZGl2PiZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJz
cDsgJm5ic3A7IHNlbGYud29ya2VyVGhyZWFkLnN0YXJ0KCk8L2Rpdj48ZGl2PiZuYnNwOyAmbmJz
cDsmbmJzcDs8L2Rpdj48ZGl2PiZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAjIEknZCBsaWtl
IHRvIHJ1biB3aGVuIHdoZW4gflRocmVhZENvbnRyb2xsZXIgaXMgaW52b2tlZC4gVGhhdCdzIHF1
aXRlPC9kaXY+PGRpdj4mbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgIyBkaWZmZXJlbnRmcm9t
IHdoZW4gX19kZWxfXyBpcyBpbnZva2VkLiBIb3c/PC9kaXY+PGRpdj4mbmJzcDsgJm5ic3A7ICZu
YnNwOyAmbmJzcDsgIzwvZGl2PjxkaXY+Jm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICMgMS4g
R2l2ZSB1cC4gSnVzdCBpbnZva2UgaXQgbWFudWFsbHkuIEhvd2V2ZXIsIHRoaXMgaXMgZXJyb3It
cHJvbmUgKGkuZS48L2Rpdj48ZGl2PiZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAjICZuYnNw
OyAmbmJzcDtJJ2xsIGZvcmdldCB0byBkbyBpdCBhdCBzb21lIHBvaW50KS48L2Rpdj48ZGl2PiZu
YnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAjIDIuIENvbm5lY3QgYXBwLmFib3V0VG9RdWl0IHRv
IHRoaXMuIFRoaXMgc2VlbXMgZmFpcmx5IHJlYXNvbmFibGUsIGJ1dDwvZGl2PjxkaXY+Jm5ic3A7
ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICMgJm5ic3A7ICZuYnNwO2l0IHdvdWxkIGZlZWwgY2xlYW5l
ciB0byBpbnZva2Ugd2hlbiB0aGUgZGVzdHJ1Y3RvciBpcyBpbnZva2VkLDwvZGl2PjxkaXY+Jm5i
c3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICMgJm5ic3A7ICZuYnNwO3JhdGhlciB0aGFuIGVhcmxp
ZXIuIEFsc28sIHRoaXMgbWVhbnMgdGhhdCB0aGUgUUFwcGxpY2F0aW9uIHdvdWxkPC9kaXY+PGRp
dj4mbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgIyAmbmJzcDsgJm5ic3A7bmVlZCB0byBiZSBw
YXNzZWQgdG8gZXZlcnkgdGhyZWFkLCB3aGljaCBtaWdodCBpbnZvbHZlIGF3a3dhcmRuZXNzPC9k
aXY+PGRpdj4mbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgIyAmbmJzcDsgJm5ic3A7aW4gcGFz
c2luZyBpdCB0aHJvdWdoIHNldmVyYWwgaW50ZXJ2ZW5pbmcgc3ViY2xhc3Nlcy48L2Rpdj48ZGl2
PiZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAjIDMuIENvbm5lY3QgZGVzdHJveWVkKCksIHdo
aWNoIGRvZXNuJ3Qgd29yayAtLSB0aGlzIGlzbid0IGVtaXR0ZWQgdW50aWw8L2Rpdj48ZGl2PiZu
YnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAjICZuYnNwOyAmbmJzcDt0aGUgb2JqZWN0IGlzIG1v
c3RseSBkZWFkLCBmYXIgYWZ0ZXIgflRocmVhZENvbnRyb2xsZXIgd2FzIGludm9rZWQsPC9kaXY+
PGRpdj4mbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgIyAmbmJzcDsgJm5ic3A7YW5kIHdvbid0
IGJlIGV4ZWN1dGVkLjwvZGl2PjxkaXY+Jm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICMgNC4g
SGF2ZSBfX2RlbF9fIGludm9rZSB0aGlzLCB3aGljaCBkb2Vzbid0IHdvcmsgLS0gaXQgb25seSBo
YXBwZW5zIGFmdGVyPC9kaXY+PGRpdj4mbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgIyAmbmJz
cDsgJm5ic3A7flRocmVhZENvbnRyb2xsZXIgaGFzIGZpbmloZWQuPC9kaXY+PGRpdj4mbmJzcDsg
Jm5ic3A7ICZuYnNwOyAmbmJzcDsgZGVmIGRlbF8oc2VsZik6PC9kaXY+PGRpdj4mbmJzcDsgJm5i
c3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyBwcmludCgnZGVsXycpPC9kaXY+PGRpdj4m
bmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyBzZWxmLndvcmtlclRocmVh
ZC5xdWl0KCk8L2Rpdj48ZGl2PiZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5i
c3A7IHNlbGYud29ya2VyVGhyZWFkLndhaXQoKTwvZGl2PjxkaXY+Jm5ic3A7ICZuYnNwOyZuYnNw
OzwvZGl2PjxkaXY+Jm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7IGRlZiBfX2RlbF9fKHNlbGYp
OjwvZGl2PjxkaXY+Jm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgcHJp
bnQoJ19fZGVsX18nKTwvZGl2PjxkaXY+Jm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNw
OyAmbmJzcDsgIyBDcmFzaCB3aGVuIHVuY29tbWVudGVkLjwvZGl2PjxkaXY+Jm5ic3A7ICZuYnNw
OyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgI3NlbGYuZGVsXygpPC9kaXY+PGRpdj4mbmJz
cDsgJm5ic3A7Jm5ic3A7PC9kaXY+PGRpdj4mbmJzcDsgJm5ic3A7IGlmIF9fbmFtZV9fID09ICdf
X21haW5fXyc6PC9kaXY+PGRpdj4mbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgYXBwID0gUUFw
cGxpY2F0aW9uKHN5cy5hcmd2KTwvZGl2PjxkaXY+Jm5ic3A7ICZuYnNwOyZuYnNwOzwvZGl2Pjxk
aXY+Jm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICMgRXhpdCB0aGUgcHJvZ3JhbSBzaG9ydGx5
IGFmdGVyIHRoZSBldmVudCBsb29wIHN0YXJ0cyB1cCwgYnV0IGJlZm9yZSB0aGU8L2Rpdj48ZGl2
PiZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAjIHRocmVhZCBmaW5pc2hlcy48L2Rpdj48ZGl2
PiZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyBRVGltZXIuc2luZ2xlU2hvdCgyMDAsIGFwcC5l
eGl0KTwvZGl2PjxkaXY+Jm5ic3A7ICZuYnNwOyZuYnNwOzwvZGl2PjxkaXY+Jm5ic3A7ICZuYnNw
OyAmbmJzcDsgJm5ic3A7ICMgU3RhcnQgYSB0aHJlYWQ8L2Rpdj48ZGl2PiZuYnNwOyAmbmJzcDsg
Jm5ic3A7ICZuYnNwOyB0bSA9IFRocmVhZENvbnRyb2xsZXIoYXBwKTwvZGl2PjxkaXY+Jm5ic3A7
ICZuYnNwOyZuYnNwOzwvZGl2PjxkaXY+Jm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICMgUnVu
IHRoZSBtYWluIGV2ZW50IGxvb3AuPC9kaXY+PGRpdj4mbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJz
cDsgcmV0ID0gYXBwLmV4ZWNfKCk8L2Rpdj48ZGl2PiZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNw
OyBwcmludCgnZG9uZScpPC9kaXY+PGRpdj4mbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgc3lz
LmV4aXQocmV0KTwvZGl2PjxkaXY+Jm5ic3A7ICZuYnNwOyZuYnNwOzwvZGl2PjxkaXY+PGJyPjwv
ZGl2PjwvZGl2Pg==" style="height:0;font-size:0em;padding:0;margin:0">​</div></div><div>-- <br>Bryan A. Jones, Ph.D.<br>Associate Professor<br>Department of Electrical and Computer Engineering<br>231 Simrall / PO Box 9571<br>Mississippi State University<br>Mississippi state, MS 39762<br><a href="http://www.ece.msstate.edu/~bjones" target="_blank">http://www.ece.msstate.edu/~bjones</a><br>bjones AT ece DOT msstate DOT edu<br>voice 662-325-3149<br>fax 662-325-2298<br><br>Our Master, Jesus Christ, is on his way. He'll show up right on<br>time, his arrival guaranteed by the Blessed and Undisputed Ruler,<br>High King, High God.<br>- 1 Tim. 6:14b-15 (The Message)<br>
</div></div>