2017-05-12 82 views
3

matplotlib図をQt Designerから作成したフォームにリンクする最良の方法を理解できません。私はQtDesignerで作成したフォームをpyuic5を使ってPythonにコンパイルしました。私の主なプログラムは次のとおりです。Qt DesignerフォームとPyQt5を使用してQWidget内にmatplotlib図をプロットする

て、myAppその後pyuic5(design.py)によって変換されたQtのデザイナーから作成app_framework.pyフォーム呼び出す
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_() 

:私はどこでこれに困惑しているよう

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> 

をフレームワーク私はmatplotlibの図形をQtDesignerの空の前のウィジェットにリンクすることができます。そうすれば、GUIウィンドウに新しいデータをプロットすることができます(テキスト入力、ボタン押しなど)

IいくつかのスレッドはSOとにありますしかし、私はQtデザイナーフォームでこのウィジェットのスペースを作成し、プロットをリンクしたり、ウィジェットを作成してからリンクしてプロットしたりする正しいプロセスを理解していません。

私がこれまで行ってきたことは、次のように私はdesign.pyファイルを変更し、Qtの創造主の内部で空のQWidgetを作成してpyuic5後にコンパイルしている:app_framework.pyその後、

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() 
# *********** 

とのように:

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() 

これはうまくいくと思いましたが、プロットプッシュボタンをクリックしても何も起こりません。それはロックアップしません、それは何もプロットしていません。私は、この空のウィジェットにmatplotlibの図形やキャンバスをプロットするための基本的なものがないと思っています。

答えて

4

このSO postの助けを借りて解決策が見つかりました。これはおそらく買う必要がある本のfree sample chapterにリンクしています。他の多くの記事で言及されているように、ヘッダmplwidgetを使用して空のQtWidgetをMplWidgetに「昇格」する必要があります。これを実行した後、pyuic5コマンドを実行すると、 "mplwidget import MplWidgetから"というメッセージがdesign.pyファイルに表示されます。これは、上書きを心配することなくいつでも更新できます。次に、mplwidget.pyファイルを次のように作成します。

# 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) 

次に、以前のようにappフレームワークを作成することができます。実行してプロットボタンを押すと、図が期待通りに表示されます。私は基本的には、vblのものを手にしただけでQWidgetを「プロモート」するためにすべてをやったと思うが、Qtデザイナーのフォームが編集されるたびに上書きされるだろう。

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_() 
関連する問題