[PyQt] No way to stop a QThread in a Plasma.Applet

Nate C nate1001 at gmail.com
Fri Jul 16 06:29:43 BST 2010


I have posted this same general problem here and the plasma-devel
list. But I have not come up with any solutions. My code uses a
QThread for network operations. The thread works fine but I need to
stop it when the applet closes or it segfaults. Reading the docs
Plasma::Applet subclasses from QGraphicsWidget which has a closeEvent
that can be subclassed for teardown procedures. There is no closeEvent
in the KDE Plasma API. On further inspection of the
plasmascript.Applet instance I see there is a self.applet attribute
witch appears to be the actual Plasma::Applet : QGraphicsWidget
subclass and also has an attribute closeEvent. But, how do you use it?
I have tried self.applet.closeEvent = self.closeEvent but it is never
triggered. I have tried connecting to the destroyed event. I have
tried ending the thread in by subclassing __del__ but that segfaults.
If I do nothing and let the thread run the program segfaults.

I have attatched a plasmoid.zip file of the code below

from PyQt4.QtGui import *
from PyQt4.QtCore import *
from PyKDE4.plasma import Plasma
from PyKDE4 import plasmascript

import sys
D = sys.stderr.write

class Thread(QThread):

    def __init__(self, parent=None):
        QThread.__init__(self, parent)
        self.exiting = False

    def quit(self):
        self.exiting = True
        self.wait()

    def run(self):
        while not self.exiting:
            pass
            # do network stuff here
            QThread.sleep(1)
        return

class NoWaytoStopThisThread(plasmascript.Applet):
    def __init__(self, parent=None):
        plasmascript.Applet.__init__(self,parent)

    def init(self):

        self.worker = Thread()
        # connect worker signals here ...

        # the docs says this unblockable so this probably would not
work any ways
        self.connect(self, SIGNAL("destroyed(QObject* obj=0)"), self.onDestroy)
        self.connect(self.applet, SIGNAL("destroyed(QObject* obj=0)"),
self.onDestroy)
        self.applet.closeEvent = self.closeEvent

        # this was a longshot
        self.w = QGraphicsWidget()
        self.w.closeEvent = self.onDestroy
        layout = QGraphicsLinearLayout(Qt.Vertical)
        self.setLayout(layout)
        layout.addItem(self.w)

        self.worker.start()
        # ...?

    # never gets here
    def closeEvent(self, event):
        self.worker.quit()
        D('close\n')

    # never gets here
    def onDestroy(self, applet):
        self.worker.quit()
        D('onDestroy')

    # segfaults
    def __del__(self):
         self.worker.quit()

def CreateApplet(parent):
    return NoWaytoStopThisThread(parent)
-------------- next part --------------
A non-text attachment was scrubbed...
Name: test123.zip
Type: application/zip
Size: 4734 bytes
Desc: not available
URL: <http://www.riverbankcomputing.com/pipermail/pyqt/attachments/20100715/33ae53d8/attachment-0001.zip>


More information about the PyQt mailing list