3
2

More than 3 years have passed since last update.

pyqtgraphにwidgetを追加し制御する

Last updated at Posted at 2019-12-01

1. はじめに

pyqtおよびpyqtgraphの初心者です。測定データを高速に表示させたく、pyqtgraphを使い高速表示を実現することができました。その後、表示パラメータを変更できるようにしたい等の要望が出てきましたが、様々なグラフやウィジットの例はあっても、それらを組み合わせた例が見つからず、色々調べてやっとわかりました。他の方にも役にたつかもと思い投稿します。

2. ポイント

(自分ではなかなか方法が分からず試行錯誤したところ)

・ウィジットをグラフィックアイテムとして追加する

押しボタン等のウィジットをpyqtgraphのウインドウに追加すればいいのですが、以下の方法で実施しています。
・QGraphicsProxyWidget [PyQt5.QtWidgets]
ウィジットをグラッフィックアイテムとして見せる。
・addItem [class pyqtgraph.PlotItem]
  グラフィックアイテム(QGraphicsItem)をビューボックスに追加。
・addLayout [class pyqtgraph.GraphicsLayou]
pyqtgraphのウインドウにグラフィックレイアウトを追加。

・サブウインドウ生成時は親ウインドウのオブジェクトを渡す

QMainWindowによりサブウインドウを作っていますが、初期化時、親ウインドウのオブジェクト(下記サンプルの場合はwin)を渡します。

test.py
class SubWindow(QMainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.initUI()
   .............................

3. サンプルコード

・プロット機能によりランダムな値のポイントを数を増やしながら更新し続けます。
・ウインドウ下部のレイアウトには、test1, test2, exitの3つのボタンをグラフィックアイテムとして表示します。それぞれのボタンを押すとコマンドラインにボタン名を表示し、
さらに以下の動作をします。
test1 : 追加動作なし
test2 : サブウインドウを開き、ClearPTRボタンを押すと表示プロットを初期化します。
exit : ポイント表示の更新を終了し、メインのウインド(だけ)を閉じます。

メインウインド
image.png

TEST2を押したときのサブウインド
image.png

test.py
import sys
from PyQt5.QtWidgets import QMainWindow, QPushButton, QApplication, QGraphicsProxyWidget
from pyqtgraph.Qt import QtGui, QtCore
import pyqtgraph as pg
import numpy as np

class SubWindow(QMainWindow):
    def __init__(self, parent):
        super().__init__(parent)
        self.initUI()
    def initUI(self):
        btn1 = QPushButton("Button01", self)
        btn1.clicked.connect(self.button01Clicked)
        btn1.move(27, 15)
        btn2 = QPushButton("Clear PTR", self)
        btn2.clicked.connect(self.Cbutton01Clicked)
        btn2.move(27, 50)
        self.statusBar()
        self.setWindowTitle('TEST2 Window')
        self.resize(300,200)
        self.show()
    def button01Clicked(self):
        sender = self.sender()
        self.statusBar().showMessage(sender.text() + ' Push Button01')
    def Cbutton01Clicked(self):
        global ptr
        sender = self.sender()
        self.statusBar().showMessage(sender.text() + ' Clear Points')
        ptr = 0

class button :
    def __init__(self, win):
        self.win = win
        self.p = self.win.addLayout(row=1, col=0)
        self.list = {}
    def add(self, name, func) :
        proxy = QGraphicsProxyWidget()
        item = self.p.addItem(proxy, row=0, col=len(self.list))
        QPB = QtGui.QPushButton(name)
        QPB.clicked.connect(func)
        proxy.setWidget(QPB)
        self.list[name]=[proxy, item, QPB]
    def b_exit(self) :
        print("ckick exit")
        timer.stop()
        self.win.close()
    def b_test1(self) :
        print("ckick TEST1")
    def b_test2(self) :
        print("ckick TEST2")
        sw = SubWindow(self.win)

app = QtGui.QApplication([])

win = pg.GraphicsWindow(title="test")
win.resize(1000,600)
win.setWindowTitle("Test Window")
pg.setConfigOptions(antialias=True)
p6 = win.addPlot(Title="wave")

b = button(win)
b.add("test1", b.b_test1)
b.add("test2", b.b_test2)
b.add("exit",  b.b_exit)

curve = p6.plot(pen=None,symbol='o' )
ptr = 0
def update() :
    global curve, ptr, p6
    x = np.random.normal(size=ptr+1)
    y = np.random.normal(size=ptr+1)
    curve.setData(x,y)
    p6.enableAutoRange('xy', False)
    ptr += 1

timer = QtCore.QTimer()
timer.timeout.connect(update)
timer.start(50)

sys.exit(app.exec_())

4. おわりに

以下の参考文献もとに見よう見まねで組み合わせて作ったので、本来の書き方とは違うところがあるかもしれません。ご指摘いただけると助かります。

動作環境:
 ・windows10にpython3.6 , pyqtgraph , pyqt5をインストールし使用。

参考文献:
 ・The complete PyQt5 tutorial — Start building GUI apps with Python
 ・Add button to PyQtGraph Layout
 ・Welcome to the documentation for pyqtgraph
 ・PyQt5とpython3によるGUIプログラミング[1]

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2