Passing parameter to a pyqt thread when started
Asked Answered
D

1

6

Is there any way we can pass a parameter to QThread when the thread is started (.start) ?

I found an example of using pyqt thread in stackoverflow, but I was wondering how to pass a parameter, in case I want the worker thread to process a data that I pass to its run() function.

The post I refer to: Busy indication with PyQt progress bar

The code:

class MyCustomWidget(QtGui.QWidget):

    def __init__(self, parent=None):
        super(MyCustomWidget, self).__init__(parent)
        layout = QtGui.QVBoxLayout(self)       

        self.progressBar = QtGui.QProgressBar(self)
        self.progressBar.setRange(0,100)
        button = QtGui.QPushButton("Start", self)
        layout.addWidget(self.progressBar)
        layout.addWidget(button)

        button.clicked.connect(self.onStart)

        self.myLongTask = TaskThread()
        self.myLongTask.notifyProgress.connect(self.onProgress)


    def onStart(self):
        self.myLongTask.start()

    def onProgress(self, i):
        self.progressBar.setValue(i)


class TaskThread(QtCore.QThread):
    notifyProgress = QtCore.pyqtSignal(int)
    def run(self):
        for i in range(101):
            self.notifyProgress.emit(i)
            time.sleep(0.1)

I want to pass a variable when calling .start such as

self.myLongTask.start(myvar)
.
.
def run(self, myvar):

but of course, pyqt does not allow that.

Denny answered 15/10, 2015 at 2:15 Comment(5)
Is there a reason you would not want to pass the parameter using the signal/slot mechanism once the thread is already started?Histamine
As I understood, the signal/slot like the code above is can be used to send param from TaskThread to MyCustomWidget. What I want is to send param from the MyCustomWidget to TaskThread.Denny
It is possible to signals/slots both ways, but why not just pass the parameter in at thread instantiation time?Hedva
It is possible to send both ways? Can you give an example? Thanks! The reason is I want to pass new value of the param passed each time I start the thread. That new value will be processed by the thread run().Denny
@Denny Sorry about this being 4 months late. I hadn't forgotten your request for an example. This answer I just wrote demonstrates similar behaviour. It demonstrates signal emission in both directions. You would just need to modify it to pass a parameter when the signals are emitted in the desired direction.Hedva
E
7

You can not pass argument to run but you can pass argument to it's constructor like this:

class TaskThread(QtCore.QThread):
    notifyProgress = QtCore.pyqtSignal(int)
    def __init__(self, myvar, parent=None):
        QThread.__init__(self, parent)
        self.myvar = myvar
    def run(self):
        #use self.myvar in your run 
        for i in range(101):
            self.notifyProgress.emit(i)
            time.sleep(0.1)

and in the MyCustomWidget class:

class MyCustomWidget(QtGui.QWidget):

    def __init__(self, parent=None):
        super(MyCustomWidget, self).__init__(parent)
        layout = QtGui.QVBoxLayout(self)       

        self.progressBar = QtGui.QProgressBar(self)
        self.progressBar.setRange(0,100)
        button = QtGui.QPushButton("Start", self)
        layout.addWidget(self.progressBar)
        layout.addWidget(button)

        button.clicked.connect(self.onStart)
        ##############################################################
        #and pass your argumetn to it's constructor here
        self.myLongTask = TaskThread(myvar=myargument)
        ##############################################################
        self.myLongTask.notifyProgress.connect(self.onProgress)


    def onStart(self):
        self.myLongTask.start()

    def onProgress(self, i):
        self.progressBar.setValue(i)
Endotoxin answered 15/10, 2015 at 14:17 Comment(1)
Thanks for the code. It actually gives out error: AttributeError: 'PyQt4.QtCore.pyqtSignal' object has no attribute 'connect' But if we move the self.notifyProgress = QtCore.pyqtSignal(int) outside and above init, it works.Denny

© 2022 - 2024 — McMap. All rights reserved.