如何找到类似于“matplotlib.pyplot.gcf()”工作方式的打开的 pyqtgraph GraphicsWindow?

How can I find an open pyqtgraph GraphicsWindow similar to how 'matplotlib.pyplot.gcf()` works?

我想要 pyqtgraph 对应 matplotlib.pyplot.gcf() 函数,returns 引用当前图形。我想要一个 returns 对当前 pyqtgraph GraphicsWindow 实例的引用的函数。有办法吗?

pyqtgraph中没有隐含的"current figure"概念;每个 window 或图形对象都应明确引用。例如:

plot_window = pg.plot()

# Add data to this plot:
plot_curve = plot_window.plot(data)

# Update data in this curve:
plot_curve.setData(data)

如果你只想获取当前活动的window,那么Qt可以提供:http://doc.qt.io/qt-5/qapplication.html#activeWindow

这可以通过

  1. 创建跟踪的全局列表windows
  2. 子类化 pg.GraphicsWindowpg.PlogWidget(假设您 import pyqtgraph as pg
  3. 将子类 window/widget 的新创建实例添加到全局跟踪列表
  4. 覆盖 closeEvent 以便在跟踪器关闭时从跟踪器中删除 windows。

这是因为 the way python caches imported modules,所以再次导入 tracking.tracker 应该访问相同的变量。

例如:使tracking.py:

import warnings


class WTracker:

    def __init__(self):
        self.open_windows = []

    def window_closed(self, win):
        if win in self.open_windows:
            self.open_windows.remove(win)
        else:
            warnings.warn('  tracker received notification of closing of untracked window!')

    def window_opened(self, win):
        self.open_windows += [win]


tracker = WTracker()

然后figure.py:

import pyqtgraph as pg
from tracking import tracker


class Figure(pg.GraphicsWindow):
    def __init__(self):
        super(Figure, self).__init__()
        tracker.window_opened(self)

    def closeEvent(self, event):
        tracker.window_closed(self)
        event.accept()

终于可以实现了gcf();让我们把它放在 pyplot.py:

from tracking import tracker
from figure import Figure


def gcf():
    if len(tracker.open_windows):
        return tracker.open_windows[-1]
    else:
        return Figure()

然后用tester.py测试:

import sys
from PyQt4 import QtGui
from figure import Figure
from pyplot import gcf

app = QtGui.QApplication(sys.argv)

fig1 = gcf()
fig2 = gcf()
fig3 = Figure()
fig4 = gcf()
fig4.close()
fig5 = gcf()

print('fig2 is fig1 = {}'.format(fig2 is fig1))
print('fig3 is fig1 = {}'.format(fig3 is fig1))
print('fig4 is fig3 = {}'.format(fig4 is fig3))
print('fig5 is fig3 = {}'.format(fig5 is fig3))
print('fig5 is fig1 = {}'.format(fig5 is fig1))

结果:

$ python tester.py
fig2 is fig1 = True
fig3 is fig1 = False
fig4 is fig3 = True
fig5 is fig3 = False
fig5 is fig1 = True

子类化 pg.PlotWidget 而不是 pg.GraphicsWindow 是可行的,但是你必须创建一个布局,将其设置为中心项,然后 运行 self.show().