Python Forum
Sending a custom signal from a worker
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Sending a custom signal from a worker
#1
Hi all, I'm working in a Python application, using PySide on a Raspberry Pi, with Raspbian Jessie OS.

I'm very new in Python, so I'm not an expert at all, and probably it's a begginer's question.

In my application, I have:

main thread -> Gui Thread that implements front end.
subyacent thread -> Makes some long work (no gui at all, plain code), implemented in a Custom class named MyWorker.

In some places of subyacent thread's code, I need to emit a signal that have to be catched by the main thread. In a previous version, I did it this way:

Main thread's code

    #Slot for clicked button
    def Slot_Start_Calculation (self):

        self.MyLongThread = QThread()
        MyLongWorker = MyWorker(self, Qty)
        MyLongWorker.moveToThread(self.MyLongThread)

        self.MyLongThread.started.connect(MyLongWorker.Run_LongWorker)
        MyLongWorker.WorkerFinished.connect(self.MyLongThread.quit)
        MyLongWorker.WorkerFinished.connect(self.MyLongWorker.deleteLater)
        MyLongThread.finished.connect(self.MyLongThread.deleteLater)

        MyLongThread.start()


    def Slot_Worker_Sent_A_Signal (self, Result):

        print ("Worker sent this result: " + str(Result))
        .
        .
        .
MyWorker's code

    class MyWorker(QObject):

    WorkerFinished = Signal()
    CustomSignal = Signal(int)

    def __init__(self, parent, Quantity)

        super().__init__(parent)
        self_parent = parent
        self.Quantity = Quantity
        print("Myworker's constructor")

    def __del__(self):
        print("Myworker's destructor")


    def Run_LongWorker (self):

        self.CustomSignal.connect(self.parent.Slot_Worker_Sent_A_Signal)
        .
        .
        .
        self.CustomSignal.emit(MyPartialResult)
        .
        .
        .
        self.WorkerFinished.emit()
This code is running in a test environment from some weeks ago while I finish some details of the GUI, and I didn't see anything wrong. Yesterday searching in the web I casually noticed that QObject::moveToThread can't move objects with a parent

[1]]https:[//forum.qt.io/topic/40653/qobject-movetothread-cannot-move-objects-with-a-parent][1]

so I'm afraid that my code may have problems that I have not yet detected.

I modified this part of code, and now it is:

New code for main Thread
    #New slot for clicked button.
    def Slot_Start_Calculation (self):

        MyLongThread = QThread()
        MyLongWorker = MyWorker(Qty)
        MyLongWorker.moveToThread(MyLongThread)

        MyLongThread.started.connect(MyLongWorker.Run_LongWorker)
        MyLongWorker.WorkerFinished.connect(MyLongThread.quit)
        MyLongWorker.WorkerFinished.connect(MyLongWorker.deleteLater)
        MyLongThread.finished.connect(MyLongThread.deleteLater)

        MyLongThread.start()


    def Slot_Worker_Sent_A_Signal (self, Result):

        print ("Worker sent this result: " + str(Result))
        .
        .
        .
New code for MyWorker

class MyWorker(QObject):

    WorkerFinished = Signal()
    CustomSignal = Signal(int)

    def __init__(self, Quantity)

        super().__init__()
        self.Quantity = Quantity
        print("Myworker's constructor")

    def __del__(self):
        print("Myworker's destructor")

    def Run_LongWorker (self):

        self.CustomSignal.connect( ??? .Slot_Worker_Sends_A_Signal)
        .
        .
        .
        self.CustomSignal.emit(MyPartialResult)
        .
        .
        .
        self.WorkerFinished.emit()
So, now, I don't really know how to connect this signal to a slot that lives in main thread, cause if I'm not wrong, there is no parent/children relation since I changed thread affinity.

Could someone please tell me if there is a way to do this, and guide me towards documentation about this problem?

Many thanks in advance.
Reply
#2
Here's something to read: http://greenteapress.com/semaphores/Litt...phores.pdf
Reply
#3
Thank you very much Larz60+. I will read it, and I will publish my solution if I can find it.

Regards
Reply
#4
Hi again.

I read the document that Larz60+ recommended (very good and interesting), but I still can't see how to deal with a solution to my specific problem.

Thing that misleads me is how can I use a semaphore in my main thread (if this is the resource that Larz60+ suggested me) beacuse main thread is a GUI with an event loop in which, if I wait for a signal from the Worker, I´m leaving hung all functions of the front end.

Sorry cause trying to be simple I was very inespecific with the function of the worker. I think that the important thing to take in account is that this worker makes a job than can be running for many minutes, then has to inform a partial result to main thread and keep running for a while.

Could someone please tell me if I'm wrong, or guide me in the right direction?

Many thanks in advance!
Reply
#5
Finally, I think I found an answer. In constructor of the Worker class, I had to change the parent object reference and the super class init calling.

class MyWorker(QObject):
 
WorkerFinished = Signal()
CustomSignal = Signal(int)
 
def __init__(self, parent = None, Quantity)
 
    super().__init__()
    self.Quantity = Quantity
    print("Myworker's constructor")
 
def __del__(self):
    print("Myworker's destructor")
 
 
def Run_LongWorker (self):
 
    self.CustomSignal.connect(self.parent.Slot_Worker_Sent_A_Signal)
    .
    .
    .
    self.CustomSignal.emit(MyPartialResult)
    .
    .
    .
    self.WorkerFinished.emit()
And now everything is working as expected.

If somebody sees a problem with that code, please feel free to tell me.

Thanks!
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Suspending worker threads olderguy 1 2,011 Apr-21-2021, 10:28 AM
Last Post: Larz60+
  Receive data from Redis RQ worker process freak14 0 1,891 Jul-15-2019, 12:39 PM
Last Post: freak14
  Good way to have a worker queue accessible by multiple process? cheater 2 2,496 Dec-21-2017, 09:30 PM
Last Post: wavic
  Worker thread? micko 1 3,026 Feb-27-2017, 09:52 AM
Last Post: Ofnuts

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020