Pyside 中的 Matplotlib 与 Qt 设计器 (PySide)
Matplotlib in Pyside with Qt designer (PySide)
我一直在寻找一个工作示例,该示例如何在使用 QT 设计器创建的 pyside 中嵌入 matplotlib 图,同时将逻辑保存在单独的文件中。我知道网上有很多示例,但其中 none 实际上使用了 QT 设计器,然后创建一个单独的文件来添加将 matplitlib 图添加到小部件的逻辑。我找到了一个 'almost' 有效 http://blog.rcnelson.com/building-a-matplotlib-gui-with-qt-designer-part-1/ 的例子,但在我的版本中它不可能 "Change the layoutName property from “verticalLayout” to “mplvl”".
所以我有以下具体问题:
我不清楚 Pyside Qt 设计器中可以嵌入哪些项目。它是一个简单的 "widget" 吗(因为 pyside 中没有可用的 matplotlib 小部件)。如果是这样,我该如何将情节添加到该小部件?或者我是否必须使用 Qt Designer 创建一个 'FigureCanvas'?这可能吗?如果可以,怎么做?
这是我可以使用 Pyside Qt 设计器在嵌入小部件时进行的最简单的设计(正确吗?)。我现在如何在其上添加 matplotlib 图?
按照其中一个答案的建议,我现在将 Qwidget 提升为 MyStaticMplCanvas 并将 Qwidget 的名称编辑为 mplvl。
使用 Pyside Qt 设计器自动生成文件并使用
pyside-uic ui.ui -o ui.py -x
ui.py 看起来像这样:
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'gui.ui'
#
# Created: Wed Apr 20 14:00:02 2016
# by: pyside-uic 0.2.15 running on PySide 1.2.2
#
# WARNING! All changes made in this file will be lost!
from PySide import QtCore, QtGui
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(444, 530)
self.centralwidget = QtGui.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.mplvl = MyStaticMplCanvas(self.centralwidget)
self.mplvl.setGeometry(QtCore.QRect(120, 190, 221, 161))
self.mplvl.setObjectName("mplvl")
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtGui.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 444, 21))
self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtGui.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
MainWindow.setWindowTitle(QtGui.QApplication.translate("MainWindow", "MainWindow", None, QtGui.QApplication.UnicodeUTF8))
from mystaticmplcanvas import MyStaticMplCanvas
if __name__ == "__main__":
import sys
app = QtGui.QApplication(sys.argv)
MainWindow = QtGui.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
我现在如何从单独的 .py 文件向 mplvl 对象添加绘图?
我不是这方面的专家,所以这可能不是最简洁的方法,但这里有一些工作代码可以帮助您入门:
- 我认为添加小部件的最简单方法是通过
QxxxxLayout
- 然后我让你的
Plotter
继承自 FigureCanvas
- 并告诉
matplotlib
与 PySide
一起工作
ui.py:
from PySide import QtCore, QtGui
class Ui_Form(object):
def setupUi(self, Form):
Form.setObjectName("Form")
Form.resize(533, 497)
self.mplvl = QtGui.QWidget(Form)
self.mplvl.setGeometry(QtCore.QRect(150, 150, 251, 231))
self.mplvl.setObjectName("mplvl")
self.vLayout = QtGui.QVBoxLayout()
self.mplvl.setLayout(self.vLayout)
self.retranslateUi(Form)
QtCore.QMetaObject.connectSlotsByName(Form)
def retranslateUi(self, Form):
Form.setWindowTitle(QtGui.QApplication.translate("Form", "Form", None, QtGui.QApplication.UnicodeUTF8))
为此,您只需将 canvas 添加到 QtDesigner
中的 mplvl
main.py:
import matplotlib
matplotlib.use('Qt4Agg')
matplotlib.rcParams['backend.qt4'] = 'PySide'
from matplotlib.backends.backend_qt4agg import (
FigureCanvasQTAgg as FigureCanvas,
NavigationToolbar2QT as NavigationToolbar)
from matplotlib.figure import Figure
from PySide import QtGui, QtCore
import random
from weakref import proxy
from ui import Ui_Form
class Plotter(FigureCanvas):
def __init__(self, parent):
''' plot some random stuff '''
self.parent = proxy(parent)
# random data
data = [random.random() for i in range(10)]
fig = Figure()
super(Plotter,self).__init__(fig)
# create an axis
self.axes = fig.add_subplot(111)
# discards the old graph
self.axes.hold(False)
# plot data
self.axes.plot(data, '*-')
def binding_plotter_with_ui(self):
self.parent.vLayout.insertWidget(1, self)
if __name__ == "__main__":
import sys
app = QtGui.QApplication(sys.argv)
Form = QtGui.QWidget()
ui = Ui_Form()
ui.setupUi(Form)
# plotter logic and binding needs to be added here
plotter = Plotter(ui)
plotter.binding_plotter_with_ui()
plotter2 = Plotter(ui)
plotter2.binding_plotter_with_ui()
Form.show()
sys.exit(app.exec_())
现在剩下的可能是调整 FigureCanvas
以使其大小和比例正确,这样您应该能够得到您想要的 this example or the other。
祝你好运!
看看QT4中嵌入的matplotlib例子:http://matplotlib.org/examples/user_interfaces/embedding_in_qt4.html
他们在这里定义了几个 classes 在 QT4 应用程序中实现 matplotlib 小部件,例如class MyStaticMplCanvas
。在QT Designer中使用这个class的技巧是使用一个标准的QWidget,右击它select Promote to ...
在class下填写MyStaticMplCanvas
名称Promoted class name
,以及在 header file
下找到此 class 的文件名(添加了扩展名 .h,但在 python 代码中被忽略)。单击 Add
和 Promote
。
现在在 uic 编译后 python 代码应该类似于:
from PySide import QtCore, QtGui
class Ui_Form(object):
def setupUi(self, Form):
...
self.mplvl = MyStaticMplCanvas(Form)
...
from mystaticmplcanvas import MyStaticMplCanvas
我一直在寻找一个工作示例,该示例如何在使用 QT 设计器创建的 pyside 中嵌入 matplotlib 图,同时将逻辑保存在单独的文件中。我知道网上有很多示例,但其中 none 实际上使用了 QT 设计器,然后创建一个单独的文件来添加将 matplitlib 图添加到小部件的逻辑。我找到了一个 'almost' 有效 http://blog.rcnelson.com/building-a-matplotlib-gui-with-qt-designer-part-1/ 的例子,但在我的版本中它不可能 "Change the layoutName property from “verticalLayout” to “mplvl”".
所以我有以下具体问题: 我不清楚 Pyside Qt 设计器中可以嵌入哪些项目。它是一个简单的 "widget" 吗(因为 pyside 中没有可用的 matplotlib 小部件)。如果是这样,我该如何将情节添加到该小部件?或者我是否必须使用 Qt Designer 创建一个 'FigureCanvas'?这可能吗?如果可以,怎么做?
这是我可以使用 Pyside Qt 设计器在嵌入小部件时进行的最简单的设计(正确吗?)。我现在如何在其上添加 matplotlib 图?
按照其中一个答案的建议,我现在将 Qwidget 提升为 MyStaticMplCanvas 并将 Qwidget 的名称编辑为 mplvl。
使用 Pyside Qt 设计器自动生成文件并使用 pyside-uic ui.ui -o ui.py -x
ui.py 看起来像这样:
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'gui.ui'
#
# Created: Wed Apr 20 14:00:02 2016
# by: pyside-uic 0.2.15 running on PySide 1.2.2
#
# WARNING! All changes made in this file will be lost!
from PySide import QtCore, QtGui
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(444, 530)
self.centralwidget = QtGui.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.mplvl = MyStaticMplCanvas(self.centralwidget)
self.mplvl.setGeometry(QtCore.QRect(120, 190, 221, 161))
self.mplvl.setObjectName("mplvl")
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtGui.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 444, 21))
self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtGui.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
MainWindow.setWindowTitle(QtGui.QApplication.translate("MainWindow", "MainWindow", None, QtGui.QApplication.UnicodeUTF8))
from mystaticmplcanvas import MyStaticMplCanvas
if __name__ == "__main__":
import sys
app = QtGui.QApplication(sys.argv)
MainWindow = QtGui.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
我现在如何从单独的 .py 文件向 mplvl 对象添加绘图?
我不是这方面的专家,所以这可能不是最简洁的方法,但这里有一些工作代码可以帮助您入门:
- 我认为添加小部件的最简单方法是通过
QxxxxLayout
- 然后我让你的
Plotter
继承自FigureCanvas
- 并告诉
matplotlib
与PySide
一起工作
ui.py:
from PySide import QtCore, QtGui
class Ui_Form(object):
def setupUi(self, Form):
Form.setObjectName("Form")
Form.resize(533, 497)
self.mplvl = QtGui.QWidget(Form)
self.mplvl.setGeometry(QtCore.QRect(150, 150, 251, 231))
self.mplvl.setObjectName("mplvl")
self.vLayout = QtGui.QVBoxLayout()
self.mplvl.setLayout(self.vLayout)
self.retranslateUi(Form)
QtCore.QMetaObject.connectSlotsByName(Form)
def retranslateUi(self, Form):
Form.setWindowTitle(QtGui.QApplication.translate("Form", "Form", None, QtGui.QApplication.UnicodeUTF8))
为此,您只需将 canvas 添加到 QtDesigner
mplvl
main.py:
import matplotlib
matplotlib.use('Qt4Agg')
matplotlib.rcParams['backend.qt4'] = 'PySide'
from matplotlib.backends.backend_qt4agg import (
FigureCanvasQTAgg as FigureCanvas,
NavigationToolbar2QT as NavigationToolbar)
from matplotlib.figure import Figure
from PySide import QtGui, QtCore
import random
from weakref import proxy
from ui import Ui_Form
class Plotter(FigureCanvas):
def __init__(self, parent):
''' plot some random stuff '''
self.parent = proxy(parent)
# random data
data = [random.random() for i in range(10)]
fig = Figure()
super(Plotter,self).__init__(fig)
# create an axis
self.axes = fig.add_subplot(111)
# discards the old graph
self.axes.hold(False)
# plot data
self.axes.plot(data, '*-')
def binding_plotter_with_ui(self):
self.parent.vLayout.insertWidget(1, self)
if __name__ == "__main__":
import sys
app = QtGui.QApplication(sys.argv)
Form = QtGui.QWidget()
ui = Ui_Form()
ui.setupUi(Form)
# plotter logic and binding needs to be added here
plotter = Plotter(ui)
plotter.binding_plotter_with_ui()
plotter2 = Plotter(ui)
plotter2.binding_plotter_with_ui()
Form.show()
sys.exit(app.exec_())
现在剩下的可能是调整 FigureCanvas
以使其大小和比例正确,这样您应该能够得到您想要的 this example or the other。
祝你好运!
看看QT4中嵌入的matplotlib例子:http://matplotlib.org/examples/user_interfaces/embedding_in_qt4.html
他们在这里定义了几个 classes 在 QT4 应用程序中实现 matplotlib 小部件,例如class MyStaticMplCanvas
。在QT Designer中使用这个class的技巧是使用一个标准的QWidget,右击它select Promote to ...
在class下填写MyStaticMplCanvas
名称Promoted class name
,以及在 header file
下找到此 class 的文件名(添加了扩展名 .h,但在 python 代码中被忽略)。单击 Add
和 Promote
。
现在在 uic 编译后 python 代码应该类似于:
from PySide import QtCore, QtGui
class Ui_Form(object):
def setupUi(self, Form):
...
self.mplvl = MyStaticMplCanvas(Form)
...
from mystaticmplcanvas import MyStaticMplCanvas