【问题标题】:Passing parameter to a pyqt thread when started启动时将参数传递给pyqt线程
【发布时间】:2016-01-13 07:56:48
【问题描述】:

有什么方法可以在线程启动时将参数传递给QThread(.start)?

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

我参考的帖子:Busy indication with PyQt progress bar

代码:

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 不允许这样做。

【问题讨论】:

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

标签: python pyqt pyqt4 qthread


【解决方案1】:

您不能将参数传递给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)

【讨论】:

  • 感谢您的代码。它实际上给出了错误: AttributeError: 'PyQt4.QtCore.pyqtSignal' object has no attribute 'connect' 但是如果我们将 self.notifyProgress = QtCore.pyqtSignal(int) 移到 init 之外和之上,它工作。
猜你喜欢
  • 1970-01-01
  • 2011-12-13
  • 2011-02-18
  • 2022-08-05
  • 2014-05-16
  • 2015-03-08
  • 2014-01-05
相关资源
最近更新 更多