title: How to use QThread correctly in pyqt with moveToThread()?
body: <p>i read this article <a href="http://mayaposch.wordpress.com/2011/11/01/how-to-really-truly-use-qthreads-the-full-explanation/" rel="noreferrer">How To Really, Truly Use QThreads; The Full Explanation</a>, it says instead of  subclass qthread, and reimplement run(), one should  use moveToThread to push a QObject onto QThread instance using moveToThread(QThread*)</p>
  
  <p>here is the c++ example, but i don't know how to convert it to python code.</p>
  
  <pre class="lang-cpp prettyprint-override"><code>class Worker : public QObject
   {
       Q_OBJECT
       QThread workerThread;
  
   public slots:
       void doWork(const QString &amp;parameter) {
           // ...
           emit resultReady(result);
       }
  
   signals:
       void resultReady(const QString &amp;result);
   };
  
   class Controller : public QObject
   {
       Q_OBJECT
       QThread workerThread;
   public:
       Controller() {
           Worker *worker = new Worker;
           worker-&gt;moveToThread(&amp;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 &amp;);
   signals:
       void operate(const QString &amp;);
   };
  
  
  
  QThread* thread = new QThread;
  Worker* worker = new Worker();
  worker-&gt;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-&gt;start();
  </code></pre>
  
  <p>i've been using this method to generate a qthread , but as you can see, it's using the not recommended way. how can i re-write it to use the preferred method ?</p>
  
  <pre class="lang-py prettyprint-override"><code>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)
  </code></pre>
  
  <p>edit: two years later ...
  I tried qris' code, it works and in different thread </p>
  
  <pre class="lang-py prettyprint-override"><code>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_()
  </code></pre>
  
  <p>the ouput is:</p>
  
  <pre><code>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,
  </code></pre>