在嵌入式PyQt应用程序中使用QThread 我在C++中编写了一个Qt应用程序,它嵌入Python解释器,并使用PyQT来允许脚本化用户界面进行数据分析。Python代码对数据进行一些计算,并返回一个QWidget(包含各种绘图等),插入到主应用程序中 我想从Python中派生一个新的Q线程,以便允许控件返回到C++应用程序,这样繁重的计算不会阻塞GUI运行的主线程。问题是,一旦控制返回到C++应用程序,线程就会进入睡眠状态,直到Python解释器再次被调用,例如MyPuttLIB图上的鼠标事件。我怀疑这是Python的GIL造成的
在控制传递回嵌入应用程序后,如何让从Python创建的QThread继续运行 我正在使用以下代码进行测试。嵌入应用程序调用test_thread()并将返回的容器添加到QTabwidget。线程仅在我在matplotlib绘图上生成鼠标事件时执行在嵌入式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
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解释器继续运行。如果嵌入应用程序不允许python继续运行,那么任何试图绕过这一点的尝试都会导致问题。我对python中的线程还不熟悉,但我的理解是,我仍然可以生成多个线程,GIL只是阻止它们同时运行。我可以看到这是Python中多线程的限制,但是我不能在PC++线程旁边运行一个Python线程吗?我是否忽略了什么?从Python开始的线程与其他Python开始的线程一起被阻塞。那么,主Python线程正在阻塞我正在创建的新线程?是否不可能以某种方式释放GIL以允许其他线程运行?有几种方法可以从C/C++扩展中释放GIL。这些都是按照。如果嵌入应用程序正在调用python,那么就取决于嵌入应用程序如何执行python。您无法通过创建线程(甚至在python之外)来真正避免这种情况,因为python解释器必须运行,以在工作程序和嵌入应用程序之间提供粘合。需要明确的是,在您的情况下,python解释器似乎是由第三方应用程序启动的,第三方应用程序控制python。当控制返回到该应用程序时,python将失去GIL。让python继续运行取决于第三方应用程序。你不能在口译员内部回避这个问题。