I am fairly new in writing bigger programs in Python (I was only writing short scripts before). The program I'm about to write recives data from an external device, saves it to database and displays it in GUI (continuously). Since handling the data is time consuming I want to use threads (PySide QtCore QThreads to be specific). The best way to do this that I can think of is to set up two threads, one for the database processes and one for the handling of serial port, with GUI running in the MainThread. Now I've read a whole bunch of stuff about proper/improper QThreading, starting with Maya's post and digging deeper, up to this post where I found that:
When to subclass and when not to?
If you do not really need an event loop in the thread, you should subclass. If you need an event loop and handle signals and slots within the thread, you may not need to subclass.
Question 1: Now the first thing I don't know is which way to go (subclassing or not). My guess is subclassing, since (Question2), but I'm not entirely sure and for now I'm sticking to moveToThread()
.
Question 2: The other thing I have no clue about is how to make the actions in my threads event-driven (the SerialThread receives the data from the device, sends it via signal to the DatabaseThread, the DatabaseThread collects the data and puts it in the database).
Question 3: When using moveToThread()
I get AttributeError: 'PySide.QtCore.QThread' object has no attribute 'my_awesome_method'
for every method I write for my class. It's clear to me that I don't understand the principle of operation here. How do I implement my methods that I want my_class
to have while using my_class.moveToThread(my_thread)
?
I've found all tutorials possible on QThreads and C++, so this discussion on QThreads in Python is interesting, but does not explain everything I want to know. I need a simple example with signals, slots and an exact explanation on how to use run(). Do I decorate it? Why? How? How does it work?
The short version of my code looks like this:
from PySide import QtCore
from app.thrads.gui.gui import Gui #my own class
from app.threads.db.db import Database #my own class
from app.threads.serial.serial import Serial #my own class
class AppManager():
def __init__(self):
self.gui = Gui()
self.db = Database()
self.db_thread = QtCore.QThread()
self.db.moveToThread(self.db_thread)
self.db_thread.start()
self.serial = Serial()
self.serial_thread = QtCore.QThread()
self.serial.moveToThread(self.serial_thread)
self.serial_thread.start()
and my Database and Serial class look somewhat like this:
from PySide import QtCore
from .db_signal import DbSignal
class Database(QtCore.QObject):
def __init__(self):
super(Database, self).__init__()
self.signal = DbSignal()
def my_awesome_method(self):
''' does something awesome '''
pass