Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/cmake/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python中的线程完成事件_Python_Delegates_Multithreading - Fatal编程技术网

Python中的线程完成事件

Python中的线程完成事件,python,delegates,multithreading,Python,Delegates,Multithreading,我有一个PyQt程序,在这个程序中,我启动了一个新线程来绘制复杂的图像。 我想知道线程何时完成,以便我可以在表单上打印图像 我面临的唯一障碍是,我需要从GUI线程内部调用绘图方法,因此我需要一种方法来告诉GUI线程从绘图线程内部执行某些操作 我可以用一个线程来完成,但是程序停止了 我以前用C#做这件事,用的是一个有需要完成的事件的后台工作人员 有没有一种方法可以在Python中完成这样的事情?或者我应该侵入PyQt应用程序的主循环并对其进行一些更改吗?在使用的示例中,有一个Mandelbrot应

我有一个PyQt程序,在这个程序中,我启动了一个新线程来绘制复杂的图像。 我想知道线程何时完成,以便我可以在表单上打印图像

我面临的唯一障碍是,我需要从GUI线程内部调用绘图方法,因此我需要一种方法来告诉GUI线程从绘图线程内部执行某些操作

我可以用一个线程来完成,但是程序停止了

我以前用C#做这件事,用的是一个有需要完成的事件的后台工作人员


有没有一种方法可以在Python中完成这样的事情?或者我应该侵入PyQt应用程序的主循环并对其进行一些更改吗?

在使用的示例中,有一个Mandelbrot应用程序。在我的安装中,源代码位于C:\Python26\Lib\site packages\PyQt4\examples\threads\mandelbrot.pyw中。它使用一个线程来呈现pixmap,并使用一个信号(在代码中搜索QtCore.signal)来告诉GUI线程绘制时间。看起来像您想要的。

我相信您的绘图线程可以使用QApplication.postEvent向主线程发送事件。您只需要选择一些对象作为事件的接收者

扩展Jeff的答案:声明可以使事件处理程序(Qt术语中的插槽)在“拥有”对象的线程中执行


因此,在您的情况下,您需要在表单上定义一个插槽打印图像(QImage),并在创建图像的任何对象上定义一个doneDrawing(QImage)信号,然后使用排队或自动连接将它们连接起来。

我的一个项目也有类似的问题,并使用信号告诉我的主GUI线程何时显示工作人员的结果并更新进度条

请注意,在中有几个连接对象和信号的示例。并非所有这些都适用于python(我花了一段时间才意识到这一点)

下面是将python信号连接到python函数的示例

QtCore.QObject.connect(a, QtCore.SIGNAL("PySig"), pyFunction)
a.emit(QtCore.SIGNAL("pySig"), "Hello", "World")
另外,不要忘了将
\uuuuuqtsignals\uuuuuu=(“PySig”)
添加到您的工人类中

以下是我所做工作的精简版本:

class MyGui(QtGui.QMainWindow):

    def __init__(self, parent=None):
        QtGui.QMainWindow.__init__(self, parent)
        self.worker = None

    def makeWorker(self):
        #create new thread
        self.worker = Worker(work_to_do)
        #connect thread to GUI function
        QtCore.QObject.connect(self.worker, QtCore.SIGNAL('progressUpdated'), self.updateWorkerProgress)
        QtCore.QObject.connect(self.worker, QtCore.SIGNAL('resultsReady'), self.updateResults)
        #start thread
        self.worker.start()

    def updateResults(self):
        results = self.worker.results
        #display results in the GUI

    def updateWorkerProgress(self, msg)
        progress = self.worker.progress
        #update progress bar and display msg in status bar


class Worker(QtCore.QThread):

    __pyqtSignals__ = ( "resultsReady", 
                        "progressUpdated" )

    def __init__(self, work_queue):
        self.progress = 0  
        self.results = []
        self.work_queue = work_queue
        QtCore.QThread.__init__(self, None)

    def run(self):
        #do whatever work
        num_work_items = len(self.work_queue)
        for i, work_item in enumerate(self.work_queue):
            new_progress = int((float(i)/num_work_items)*100)
            #emit signal only if progress has changed
            if self.progress != new_progress:
                self.progress = new_progress
                self.emit(QtCore.SIGNAL("progressUpdated"), 'Working...')
            #process work item and update results
            result = processWorkItem(work_item)
            self.results.append(result)
        self.emit(QtCore.SIGNAL("resultsReady"))