2016-04-06 26 views
9

ロジックを別のファイルに保存しながらQTデザイナーで作成されたpplideにmatplotlibプロットを埋め込む方法の実例を探しています。私はWeb上に多数の例があることは知っていますが、実際にはQTデザイナを使用していないし、matplitlibプロットがウィジェットに追加されるロジックを追加するために別のファイルを作成します。私は 'ほぼ' http://blog.rcnelson.com/building-a-matplotlib-gui-with-qt-designer-part-1/が動作していますが、私のバージョンでは「layoutLanout」から「mplvl」にlayoutNameプロパティを変更することはできません。Qtデザイナー(PySide)を持つPysideのMatplotlib

私は以下の具体的な質問があります。 Pyside Qtデザイナーにどのようなプロットを埋め込むことができるのかはわかりません。単純な「ウィジェット」ですか(pysideで利用可能なmatplotlibウィジェットはありません)。もしそうなら、どうすればそのウィジェットにプロットを追加できますか? Qt Designerで 'FigureCanvas'を作成する必要がありますか?これはまったく可能ですか?もしそうなら、どうですか?

これは、Pyside Qtデザイナーがウィジェットを埋め込む際に行うことができる最もシンプルなデザインです(これは正しいですか?)。どのようにして、その上にmatplotlibプロットを追加することができますか?

答えの1つとして示唆されているように、私は今QwidgetをMyStaticMplCanvasに昇格させ、Qwidgetの名前をmplvlに編集しました。

自動的PysideのQt Designerでファイルを生成し、でコンパイルさ 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オブジェクトにプロットを追加しますか?

+2

は今UICにより、コンパイル後のpythonコードは次のようになります。 'matplotlib.backends.qt_compat'モジュールからすべてをインポートすることをお勧めします。 – tacaswell

+1

pysideのコードはpyside-uicによって自動的に生成されるので、何とかしておく必要があります。それが不可能だと言っていない限り? – Nickpick

+1

私にも同様の問題がありましたが、いくつかの違いがあります。このポストを参照してくださいstackoverflow: http://stackoverflow.com/questions/36665850/matplotlib-animation-inside-your-own-pyqt4-gui/36669876#36669876 希望に役立ちます。 –

答えて

7

それがこれを行うためのクリーンな方法ではないかもしれないので、私はその問題の専門家でないんだけど、ここであなたが始めるためにいくつかの作業のコードは次のとおりです。

  • 私はウィジェットを追加する最も簡単な方法を考えますQxxxxLayout
  • を経由して、その後、私はちょうどFigureCanvas
  • からあなたPlotter継承を行い、PySide
で動作するように matplotlibを告げています

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

あなただけでmplvlにキャンバスを追加する必要がQtDesigner

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またはthe otherを見たいものを得ることができるはずです。

幸運を祈る!

+0

明確にするには、ウィジェットをレイアウトに入れる必要があります。この場合、ウィジェットの名前はmplvlで、垂直レイアウトはvLayoutです。その後、上記のコードが動作します。 – Nickpick

+0

唯一の小さな問題は、プロットが少し下に切り取られることです。それについて何かできることはありますか? – Nickpick

+0

QtDesignerの中で、垂直レイアウトを置く最初のスクロール領域を追加します( '' mplvl''を置き換えてください)。次に、このレイアウト内にプロットを追加します。縦軸のサイズの問題は、単に小さすぎる '' self.mplvl.setGeometry(QtCore.QRect(150,150,251,231)) ''から発生します。 – Silmathoron

3

はQT4に埋め込むのmatplotlibの例を見てください:ここでhttp://matplotlib.org/examples/user_interfaces/embedding_in_qt4.html

彼らは、例えば、QT4アプリケーションでmatplotlibのウィジェットを実装するクラスのカップルを定義しますクラスMyStaticMplCanvas。QT Designerでこのクラスを使用するには、標準のQWidgetを使用して右クリックし、Promote to ...を選択します。クラス名MyStaticMplCanvasPromoted class nameの下に入力し、このクラスが見つかるファイル名はheader fileです(拡張子.hが追加され、 Pythonコードでは無視されます)。 AddPromoteをクリックします。あなたは、同じプロセスで `PyQt`と` PySide`輸入を混在させることはできません

from PySide import QtCore, QtGui 
class Ui_Form(object): 
    def setupUi(self, Form): 
     ... 
     self.mplvl = MyStaticMplCanvas(Form) 
     ... 

from mystaticmplcanvas import MyStaticMplCanvas 
+1

これは間違いなく正しい方向への一歩です。 TypeError:引数がオーバーロードされた呼び出しと一致しませんでした。 QWidget.setParent(QWidget):引数1に予期しない型 'PySide.QtGui.QWidget'があります。 QWidget。 setParent(QWidget、Qt.WindowFlags):引数1に予期しないタイプの 'PySide.QtGui.QWidget'があります – Nickpick

+1

PyStideからのみインポートし、PyQt4では何もインポートしないようにしてください。おそらくmatplotlibはデフォルトでPyQt4を使用しています。あなたのスクリプトの最初の行は、Silmathoronの答えのように、matplotlibで正しいバックエンドを設定します。 – Rob

+0

私は、元の質問を編集して、物事の現在の状態をよりよく表示しました – Nickpick

関連する問題