I'm making a PyQt5 application with embedded matplotlib canvas. I need to add custom tools to Matplotlib toolbar that can be toggled in the same way as Matplotlib's default tools "zoom" and "pan". Problem is that Matplotlib's NavigationToolbar2QT-class doesn't seem to have functions to directly add tools unlike ToolbarQt, which I can't get working.
Here is a simplified version of my trial code using NavigationToolbar2QT:
import sys
from PyQt5 import QtWidgets, uic
from matplotlib.backends.backend_qt5agg import (
FigureCanvas, NavigationToolbar2QT as NavigationToolbar)
from matplotlib.figure import Figure
ui_file = 'user_interface.ui'
class ToolBar(NavigationToolbar):
def __init__(self, figure_canvas, parent=None):
NavigationToolbar.__init__(self, figure_canvas, parent=None)
# Add custom tools here
class MplWidget(QtWidgets.QWidget):
def __init__(self, parent=None):
QtWidgets.QWidget.__init__(self, parent)
self.canvas = FigureCanvas(Figure())
layout = QtWidgets.QVBoxLayout()
layout.addWidget(self.canvas)
self.setLayout(layout)
self.canvas.figure.add_subplot(111)
self.canvas.draw()
class Ui(QtWidgets.QMainWindow):
def __init__(self):
super(Ui, self).__init__()
uic.loadUi(ui_file, self)
self.toolbar = ToolBar(self.MplWidget.canvas)
self.ToolBarLayout.addWidget(self.toolbar)
self.show()
app = QtWidgets.QApplication(sys.argv)
window = Ui()
sys.exit(app.exec_())
I know I can add new tools to my custom ToolBar-class by adding it to NavigationToolbar2QT's toolitems, but I can't implement the toggle functionality by doing this.
I also tried to do this with ToolbarQt:
import sys
from PyQt5 import QtWidgets, uic
from matplotlib.backends.backend_qt5 import ToolbarQt
from matplotlib.backends.backend_qt5agg import FigureCanvas
from matplotlib.backend_managers import ToolManager
from matplotlib import backend_tools
from matplotlib.figure import Figure
from matplotlib import pyplot
import matplotlib
pyplot.rcParams['toolbar'] = 'toolmanager'
matplotlib.use('Qt5Agg')
ui_file = 'user_interface.ui'
class MplWidget(QtWidgets.QWidget):
def __init__(self, parent=None):
QtWidgets.QWidget.__init__(self, parent)
self.canvas = FigureCanvas(Figure())
layout = QtWidgets.QVBoxLayout()
layout.addWidget(self.canvas)
self.setLayout(layout)
self.canvas.figure.add_subplot(111)
self.canvas.draw()
class Ui(QtWidgets.QMainWindow):
def __init__(self):
super(Ui, self).__init__()
uic.loadUi(ui_file, self)
self.tool_manager = ToolManager(self.MplWidget.canvas.figure)
backend_tools.add_tools_to_manager(self.tool_manager)
self.toolbar = ToolbarQt(self.tool_manager, self)
backend_tools.add_tools_to_container(self.toolbar)
self.ToolBarLayout.addWidget(self.toolbar)
# Add custom tool here
self.show()
app = QtWidgets.QApplication(sys.argv)
window = Ui()
sys.exit(app.exec_())
In this case, however, even the default tools will cause the following error even though Qt5-backend is used.
AttributeError: 'FigureCanvasQTAgg' object has no attribute '_tkcanvas'