I try to embed the EditableGraph function into a PyQt5 application. I developed the following program for testing, based on solutions found online.
from PyQt5 import QtWidgets, QtCore
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure
from netgraph import EditableGraph, InteractiveGraph
class MainWindow(QtWidgets.QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.canvas = FigureCanvas(Figure())
self.canvas.ax = self.canvas.figure.add_subplot(111)
self.editgraph = EditableGraph([(0, 1), (1,2), (2,0)],
ax=self.canvas.ax)
# Enable key_press_event events:
self.canvas.setFocusPolicy(QtCore.Qt.ClickFocus)
self.canvas.setFocus()
widget = QtWidgets.QWidget()
self.setCentralWidget(widget)
layout = QtWidgets.QVBoxLayout(widget)
layout.addWidget(self.canvas)
if __name__ == "__main__":
app = QtWidgets.QApplication([])
w = MainWindow()
w.show()
app.exec_()
However I have the following error:
self.fig.canvas.manager.key_press = key_press_handler AttributeError: 'NoneType' object has no attribute 'key_press'
More in detail, the error message is:
Traceback (most recent call last):
File "C:... \testit.py", line 26, in <module>
w = MainWindow()
^^^^^^^^^^^^
File "C:... \testit.py", line 13, in __init__
self.graph = EditableGraph([(0, 1), (1,2), (2,0)], ax=self.canvas.ax)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C: ... \netgraph\_interactive_graph_classes.py", line 1971, in __init__
self.fig.canvas.manager.key_press = key_press_handler
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'key_press'
When I exchange EditableGraph by InteractiveGraph, it works well.
I use the following dev version of NetGraph.
pip install https://github.com/paulbrodersen/netgraph/archive/dev.zip
I don't know where the problem originated from, and I couldn't find a solution on the Web. Can you please help me? This embedding is crucial for my application. Thank you.
Finally I found the solution. The issue is to properly assign a manager to the canvas. First,
matplotlib.figure.Figuredoes not produce a manager whilepyplot.figure()does. In the following program the result isNoneforfig1while it corresponds to an object reference forfig2.However, merely replacing
Figure()withplt.figure()is insufficient because themanageris not copied/exported/transmitted to the canvas. Therefore, this must be achieved explicitly. The final code is as follows:The creation of a matplotlib canvas in PyQT5 is typically defined by a class. Here is the definition of such a class including the manager: