Reputation: 63
I'm working on an app using Python 3.6 and PyQt-5.9.1 with Qt Designer for the UI design, and I need to include some matplotlib plots.
After some digging, I found out that in order not to modify the python code generated from the ui file everytime I update the gui part (which is what is expected from Qt Designer), I would need a MatplotlibWidget plugin set-up in Qt Designer.
My problem is that the references I found for this plugin are either from the Python(x,y) package that is based on Python 2.7 and would not work with Python 3.x; or the PyQtdesginerplugins package that is not working either in Python 3.x/Qt5 environment (already pointed out in this question How do I add matplotlib plugin to Qt5.4 Designer plugins?).
Is there any possibility to add a MatplotlibWidget to Qt Designer in my Python 3.6 and Qt5 environment? That would help a lot to take full advantage of Qt Designer in segregating the ui from the application logic.
Upvotes: 2
Views: 5898
Reputation: 41
@Thib. I was struggling with the same problem but I got it to work. As @ekhumoro suggested, you can put you python files anywhere and then add that folder to the environment path BUT you will need to go run Scripts\pyqt5designer.exe (which is either in python virtual environment or your python installation folder, depending on your setup) if you installed QT designer using pyqt5-tools, which you did based on your path provided above.
Upvotes: 0
Reputation: 120678
Below you will find a PyQt5 version of the MatplotlibPlugin for Qt Designer.
To use it, put both files in a directory that is either included in your PYQTDESIGNERPATH
environment variable, or in a "python" subdirectory within one of the directories that Qt Designer searches for its own plugins. The two files must be named exactly as shown below.
matplotlibwidget.py:
from PyQt5.QtCore import QSize
from PyQt5.QtWidgets import QSizePolicy
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as Canvas
from matplotlib.figure import Figure
from matplotlib import rcParams
rcParams['font.size'] = 9
class MatplotlibWidget(Canvas):
def __init__(self, parent=None, title='', xlabel='', ylabel='',
xlim=None, ylim=None, xscale='linear', yscale='linear',
width=4, height=3, dpi=100):
self.figure = Figure(figsize=(width, height), dpi=dpi)
self.axes = self.figure.add_subplot(111)
self.axes.set_title(title)
self.axes.set_xlabel(xlabel)
self.axes.set_ylabel(ylabel)
if xscale is not None:
self.axes.set_xscale(xscale)
if yscale is not None:
self.axes.set_yscale(yscale)
if xlim is not None:
self.axes.set_xlim(*xlim)
if ylim is not None:
self.axes.set_ylim(*ylim)
super(MatplotlibWidget, self).__init__(self.figure)
self.setParent(parent)
super(MatplotlibWidget, self).setSizePolicy(
QSizePolicy.Expanding, QSizePolicy.Expanding)
super(MatplotlibWidget, self).updateGeometry()
def sizeHint(self):
return QSize(*self.get_width_height())
def minimumSizeHint(self):
return QSize(10, 10)
matplotlibplugin.py:
import os
from PyQt5.QtGui import QIcon
from PyQt5.QtDesigner import QPyDesignerCustomWidgetPlugin
from matplotlib import rcParams
from matplotlibwidget import MatplotlibWidget
rcParams['font.size'] = 9
class MatplotlibPlugin(QPyDesignerCustomWidgetPlugin):
def __init__(self, parent=None):
super(MatplotlibPlugin, self).__init__(parent)
self._initialized = False
def initialize(self, editor):
self._initialized = True
def isInitialized(self):
return self._initialized
def createWidget(self, parent):
return MatplotlibWidget(parent)
def name(self):
return 'MatplotlibWidget'
def group(self):
return 'PyQt'
def icon(self):
return QIcon(os.path.join(
rcParams['datapath'], 'images', 'matplotlib.png'))
def toolTip(self):
return ''
def whatsThis(self):
return ''
def isContainer(self):
return False
def domXml(self):
return '<widget class="MatplotlibWidget" name="mplwidget">\n' \
'</widget>\n'
def includeFile(self):
return 'matplotlibwidget'
Upvotes: 3