Hi I'm struggling with some code here. What I have are two widgets in a window. Widget 1 is a timer which can take an input and Widget 2 is a graph. What I want to do is to collect data at an interval specified by the timer. Both of the widgets are in a different widget or class called window. The problem I have is that when I setData for the graph widget the graph doesn't seem to update. The call is called by the timer widget when it's count is 0. self.readpanda() then uploads some data and calls the updatePlot() function. I can see that the plotData array gets bigger but the graph doesn't update. See code for graph widget:
## importing libraries
from dataclasses import dataclass
from PyQt5.QtWidgets import *
from PyQt5 import QtCore, QtGui
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from pyqtgraph import PlotWidget, plot
import pyqtgraph as pg
import sys
import numpy as np
import pandas as pd
import csv
from alicat import FlowController, FlowMeter
import time
import datetime
import sys
import os
# global variables
global count
global data
data = []
count = 30
# Timestamp function
def timestamp():
return int(time.mktime(datetime.datetime.now().timetuple()))
#TimeAxis Function
class TimeAxisItem(pg.AxisItem):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.setLabel(text='Time', units=None)
self.enableAutoSIPrefix(False)
def tickStrings(self, values, scale, spacing):
return [datetime.datetime.fromtimestamp(value).strftime("%H:%M:%S") for value in values]
class Graph(QWidget):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.plot = pg.PlotWidget(
title="GC Composition",
labels={'left': 'Gas Composition %'},
axisItems={'bottom': TimeAxisItem(orientation= 'bottom')}
)
self.plot.setYRange(0, 100)
self.plot.enableAutoRange(axis='x',enable=True)
# self.plot.setXRange(timestamp(), timestamp() + 100)
self.plot.showGrid(x=True, y=True)
self.layout = QVBoxLayout()
self.setLayout(self.layout)
self.layout.addWidget(self.plot)
self.plotCurve1 = self.plot.plot(pen='y')
self.plotCurve2 = self.plot.plot(pen='r')
self.plotCurve3 = self.plot.plot(pen='g')
self.plotData = {'t': [], 'H2': [], 'O2':[],'CO2':[]}
# self.timer = QtCore.QTimer()
# self.timer.setInterval(1000*count)
# self.timer.timeout.connect(self.readpanda)
# self.timer.start()
def __call__(self, *args, **kwargs):
if count==0:
self.readpanda()
def updatePlot(self, newValues):
self.plotData['H2'].append(newValues[1])
self.plotData['O2'].append(newValues[2])
self.plotData['CO2'].append(newValues[3])
self.plotData['t'].append(newValues[0])
print(self.plotData)
self.plotCurve1.setData(self.plotData['t'],self.plotData['H2'])
self.plotCurve2.setData(self.plotData['t'],self.plotData['O2'])
self.plotCurve3.setData(self.plotData['t'],self.plotData['CO2'])
def readpanda(self):
# Initialize rows list
rows=[]
#read csv file
with open('CH1.LOG') as f:
# creating a reader object (issue with header)
file = csv.reader(f,delimiter='\t')
# file = pd.read_csv(f, delimiter= '\t', header=None)
# extract each data row by row
for line in file:
pass
rows = line
# with new list rows loop through each row to index through categories H2, O2, CO2 and extract data for timestamp, and category peak area
datarow=[]
datarow.append(timestamp())
# int(time.mktime(datetime.datetime.now().timetuple())))
iH2 = rows.index("H2")
datarow.append(eval(rows[iH2+2]))
# fields.append(H2)
iO2 = rows.index("O2")
datarow.append(eval(rows[iO2+2]))
# print(O2)
iCO2 = rows.index("CO2")
datarow.append(eval(rows[iCO2+2]))
# print(datarow)
global data
# print(datarow)
data.append(datarow)
self.updatePlot(datarow)
global count
count = 30
# Timer Widget
class MyWidget(QWidget):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.layout = QVBoxLayout()
self.layout.setSpacing(10)
self.layout.setContentsMargins(10,10,10,10)
self.setLayout(self.layout)
# calling method
self.UiComponents()
# creating an instance of Graph so that it can be called again
self.Graph=Graph()
# showing all the widgets
self.show()
# method for widgets
def UiComponents(self):
# variables
# count variable
global count
count = 30
# start flag
self.start = False
# creating push button to get time in seconds
button = QPushButton("Set time(s)", self)
# setting geometry to the push button
self.layout.addWidget(button)
# adding action to the button
button.clicked.connect(self.get_seconds)
# creating label to show the seconds
self.label = QLabel("//TIMER//", self)
# setting geometry of label
self.layout.addWidget(self.label)
# setting border to the label
self.label.setStyleSheet("border : 3px solid black")
# setting font to the label
self.label.setFont(QFont('Times', 15))
# setting alignment ot the label
self.label.setAlignment(Qt.AlignCenter)
# resize label
self.label.resize(1,1)
# creating start button
start_button = QPushButton("Start", self)
# setting geometry to the button
self.layout.addWidget(start_button)
# adding action to the button
start_button.clicked.connect(self.start_action)
# creating pause button
pause_button = QPushButton("Pause", self)
# setting geometry to the button
self.layout.addWidget(pause_button)
# adding action to the button
pause_button.clicked.connect(self.pause_action)
# creating reset button
reset_button = QPushButton("Reset", self)
# setting geometry to the button
self.layout.addWidget(reset_button)
# adding action to the button
reset_button.clicked.connect(self.reset_action)
# creating a timer object
timer = QTimer(self)
# adding action to timer
timer.timeout.connect(self.showTime)
# update the timer every tenth second
timer.start(100)
# method called by timer
def showTime(self):
# checking if flag is true
if self.start:
# incrementing the counter
global count
count -= 1
# timer is completed
if count == 0:
# making flag false
self.start = False
# setting text to the label
self.label.setText("Completed !!!! ")
# calling Graph class call function to read file and update chart
self.Graph()
if self.start:
# getting text from count
text = str(count / 10) + " s"
# showing text
self.label.setText(text)
# method called by the push button
def get_seconds(self):
global count
# making flag false
self.start = False
# getting seconds and flag
second, done = QInputDialog.getInt(self, 'Seconds', 'Enter Seconds:')
# if flag is true
if done:
# changing the value of count
count = second * 10
# setting text to the label
self.label.setText(str(second))
def start_action(self):
global count
# making flag true
self.start = True
# count = 0
if count == 0:
self.start = False
def pause_action(self):
# making flag false
self.start = False
def reset_action(self):
global count
# making flag false
self.start = False
# setting count value to 0
count = 0
# setting label text
self.label.setText("//TIMER//")
class Window(QMainWindow):
def __init__(self):
super().__init__()
self.init_gui()
# setting title
self.setWindowTitle("Python ")
# setting geometry
self.setGeometry(100, 100, 400, 600)
def init_gui(self):
self.window = QWidget()
self.layout = QGridLayout()
self.setCentralWidget(self.window)
self.window.setLayout(self.layout)
self.Mywidget= MyWidget()
self.Graph = Graph()
self.layout.addWidget(self.Mywidget,0,0,1,1)
self.layout.addWidget(self.Graph,1,1,50,50)
def main():
# create pyqt5 app
App = QApplication(sys.argv)
# create the instance of our Window
window = Window()
window.show()
# start the app
sys.exit(App.exec())
if __name__ == '__main__':
main()