启动PyQt线程时传递参数

6

在使用QThread启动线程(.start)时,有没有办法传递参数?

我在stackoverflow上找到了一个使用pyqt线程的示例,但我想知道如何传递参数,以防我希望工作线程处理我传递给其run()函数的数据。

我参考的帖子:PyQt进度条繁忙指示

代码:

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)

我希望在调用.start时传递一个变量,例如

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

但当然,PyQt 不允许那样做。


1
一旦线程已经启动,您是否有不想使用信号/槽机制传递参数的原因? - paisanco
据我理解,像上面的代码一样的信号/槽可以用来从TaskThread发送参数到MyCustomWidget。我想要的是从MyCustomWidget发送参数到TaskThread。 - electro
2
可以双向使用信号/槽,但为什么不在线程实例化时直接传递参数呢? - three_pineapples
可以双向发送吗?你能举个例子吗?谢谢!原因是我想在每次启动线程时传递新的参数值。这个新值将由线程的run()方法处理。 - electro
@electro 很抱歉这个回复晚了4个月。我没有忘记你的示例请求。我刚写的这个答案演示了类似的行为。它展示了信号在两个方向上的发射。你只需要修改它,在信号在所需方向上发射时传递一个参数即可。 - three_pineapples
1个回答

7

您不能将参数传递给run,但是可以像这样将参数传递给它的构造函数:

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)

MyCustomWidget 类中:

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)

1
感谢您的代码。实际上它会出现错误:AttributeError: 'PyQt4.QtCore.pyqtSignal' 对象没有属性 'connect'。但是如果我们将 self.notifyProgress = QtCore.pyqtSignal(int) 移到 init 之外并在其上方,它就可以工作了。 - electro

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接