簡體   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