Wie zu verwenden QThread richtig in pyqt mit moveToThread()?

habe ich diesen Artikel gelesen Wie Wirklich, Wirklich Verwenden QThreads; Die Vollständige Erklärung, heißt es statt Unterklasse qthread, und implementieren Sie die run () -, sollte man Sie nutzen moveToThread zu schieben ein QObject auf QThread Beispiel mit moveToThread(QThread*)

hier ist der c++ - Beispiel, aber ich weiß nicht, wie es zu konvertieren, um python-code.

class Worker : public QObject
 {
     Q_OBJECT
     QThread workerThread;

 public slots:
     void doWork(const QString &parameter) {
         //...
         emit resultReady(result);
     }

 signals:
     void resultReady(const QString &result);
 };

 class Controller : public QObject
 {
     Q_OBJECT
     QThread workerThread;
 public:
     Controller() {
         Worker *worker = new Worker;
         worker->moveToThread(&workerThread);
         connect(workerThread, SIGNAL(finished()), worker, SLOT(deleteLater()));
         connect(this, SIGNAL(operate(QString)), worker, SLOT(doWork(QString)));
         connect(worker, SIGNAL(resultReady(QString)), this, SLOT(handleResults(QString)));
         workerThread.start();
     }
     ~Controller() {
         workerThread.quit();
         workerThread.wait();
     }
 public slots:
     void handleResults(const QString &);
 signals:
     void operate(const QString &);
 };



QThread* thread = new QThread;
Worker* worker = new Worker();
worker->moveToThread(thread);
connect(worker, SIGNAL(error(QString)), this, SLOT(errorString(QString)));
connect(thread, SIGNAL(started()), worker, SLOT(process()));
connect(worker, SIGNAL(finished()), thread, SLOT(quit()));
connect(worker, SIGNAL(finished()), worker, SLOT(deleteLater()));
connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
thread->start();

ich habe mit dieser Methode zum generieren einer qthread , aber wie Sie sehen können, es ist mit dem nicht empfohlenen Weg. wie kann ich wieder schreiben, dass die bevorzugte Methode ?

class GenericThread(QThread):
    def __init__(self, function, *args, **kwargs):
        QThread.__init__(self)
        # super(GenericThread, self).__init__()

        self.function = function
        self.args = args
        self.kwargs = kwargs

    def __del__(self):
        self.wait()

    def run(self, *args):
        self.function(*self.args, **self.kwargs)

Bearbeiten: zwei Jahre später ...
Ich habe versucht, qris' code funktioniert es und im anderen thread

import sys
import time
from PyQt4 import QtCore, QtGui
from PyQt4.QtCore import pyqtSignal, pyqtSlot
import threading


def logthread(caller):
    print('%-25s: %s, %s,' % (caller, threading.current_thread().name,
                              threading.current_thread().ident))


class MyApp(QtGui.QWidget):

    def __init__(self, parent=None):
        QtGui.QWidget.__init__(self, parent)

        self.setGeometry(300, 300, 280, 600)
        self.setWindowTitle('using threads')

        self.layout = QtGui.QVBoxLayout(self)

        self.testButton = QtGui.QPushButton("QThread")
        self.testButton.released.connect(self.test)
        self.listwidget = QtGui.QListWidget(self)

        self.layout.addWidget(self.testButton)
        self.layout.addWidget(self.listwidget)

        self.threadPool = []
        logthread('mainwin.__init__')

    def add(self, text):
        """ Add item to list widget """
        logthread('mainwin.add')
        self.listwidget.addItem(text)
        self.listwidget.sortItems()

    def addBatch(self, text="test", iters=6, delay=0.3):
        """ Add several items to list widget """
        logthread('mainwin.addBatch')
        for i in range(iters):
            time.sleep(delay)  # artificial time delay
            self.add(text+" "+str(i))

    def test(self):
        my_thread = QtCore.QThread()
        my_thread.start()

        # This causes my_worker.run() to eventually execute in my_thread:
        my_worker = GenericWorker(self.addBatch)
        my_worker.moveToThread(my_thread)
        my_worker.start.emit("hello")
        # my_worker.finished.connect(self.xxx)

        self.threadPool.append(my_thread)
        self.my_worker = my_worker


class GenericWorker(QtCore.QObject):

    start = pyqtSignal(str)
    finished = pyqtSignal()

    def __init__(self, function, *args, **kwargs):
        super(GenericWorker, self).__init__()
        logthread('GenericWorker.__init__')
        self.function = function
        self.args = args
        self.kwargs = kwargs
        self.start.connect(self.run)

    @pyqtSlot()
    def run(self, *args, **kwargs):
        logthread('GenericWorker.run')
        self.function(*self.args, **self.kwargs)
        self.finished.emit()


# run
app = QtGui.QApplication(sys.argv)
test = MyApp()
test.show()
app.exec_()

den, Ausgang:

mainwin.__init__         : MainThread, 140221684574016,
GenericWorker.__init__   : MainThread, 140221684574016,
GenericWorker.run        : Dummy-1, 140221265458944,
mainwin.addBatch         : Dummy-1, 140221265458944,
mainwin.add              : Dummy-1, 140221265458944,
mainwin.add              : Dummy-1, 140221265458944,
mainwin.add              : Dummy-1, 140221265458944,
mainwin.add              : Dummy-1, 140221265458944,
mainwin.add              : Dummy-1, 140221265458944,
mainwin.add              : Dummy-1, 140221265458944,
Ich bin überrascht, dass diese Frage unbeantwortet/unkommentiert so lange. docs deutlich, dass mit moveToThread(thread) ist die bevorzugte Art und Weise, aber doch alle Beispiel-code habe ich in der Lage zu finden, Unterklassen QThread.run() und setzen dort arbeiten. Es wäre toll, wenn wir sehen könnten, ein Beispiel oder ein Muster verwenden.
Hier ist ein Artikel, der hat mir sehr geholfen bei der Umsetzung mein Erster thread: mayaposch.wordpress.com/2011/11/01/... . Als Sie sagte, dass es nicht eine empfohlene Praxis, um eine Unterklasse QThread auch wenn es eine Menge von tutorials zu tun.
Ist das Letzte Beispiel in der Frage richtig? mainwin.hinzuzufügen ist, wo der code fügt das Element an das listwidget, aber deutlich von der gedruckten Ausgabe können wir sehen, tat mainwin.add ausgeführt in den thread?!?

InformationsquelleAutor Shuman | 2013-12-02

Schreibe einen Kommentar