Search code examples
pythonpython-2.7pyqtgraph

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


I would like a pyqtgraph counterpart to the matplotlib.pyplot.gcf() function, which returns a reference to the current figure. I would like a function that returns a reference to the current pyqtgraph GraphicsWindow instance. Is there a way to do this?


Solution

  • This can be done by

    1. Creating a global list of tracked windows
    2. Subclassing pg.GraphicsWindow or pg.PlogWidget (assuming you import pyqtgraph as pg)
    3. Adding newly created instances of the subclassed window/widget to the global tracking list
    4. Overriding closeEvent so it removes windows from the tracker when they are closed.

    This works because of the way python caches imported modules, so importing tracking.tracker again should access the same variable.

    For example: make 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()
    

    And then 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()
    

    Finally, we can implement gcf(); let's put it in 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()
    

    Then test with 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))
    

    The result:

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

    Subclassing pg.PlotWidget instead of pg.GraphicsWindow works, but then you have to create a layout, set it as the central item, and run self.show().