Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Background thread with QThread in PyQt

I have a program which interfaces with a radio I am using via a gui I wrote in PyQt. Obviously one of the main functions of the radio is to transmit data, but to do this continuously, I have to loop the writes, which causes the gui to hang. Since I have never dealt with threading, I tried to get rid of these hangs using QCoreApplication.processEvents(). The radio needs to sleep between transmissions, though, so the gui still hangs based on how long these sleeps last.

Is there a simple way to fix this using QThread? I have looked for tutorials on how to implement multithreading with PyQt, but most of them deal with setting up servers and are much more advanced than I need them to be. I honestly don't even really need my thread to update anything while it is running, I just need to start it, have it transmit in the background, and stop it.

like image 670
gwenger Avatar asked Jul 21 '11 21:07

gwenger


People also ask

What is QThread in PyQt5?

In PyQt, you use QThread to create and manage worker threads. According to Qt's documentation, there are two main ways to create worker threads with QThread : Instantiate QThread directly and create a worker QObject , then call .

How do you use QThread?

To use it, prepare a QObject subclass with all your desired functionality in it. Then create a new QThread instance, push the QObject onto it using moveToThread(QThread*) of the QObject instance and call start() on the QThread instance. That's all.

How do you pass arguments to QThread?

You can specify different parameters using Q_ARG macro up to 9 (http://doc.qt.io/qt-5/qmetaobject.html#details). If you need more parameters, then I suggest you to create the QVector with a structure and pass it to QMetaObject::invokeMethod as the parameter.

Is PyQt thread safe?

While some parts of the Qt framework are thread safe, much of it is not. The Qt C++ documentation provides a good overview of which classes are reentrant (can be used to instantiate objects in multiple threads).


1 Answers

I created a little example that shows 3 different and simple ways of dealing with threads. I hope it will help you find the right approach to your problem.

import sys import time  from PyQt5.QtCore import (QCoreApplication, QObject, QRunnable, QThread,                           QThreadPool, pyqtSignal)   # Subclassing QThread # http://qt-project.org/doc/latest/qthread.html class AThread(QThread):      def run(self):         count = 0         while count < 5:             time.sleep(1)             print("A Increasing")             count += 1  # Subclassing QObject and using moveToThread # http://blog.qt.digia.com/blog/2007/07/05/qthreads-no-longer-abstract class SomeObject(QObject):      finished = pyqtSignal()      def long_running(self):         count = 0         while count < 5:             time.sleep(1)             print("B Increasing")             count += 1         self.finished.emit()  # Using a QRunnable # http://qt-project.org/doc/latest/qthreadpool.html # Note that a QRunnable isn't a subclass of QObject and therefore does # not provide signals and slots. class Runnable(QRunnable):      def run(self):         count = 0         app = QCoreApplication.instance()         while count < 5:             print("C Increasing")             time.sleep(1)             count += 1         app.quit()   def using_q_thread():     app = QCoreApplication([])     thread = AThread()     thread.finished.connect(app.exit)     thread.start()     sys.exit(app.exec_())  def using_move_to_thread():     app = QCoreApplication([])     objThread = QThread()     obj = SomeObject()     obj.moveToThread(objThread)     obj.finished.connect(objThread.quit)     objThread.started.connect(obj.long_running)     objThread.finished.connect(app.exit)     objThread.start()     sys.exit(app.exec_())  def using_q_runnable():     app = QCoreApplication([])     runnable = Runnable()     QThreadPool.globalInstance().start(runnable)     sys.exit(app.exec_())  if __name__ == "__main__":     #using_q_thread()     #using_move_to_thread()     using_q_runnable() 
like image 125
aukaost Avatar answered Oct 13 '22 05:10

aukaost