This is a very simple application done with python and qt, where there is an embedded matplotlib plot. I would like to include the standard toolbar (zoom, home, etc.) over t
To create a NavigationToolbar
you must pass the canvas and a parent, but since these are going to be together, it is advisable to create a widget as shown below:
class WidgetPlot(QWidget):
def __init__(self, *args, **kwargs):
QWidget.__init__(self, *args, **kwargs)
self.setLayout(QVBoxLayout())
self.canvas = PlotCanvas(self, width=10, height=8)
self.toolbar = NavigationToolbar(self.canvas, self)
self.layout().addWidget(self.toolbar)
self.layout().addWidget(self.canvas)
and then I would change m = PlotCanvas(self, width = 10, height = 8)
to m = WidgetPlot(self)
, that would solve your problem.
Plus:
To have an appropriate order it is advisable to use layouts, in the following code I show the same code with layouts:
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QMainWindow, QAction, QVBoxLayout, QHBoxLayout, QLabel, QLineEdit, QSpacerItem, QSizePolicy, QPushButton
from PyQt5.QtGui import QIcon
from PyQt5.QtCore import QSize
from matplotlib.figure import Figure
import matplotlib.pyplot as plt
import random
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.backends.backend_qt5agg import NavigationToolbar2QT as NavigationToolbar
class MainWindow(QMainWindow):
def __init__(self):
QMainWindow.__init__(self)
self.title = 'test'
self.left = 10
self.top = 10
self.width = 1920
self.height = 1080
self.setWindowTitle(self.title)
self.setGeometry(self.left, self.top, self.width, self.height)
self.statusBar().showMessage('Ready')
mainMenu = self.menuBar()
mainMenu.setNativeMenuBar(False)
fileMenu = mainMenu.addMenu('File')
helpMenu = mainMenu.addMenu('Help')
exitButton = QAction(QIcon('exit24.png'), 'Exit', self)
exitButton.setShortcut('Ctrl+Q')
exitButton.setStatusTip('Exit application')
exitButton.triggered.connect(self.close)
fileMenu.addAction(exitButton)
widget = QWidget(self)
self.setCentralWidget(widget)
vlay = QVBoxLayout(widget)
hlay = QHBoxLayout()
vlay.addLayout(hlay)
self.nameLabel = QLabel('Name:', self)
self.line = QLineEdit(self)
self.nameLabel2 = QLabel('Result', self)
hlay.addWidget(self.nameLabel)
hlay.addWidget(self.line)
hlay.addWidget(self.nameLabel2)
hlay.addItem(QSpacerItem(1000, 10, QSizePolicy.Expanding))
pybutton = QPushButton('Click me', self)
pybutton.clicked.connect(self.clickMethod)
hlay2 = QHBoxLayout()
hlay2.addWidget(pybutton)
hlay2.addItem(QSpacerItem(1000, 10, QSizePolicy.Expanding))
vlay.addLayout(hlay2)
m = WidgetPlot(self)
vlay.addWidget(m)
def clickMethod(self):
print('Clicked Pyqt button.')
if self.line.text() == '':
self.statusBar().showMessage('Not a Number')
else:
print('Number: {}'.format(float(self.line.text())*2))
self.statusBar().showMessage('Introduction of a number')
self.nameLabel2.setText(str(float(self.line.text())*2))
class WidgetPlot(QWidget):
def __init__(self, *args, **kwargs):
QWidget.__init__(self, *args, **kwargs)
self.setLayout(QVBoxLayout())
self.canvas = PlotCanvas(self, width=10, height=8)
self.toolbar = NavigationToolbar(self.canvas, self)
self.layout().addWidget(self.toolbar)
self.layout().addWidget(self.canvas)
class PlotCanvas(FigureCanvas):
def __init__(self, parent=None, width=10, height=8, dpi=100):
fig = Figure(figsize=(width, height), dpi=dpi)
FigureCanvas.__init__(self, fig)
self.setParent(parent)
FigureCanvas.setSizePolicy(self, QSizePolicy.Expanding, QSizePolicy.Expanding)
FigureCanvas.updateGeometry(self)
self.plot()
def plot(self):
data = [random.random() for i in range(250)]
ax = self.figure.add_subplot(111)
ax.plot(data, 'r-', linewidth = 0.5)
ax.set_title('PyQt Matplotlib Example')
self.draw()
if __name__ == "__main__":
app = QApplication(sys.argv)
mainWin = MainWindow()
mainWin.show()
sys.exit( app.exec_())
Output: