在嵌入式PyQt应用程序中使用QThread 我在C++中编写了一个Qt应用程序,它嵌入Python解释器,并使用PyQT来允许脚本化用户界面进行数据分析。Python代码对数据进行一些计算,并返回一个QWidget(包含各种绘图等),插入到主应用程序中 我想从Python中派生一个新的Q线程,以便允许控件返回到C++应用程序,这样繁重的计算不会阻塞GUI运行的主线程。问题是,一旦控制返回到C++应用程序,线程就会进入睡眠状态,直到Python解释器再次被调用,例如MyPuttLIB图上的鼠标事件。我怀疑这是Python的GIL造成的

在嵌入式PyQt应用程序中使用QThread 我在C++中编写了一个Qt应用程序,它嵌入Python解释器,并使用PyQT来允许脚本化用户界面进行数据分析。Python代码对数据进行一些计算,并返回一个QWidget(包含各种绘图等),插入到主应用程序中 我想从Python中派生一个新的Q线程,以便允许控件返回到C++应用程序,这样繁重的计算不会阻塞GUI运行的主线程。问题是,一旦控制返回到C++应用程序,线程就会进入睡眠状态,直到Python解释器再次被调用,例如MyPuttLIB图上的鼠标事件。我怀疑这是Python的GIL造成的,python,c++,multithreading,qt,pyqt4,Python,C++,Multithreading,Qt,Pyqt4,在控制传递回嵌入应用程序后,如何让从Python创建的QThread继续运行 我正在使用以下代码进行测试。嵌入应用程序调用test_thread()并将返回的容器添加到QTabwidget。线程仅在我在matplotlib绘图上生成鼠标事件时执行 import time from PyQt4 import QtCore, QtGui from PyQt4.QtCore import pyqtSignal, pyqtSlot from matplotlib.figure import Figu

在控制传递回嵌入应用程序后,如何让从Python创建的QThread继续运行

我正在使用以下代码进行测试。嵌入应用程序调用test_thread()并将返回的容器添加到QTabwidget。线程仅在我在matplotlib绘图上生成鼠标事件时执行

import time

from PyQt4 import QtCore, QtGui
from PyQt4.QtCore import pyqtSignal, pyqtSlot

from matplotlib.figure import Figure
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas

app = QtGui.QApplication.instance()  

class Worker(QtCore.QObject):
    finished = pyqtSignal()

    def __init__(self):
        QtCore.QObject.__init__(self)

    def do_work(self):
        for i in range(0, 10):
            print 'worker running'
            time.sleep(1)

        self.finished.emit()


class Controller(QtCore.QObject):
    def __init__(self):
        QtCore.QObject.__init__(self)

        self.thread = QtCore.QThread()
        self.worker = Worker()
        self.worker.moveToThread(self.thread)
        self.worker.finished.connect(self.thread.quit)
        self.thread.started.connect(self.worker.do_work)
        self.thread.finished.connect(app.exit)

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


class Container(QtGui.QWidget):
    def __init__(self):
        QtGui.QWidget.__init__(self)

        self.controller = Controller()
        self.controller.start_thread()

        self.fig = Figure(dpi=72, facecolor=(1, 1, 1), edgecolor=(0, 0, 0))
        self.fig.add_subplot(111)
        self.canvas = FigureCanvas(self.fig)

        self.layout = QtGui.QVBoxLayout()
        self.layout.addWidget(self.canvas)

        self.setLayout(self.layout)


def test_thread():
    container = Container()
    return container

由于GIL或全局解释器锁,CPython是单线程的。从python运行的并发线程不能超过1个

Qt并没有在这里阻止您,python才是。这里唯一的解决方法是为工作线程生成单独的python进程,然后使用IPC(套接字、共享内存等)在进程之间进行通信。Qt为这些IPC机制提供接口。您只需序列化进程间通信

这假设您询问的是并发性。关于其他问题,编辑答案以澄清管辖权

在控制传递回嵌入应用程序后,如何让从Python创建的QThread继续运行


这完全取决于嵌入应用程序。嵌入应用程序必须允许python解释器继续运行。如果嵌入应用程序不允许python继续运行,那么任何试图绕过这一点的尝试都会导致问题。

我对python中的线程还不熟悉,但我的理解是,我仍然可以生成多个线程,GIL只是阻止它们同时运行。我可以看到这是Python中多线程的限制,但是我不能在PC++线程旁边运行一个Python线程吗?我是否忽略了什么?从Python开始的线程与其他Python开始的线程一起被阻塞。那么,主Python线程正在阻塞我正在创建的新线程?是否不可能以某种方式释放GIL以允许其他线程运行?有几种方法可以从C/C++扩展中释放GIL。这些都是按照。如果嵌入应用程序正在调用python,那么就取决于嵌入应用程序如何执行python。您无法通过创建线程(甚至在python之外)来真正避免这种情况,因为python解释器必须运行,以在工作程序和嵌入应用程序之间提供粘合。需要明确的是,在您的情况下,python解释器似乎是由第三方应用程序启动的,第三方应用程序控制python。当控制返回到该应用程序时,python将失去GIL。让python继续运行取决于第三方应用程序。你不能在口译员内部回避这个问题。