問(wèn)題描述
我不明白將 matplotlib 圖形鏈接到從 Qt Designer 創(chuàng)建的表單的最佳方法.我有一個(gè)我在 QtDesigner 中創(chuàng)建的表單,然后通過(guò) pyuic5 編譯為 python.我的主要程序是:
I don't understand the best way to link a matplotlib figure to a form created from Qt Designer. I have a form I created in QtDesigner and then compiled to python through pyuic5. My main program is:
import app_framework as af
import matplotlib
from PyQt5 import QtWidgets
import sys
matplotlib.use('Qt5Agg')
app = QtWidgets.QApplication(sys.argv)
form = af.MyApp()
form.show()
app.exec_()
myApp 調(diào)用從 Qt Designer 創(chuàng)建然后由 pyuic5 (design.py) 轉(zhuǎn)換的 app_framework.py 表單:
where myApp calls the app_framework.py form created from Qt Designer then converted by pyuic5 (design.py):
from PyQt5.QtWidgets import QApplication, QMainWindow
import design
class MyApp(QMainWindow, design.Ui_mainWindow):
def __init(self):
super(self.__class__, self).__init__()
<button initializations>
<function definitions for button callbacks>
我很困惑在這個(gè)框架中我可以將 matplotlib 圖形鏈接到 QtDesigner 中的預(yù)制空小部件或類似的東西,以便我可以在發(fā)生事情時(shí)在 GUI 窗口中繪制新數(shù)據(jù)(輸入的文本、按鈕按下等)
I'm confused as to where in this framework I can link a matplotlib figure to a premade empty widget in QtDesigner, or something of that sort, so that I can plot new data in the GUI window as things happen (text entered, button push, etc.)
我在這里找到了一些線程 SO 和 matplotlib 的站點(diǎn),但我不確定我是否理解為此創(chuàng)建空間的正確過(guò)程Qt Designer 表單中的小部件,然后鏈接繪圖,和/或創(chuàng)建小部件事后,然后鏈接和繪圖.
I've found some threads here on SO and matplotlib's site, but I'm not sure I understand the correct process for creating the space for this widget in the Qt Designer form then linking a plot, and/or creating a widget post hoc and then linking and plotting.
到目前為止,我所做的是在 Qt Creator 中創(chuàng)建一個(gè)空的 QWidget,然后在 pyuic5 編譯后,我將 design.py 文件更改如下:
What I've done so far is create an empty QWidget inside Qt Creator and then after pyuic5 compile, I alter the design.py file as follows:
from PyQt5 import QtCore, QtGui, QtWidgets
# **** ADDED THIS
from matplotlib.figure import Figure
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as Canvas
# ****
class Ui_mainWindow(object):
def setupUi(self, mainWindow):
<mainWindow setup stuff>
self.centralwidget = QtWidgets.QWidget(mainWindow)
# ****ALTERED THIS FROM self.plotWidget = QtWidgets.QWidget(self.centralWidget)
self.plotWidget = MplWidget(self.centralWidget)
# *****
self.plotWidget.setGeometry(QtCore.QRect(20, 250, 821, 591))
self.plotWidget.setObjectName("plotWidget")
# **** ADDED THIS
class MplCanvas(Canvas):
def __init__(self):
self.fig = Figure()
self.ax = self.fig.add_subplot(111)
Canvas.__init__(self, self.fig)
Canvas.setSizePolicy(self, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
Canvas.updateGeometry(self)
class MplWidget(QtWidgets.QWidget):
def __init__(self, parent=None):
QtWidgets.QWidget.__init__(self, parent)
self.canvas = MplCanvas()
# ***********
然后 app_framework.py 為:
and then app_framework.py as:
from PyQt5.QtWidgets import QApplication, QMainWindow
import design
class MyApp(QMainWindow, design.Ui_mainWindow):
def __init(self):
super(self.__class__, self).__init__()
self.setupUi(self)
self.pushButton_plotData.clicked.connect(self.plot_data)
def plot_data(self):
x=range(0, 10)
y=range(0, 20, 2)
self.plotWidget.canvas.ax.plot(x, y)
self.plotWidget.canvas.draw()
我認(rèn)為這會(huì)起作用,但是當(dāng)我單擊情節(jié)按鈕時(shí),什么也沒(méi)有發(fā)生.它沒(méi)有鎖定,它只是不繪制任何東西.我猜我錯(cuò)過(guò)了在這個(gè)空小部件中繪制 matplotlib 圖形和/或畫布的基本知識(shí).
I thought this would work, but when I click the plot push button, nothing happens. It doesn't lock up, it just doesn't plot anything. I'm guessing I'm missing something fundamental for plotting a matplotlib figure and/or canvas in this empty widget.
推薦答案
通過(guò)這個(gè)SO post,鏈接到這個(gè) 我可能需要購(gòu)買的一本書的免費(fèi)示例章節(jié).正如許多其他帖子中提到的那樣,需要使用標(biāo)頭 mplwidget 將空白 QtWidget提升"為 MplWidget.完成此操作后,然后運(yùn)行 ??pyuic5 命令,from mplwidget import MplWidget"將出現(xiàn)在 design.py 文件中,可以隨時(shí)更新,無(wú)需擔(dān)心覆蓋.然后,創(chuàng)建一個(gè) mplwidget.py 文件:
I found the solution through the help of this SO post, which links to this free sample chapter of a book I'm probably gonna need to buy. As sort of mentioned in a number of other posts, one needs to "Promote" the blank QtWidget to a MplWidget using the header mplwidget. After doing this, and then running the pyuic5 command, "from mplwidget import MplWidget" will appear in the design.py file which can be updated anytime without worry about overwritting. Then, create an mplwidget.py file with:
# Imports
from PyQt5 import QtWidgets
from matplotlib.figure import Figure
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as Canvas
import matplotlib
# Ensure using PyQt5 backend
matplotlib.use('QT5Agg')
# Matplotlib canvas class to create figure
class MplCanvas(Canvas):
def __init__(self):
self.fig = Figure()
self.ax = self.fig.add_subplot(111)
Canvas.__init__(self, self.fig)
Canvas.setSizePolicy(self, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
Canvas.updateGeometry(self)
# Matplotlib widget
class MplWidget(QtWidgets.QWidget):
def __init__(self, parent=None):
QtWidgets.QWidget.__init__(self, parent) # Inherit from QWidget
self.canvas = MplCanvas() # Create canvas object
self.vbl = QtWidgets.QVBoxLayout() # Set box for plotting
self.vbl.addWidget(self.canvas)
self.setLayout(self.vbl)
然后,應(yīng)用程序框架可以像我之前一樣.運(yùn)行并按下繪圖按鈕時(shí),該圖按預(yù)期顯示.我想我基本上已經(jīng)做了所有事情來(lái)手動(dòng)提升"QWidget,只是錯(cuò)過(guò)了vbl的東西,但是每次編輯Qt Designer表單時(shí),所有這些都會(huì)被覆蓋.
Then, the app framework can be as I had earlier. When run, and pushing the plot button, the figure appears as expected. I think I basically had done everything to "Promote" the QWidget by hand just missing the vbl stuff, but all that would be overwritten everytime the Qt Designer form is editted.
app_framework.py:
app_framework.py:
from PyQt5.QtWidgets import QApplication, QMainWindow
import design
class MyApp(QMainWindow, design.Ui_mainWindow):
def __init(self):
super(self.__class__, self).__init__()
self.setupUi(self)
self.pushButton_plotData.clicked.connect(self.plot_data)
def plot_data(self):
x=range(0, 10)
y=range(0, 20, 2)
self.plotWidget.canvas.ax.plot(x, y)
self.plotWidget.canvas.draw()
main.py:
from PyQt5 import QtWidgets
import sys
# Local Module Imports
import app_framework as af
# Create GUI application
app = QtWidgets.QApplication(sys.argv)
form = af.MyApp()
form.show()
app.exec_()
這篇關(guān)于使用 Qt Designer 表單和 PyQt5 在 QWidget 中繪制 matplotlib 圖形的文章就介紹到這了,希望我們推薦的答案對(duì)大家有所幫助,也希望大家多多支持html5模板網(wǎng)!