将matplotlib与Qt5后端配合使用,并在同一进程中运行现有QApplication

问题描述 投票:0回答:2

我们有一个使用PySide2的Qt5应用程序。最近,我们想在我们的PySide2应用程序在同一进程中(在不同线程中)运行时使用matplotlib显示图,但是随后matplotlib崩溃(使用PySide2时)或在绘制之前冻结(使用PyQt5时)。

这里是最小样本,请取消注释第23行以使matplotlib崩溃或冻结:

from threading import Thread

from PySide2.QtWidgets import QApplication, QLabel

import matplotlib
matplotlib.use('QT5Agg')
import matplotlib.pyplot as plt


def start_qt_app():
    t = Thread(target=qt_app_thread_func)
    t.start()


def qt_app_thread_func():
    app = QApplication()
    label = QLabel("Hello World")
    label.show()
    app.exec_()


# Uncomment the line below to make matplotlib crash.
#start_qt_app()

plt.plot([1, 2, 3, 4])
plt.show()

input("Press enter to quit.")

print("Finished.")

我的猜测是,这与我们在一个进程中只能运行1个QApplication的限制有关。因此,这会导致matplotlib中出现问题。

我该如何解决这个问题?我想到的一个解决方案是为matplotlib创建一个代理对象,该代理对象在另一个进程中运行matplotlib,但是我不确定这是否是最不费力的解决方案。也许我可以使matplotlib使用现有的QApplication?我无法在另一个进程中运行我们的PySide2应用程序,因为它使用动态创建的numpy数组将其从主线程传递到GUI,并且在另一个进程中启动它会降低性能。

matplotlib pyside2
2个回答
0
投票

您应该使用asyncqt来管理ui和应用程序线程。从asyncqt使用QEventLoop是可以通过]完成的一种方法>

await loop.run_in_executor(exec, method_name)

asyncqt是quamash的衍生库,是为PyQt5编写的。示例代码相同。因此,根据您的喜好,您可以将asyncqt与PySide2结合使用,或者将quamash与PyQt5结合使用,以在运行后台任务时使您的应用程序具有响应能力。

asyncqt examples

asyncqt 0.7.0 pypi

Quamash 0.6.1


0
投票

[@ImportanceOfBeingErnest指出,如官方示例所示,matplotlib可以与Qt一起使用:@ImportanceOfBeingErnest

© www.soinside.com 2019 - 2024. All rights reserved.