从 C++ 嵌入式解释器捕获 python 窗口输出

Posted

技术标签:

【中文标题】从 C++ 嵌入式解释器捕获 python 窗口输出【英文标题】:Capturing python windowed output from C++ embedded interpreter 【发布时间】:2020-01-10 16:35:57 【问题描述】:

我正在使用 boost python 在 C++ 应用程序中嵌入一个 python 解释器。 (pybind11 也可以)

如果我从嵌入式解释器调用 matplotlib,使用如下内容:

import matplotlib.pyplot as plt
import numpy as np
plt.plot([1,2,3,4],[1,4,9,16])
plt.show()

python 解释器会打开一个新窗口(与我的应用程序的主窗口分开)来显示 matplotlib 图。

我知道这是一个远射,但是有什么办法可以拦截它吗? 我希望能够捕获显示在这个单独窗口中的像素,并将它们显示在我的应用程序主窗口的图形上下文中。

我猜这是不可能的,因为我相信窗口正在生成。 但想检查是否有人对此有任何见解。

【问题讨论】:

【参考方案1】:

您可以使用 matplotlib 的hardcopy backends 之一并将画布的像素保存到可以是exported to your C++ context 的字符串中。以下是python代码:

import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot

fig = matplotlib.pyplot.figure()
ax  = fig.add_subplot ( 111 )

ax.plot([1,2,3,4],[1,4,9,16])

fig.canvas.draw ()

w,h = fig.canvas.get_width_height()  # width and height of the canvas
buf = fig.canvas.tostring_argb()     # a byte string of type uint8 

在您的 C++ 代码中,您可以使用变量 whbuf 在主窗口中显示图形。

【讨论】:

谢谢,这很有帮助。我认为没有办法不可知地拦截(不更改 python 代码)? 如果您是这个意思,您可以将 python 代码翻译成相应的 C++ 代码。例如,py::object matplotlib = py::module::import("matplotlib "); py::object mpluse= matplotlib.attr("use");mpluse("Agg"); ...(使用 pybind11) 谢谢。 python 用户仍然需要调用“buf = fig.canvas.tostring_argb()”。但似乎没有办法解决这个问题。

以上是关于从 C++ 嵌入式解释器捕获 python 窗口输出的主要内容,如果未能解决你的问题,请参考以下文章

python - C++ 嵌入式解释器和对象

Matplotlib 和 C++ 中嵌入式 python 的子解释器

使用 c++ 对象的全局实例扩展嵌入式 python 解释器

使用 pybind11 通过预先存在的嵌入式 python 解释器公开 C++ 功能

如何在 C++ 中传递/捕获/响应 Python 的 KeyboardInterrupt?

如何中断嵌入在 C++ 应用程序中的 python 解释器