【问题标题】:pyqtgraph exporting from API within PyQt4 widget fails / crashes python从 PyQt4 小部件中的 API 导出的 pyqtgraph 失败/崩溃 python
【发布时间】:2015-02-16 05:46:37
【问题描述】:

我有一个使用 PyQt4 和 pyqtgraph 构建的小型应用程序。我想在调用 pyqtgraph 可用的导出器时添加一些按钮(而不是使用当用户右键单击绘图时弹出的上下文菜单)。

然而,到目前为止,我还不能让它工作。

这是应用程序的简化版本:

from PyQt4 import QtCore, QtGui
import pyqtgraph as pg
import pyqtgraph.exporters
import numpy as np
import sys


class SimpleUI(QtGui.QWidget):

    def __init__(self):
        QtGui.QWidget.__init__(self)

        self.resize(1500, 1000)
        self.plot_widget = pg.GraphicsLayoutWidget(self)
        self.layout = QtGui.QVBoxLayout(self)

        data = np.arange(10)
        self.plt = self.plot_widget.addPlot()
        self.plt.plot(data)

        self.export_btn = QtGui.QPushButton("Export")
        self.export_btn.clicked.connect(self.export)

        self.layout.addWidget(self.plot_widget)
        self.layout.addWidget(self.export_btn)

    def export(self):
        img = pg.exporters.ImageExporter(self.plt)
        img.export()


if __name__ == '__main__':
    app = QtGui.QApplication(sys.argv)
    ex = SimpleUi()
    ex.show()
    sys.exit(app.exec_())

在这种情况下单击“导出”按钮会导致对话框快速弹出然后消失。

如果我把

img.export(copy=True)

并尝试将剪贴板上的内容粘贴到某些内容(绘画等)中,python.exe 崩溃。

奇怪的是,通过 pyqtgraph 默认可用的上下文菜单导出效果很好。此外,只需在终端中工作,我就可以使用与上面完全相同的代码行来复制/保存 plotItems。即:

import numpy as np
import pyqtgraph as pg
import pyqtgraph.exporters

plt = pg.plot(np.arange(10))
img = pg.exporters.ImageExporter(plt.plotItem)
img.export()

这对我来说意味着导出器工作正常,但是当它们以我调用它们的方式从 pyqt4 小部件中调用时,会发生一些奇怪的交互。

我已经尝试了 pyqtgraph 0.9.8 以及 github 上的主分支。非常不知道这里有什么问题

谢谢

【问题讨论】:

    标签: python pyqt4 pyqtgraph


    【解决方案1】:

    您似乎没有将img 存储在任何地方,因此在对export() 的调用返回时立即收集它。

    解释:

    1. Python 中的对象仅在需要时才保存在内存中。当 Python 确定不再需要某个对象时,它会删除该对象。

    2. Python 如何知道何时不再需要某个对象?通过计数引用。当您执行img = ImageExporter(...) 时,会创建一个具有一个引用的新对象:局部变量img

    3. 在函数内部创建的变量被认为是该函数范围内的本地变量。当函数退出时,变量img消失,导致ImageExporter对象的引用计数下降到0,从而导致Python删除该对象。

    4. 1234563函数返回后继续存在)。这允许对象在 SimpleUI 仍然持有引用时一直存在。

    【讨论】:

    • 因此将 img 更改为实例变量(即 self.img)可以解决问题。不过,我不清楚为什么。我敢肯定这是一个相对基本的cs问题,但你介意解释一下发生了什么吗?例如,如果我将 print(img) 添加到导出函数,我会在内存位置获得一个导出器对象。为什么由于在同一个函数中调用了 img.export() 对象没有保存/使用?
    • 感谢您的解释。我以为我对所有这些都有相当的了解,但我想不是。那么,我假设通过调用 img.export() 我们离开了导出函数的范围,这就是 img 对象丢失的原因?
    • 不,调用img.export()只会打开文件对话框然后立即返回,此时SimpleUI.export()也返回并删除img
    • 我知道一旦 SimpleUI.export() 返回 img 就会丢失。我无法理解的是为什么这很重要。 img.export() 的目的是从 img 生成文件(或将 png 添加到剪贴板),对吗?当 img.export() 返回时,该操作已完成,不是吗?这就是为什么我不清楚为什么 img 需要在 SimpleUI.export() 完成之后持续存在。很抱歉,如果发生的事情应该很明显,但感谢您花时间解释
    • 调用img.export() 显示文件对话框并立即返回。直到用户决定文件名并按下“保存”后,才会进行实际导出,此时 img 已被删除。
    猜你喜欢
    • 2017-06-30
    • 1970-01-01
    • 2016-12-11
    • 1970-01-01
    • 2021-05-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-08
    相关资源
    最近更新 更多