Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/336.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.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_Multithreading_Pyqt - Fatal编程技术网

Python多线程从子线程发送一个函数在主线程中运行,并等待它完成

Python多线程从子线程发送一个函数在主线程中运行,并等待它完成,python,multithreading,pyqt,Python,Multithreading,Pyqt,我有一个关于python中多线程的问题。基本上在我的软件中,我得到了一个运行起来很昂贵的函数。因此,我把它放在子线程中运行。但是,在函数运行期间,它将调用函数并更改对象的某些值,这将触发GUI更改。因此,我需要把它放回主线程 问题是我需要等待这个函数在主线程中完全完成,然后在子线程中继续这个函数 所以,我需要一种聪明的方法将作业发送回主线程并等待它完成。谁能告诉我怎么做吗 非常感谢。我在下面添加了我的running thread方法 致以最良好的祝愿 import Queue import lo

我有一个关于python中多线程的问题。基本上在我的软件中,我得到了一个运行起来很昂贵的函数。因此,我把它放在子线程中运行。但是,在函数运行期间,它将调用函数并更改对象的某些值,这将触发GUI更改。因此,我需要把它放回主线程

问题是我需要等待这个函数在主线程中完全完成,然后在子线程中继续这个函数

所以,我需要一种聪明的方法将作业发送回主线程并等待它完成。谁能告诉我怎么做吗

非常感谢。我在下面添加了我的running thread方法

致以最良好的祝愿

import Queue
import logging
import sys
import time
import threading


DISABLE_THREADING = False

queue = Queue.Queue()


def run_in_sub_thread_named(name, function, *params):

    if DISABLE_THREADING:
        return function(*params)
    th = _DEThread(function, *params)
    task_info = TaskInfo(name)
    th.task_info = task_info
    running_tasks[th] = task_info
    th.start()
    return th

def run_in_main_thread(function, *params, **kwargs):
    cur_thread = threading.currentThread()
    cur_thread_name = cur_thread.getName()
    in_main_thread = (cur_thread_name == 'MainThread')
    if in_main_thread:
        function(*params, **kwargs)
    else:
        queue.put((function, params, kwargs))



class _DEThread:
    def __init__(self, function, *params):
        self.thread = threading.Thread(target=self.execute)
        self.thread.setDaemon(True)
        self.function = function
        self.params = params
        self.name = ''

    def start(self):
        self.thread.start()

    def execute(self):
        try:
            if self.params is ():
                res = self.function()
            else:
                res = self.function(*self.params)
        except:
            run_in_main_thread(self._update_task_info,
                'Exception: %s' % repr(sys.exc_info()))
            raise
        run_in_main_thread(self._update_task_info, res)

    def _update_task_info(self, res):
        if self in running_tasks:
            task_info = running_tasks[self]
            task_info.end_time = time.time()
            task_info.result = res
            finished_tasks[self] = task_info
            del running_tasks[self]

通常,在Qt中,在线程之间调用函数的方法是使用信号和插槽。您还可以使用调用另一个线程中的函数,并使用
Qt.BlockingQueuedConnection
类型强制它阻塞线程,直到主线程函数完成。不过,您需要使用
QThreads
而不是python
threads
。查看文档中描述的Worker模式,了解如何重构代码以使用
QThreads

def function_in_thread(self):
    # This will block the thread until function completes
    # in main thread.
    QtCore.QMetaObject.invokeMethod(self.main_gui, 'nameOfMethod', QtCore.Qt.BlockingQueuedConnection)

我知道这很旧,所以可能这是自编写以来的一个变化,或者可能是PyQt和PySide2之间的差异,但我只想指出,至少在我的测试中,这似乎适用于python线程,而不仅仅是QThreads。