繁体   English   中英

在嵌入式PyQt应用程序中使用QThread

[英]Using QThread in embedded PyQt application

我用c ++编写了一个Qt应用程序,它嵌入了Python解释器并利用PyQt来允许用于数据分析的脚本化用户界面。 Python代码对数据进行一些计算并返回一个插入主应用程序的QWidget(包含各种图等)。

我想从Python生成一个新的QThread以允许控制返回到c ++应用程序,以便繁重的计算不会阻止GUI运行的主线程。 问题是,只要控制权返回到c ++应用程序,线程就会进入睡眠状态,直到再次以某种方式调用Python解释器,例如。 matplotlib图上的mouseover事件。 我怀疑这是由于Python的GIL。

如何在控件传递回嵌入应用程序后继续运行从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或Global Interpreter Lock,CPython是单线程的。 你不能从python运行多于1个并发线程。

https://wiki.python.org/moin/GlobalInterpreterLock

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

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

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

这是嵌入式应用程序的100%。 必须允许python解释器继续由嵌入应用程序运行。 如果嵌入应用程序不允许python继续运行,那么任何绕过它的尝试都会导致问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM