Fabian S
Fabian S

Reputation: 55

Embed a pyqtgraph plot into a QT .ui?

first of all I hope you have me some patience since I'm new on these kind of projects and I also hope not to be asking dumb questions. That being said, my main objective is to create a UI for a raspberry pi 3 which will sense voltage, current, etc from a battery and from a solar panel.

Since I'm working on a raspberry and have some knowledge on Python3, I decided to use QTCreator which as I understand can be translated into python3 through pyqt (https://nikolak.com/pyqt-qt-designer-getting-started/). I installed it on my raspberry pi and made the following UI:

after having a basic UI, I converted the .ui file into .py with the pyuic5 command and I'm able to open the UI with "python3 main.py" and everything seems right:

how the UI looks after opening the main.py file

Now, I want to have a several plots (like voltage against time, etc) on the UI. I'm using the following for testing:

import sys
import pyqtgraph as pg
from pyqtgraph.Qt import QtCore, QtGui
import numpy as np

pg.setConfigOption('background', 'w')
pg.setConfigOption('foreground', 'k')
win = pg.GraphicsWindow()
win.setWindowTitle('pyqtgraph example: Scrolling Plots')


p1 = win.addPlot(labels =  {'left':'Voltage', 'bottom':'Time'})
data1 = np.random.normal(size=10)
data2 = np.random.normal(size=10)
curve1 = p1.plot(data1, pen=(3,3))
curve2 = p1.plot(data2, pen=(2,3))
ptr1 = 0

def update1():
    global data1, curve1, data2, ptr1

    data1[:-1] = data1[1:]  # shift data in the array one sample left
                            # (see also: np.roll)
    data1[-1] = np.random.normal()
    ptr1 += 1

    curve1.setData(data1)
    curve1.setPos(ptr1,0)



    data2[:-1] = data2[1:]  # shift data in the array one sample left
                            # (see also: np.roll)
    data2[-1] = np.random.normal()
    curve2.setData(data2)
    curve2.setPos(ptr1,0)


def update():
    update1()

timer = pg.QtCore.QTimer()
timer.timeout.connect(update)
timer.start(2000) # number of seconds (every 1000) for next update



if __name__ == '__main__':
    QtGui.QApplication.instance().exec_()

Is it possible to embbed that plot into my main.py file? If I understood correctly, I'm supposed to use the promoting widget functionality on QTCreator. Thanks in advance guys!

Upvotes: 3

Views: 9758

Answers (1)

eyllanesc
eyllanesc

Reputation: 243887

What is promoted through Qt Designer is a Widget, ie a class, so it can not be directly promoted, what we must do is place it inside a class as shown below:

Plotter.py

class  CustomWidget(pg.GraphicsWindow):
    pg.setConfigOption('background', 'w')
    pg.setConfigOption('foreground', 'k')
    ptr1 = 0
    def __init__(self, parent=None, **kargs):
        pg.GraphicsWindow.__init__(self, **kargs)
        self.setParent(parent)
        self.setWindowTitle('pyqtgraph example: Scrolling Plots')
        p1 = self.addPlot(labels =  {'left':'Voltage', 'bottom':'Time'})
        self.data1 = np.random.normal(size=10)
        self.data2 = np.random.normal(size=10)
        self.curve1 = p1.plot(self.data1, pen=(3,3))
        self.curve2 = p1.plot(self.data2, pen=(2,3))

        timer = pg.QtCore.QTimer(self)
        timer.timeout.connect(self.update)
        timer.start(2000) # number of seconds (every 1000) for next update

    def update(self):
        self.data1[:-1] = self.data1[1:]  # shift data in the array one sample left
                            # (see also: np.roll)
        self.data1[-1] = np.random.normal()
        self.ptr1 += 1
        self.curve1.setData(self.data1)
        self.curve1.setPos(self.ptr1, 0)
        self.data2[:-1] = self.data2[1:]  # shift data in the array one sample left
                            # (see also: np.roll)
        self.data2[-1] = np.random.normal()
        self.curve2.setData(self.data2)
        self.curve2.setPos(self.ptr1,0)

if __name__ == '__main__':
    w = CustomWidget()
    w.show()
    QtGui.QApplication.instance().exec_()

Before proceeding I will assume that the files have the following structure:

.
├── main.py
└── Plotter.py
  1. The first thing to do is choose the widget:

enter image description here

  1. Then we right click on this and choose the option to promote to..:

enter image description here

  1. In the dialog box we place CustomWidget in Promoted Class Name and Plotter.h in Header File, then press the Add and Promote button.

enter image description here

  1. Then we convert our .ui file to .py

enter image description here

Upvotes: 10

Related Questions