util_chart.py
功能:图形显示
# -*- coding: utf-8 -*-
import sys
import os
import csv
import pandas as pd
from datetime import datetime
from PyQt5.QtGui import *
from serial.tools.list_ports import comports
from PyQt5.QtChart import *
from widget_serial import *
from PyQt5.QtGui import QFont
'''
主工具
'''
class ChartWidget(QWidget):
def __init__(self):
super().__init__()
self.initUI()
'''
UI布局
'''
def initUI(self):
hb = QHBoxLayout()
hb.setSpacing(20)
self.setLayout(hb)
leftLayout = QVBoxLayout()
leftLayout.setSpacing(10)
hb.addLayout(leftLayout, stretch=1)
'''
右边,输入/输出区
'''
rightLayout = QVBoxLayout()
rightLayout.setSpacing(10)
hb.addLayout(rightLayout, stretch=4)
self.setStyleSheet('''QGroupBox{
background:#DDFFFF;
border:1px solid gray;
border-radius:10px;
padding:4px;
text-align:center;
font:12px
}''')
'''
Chart 1
'''
self.chtCurVol = QChart()
self.chtCurVol.axisX = QDateTimeAxis()
self.chtCurVol.axisX.setFormat("MM-dd HH:mm:ss")
# self.cdt = QDateTime.currentDateTime()
# self.chtCurVol.axisX.setRange(self.cdt, self.cdt.addSecs(6000))
self.chtCurVol.axisX.setTickCount(29)
self.chtCurVol.axisX.setLabelsAngle(90)
self.chtCurVol.addAxis(self.chtCurVol.axisX, Qt.AlignBottom)
self.chtCurVol.axisY = QValueAxis()
self.chtCurVol.axisY.setRange(0, 1200)
self.chtCurVol.axisY.setLabelFormat('%i')
self.chtCurVol.axisY.setTickCount(7)
self.chtCurVol.axisY.setTitleText("mA")
self.chtCurVol.addAxis(self.chtCurVol.axisY, Qt.AlignLeft)
self.chtCurVol.axisYRight = QValueAxis()
self.chtCurVol.axisYRight.setRange(0, 6.0)
self.chtCurVol.axisYRight.setTickCount(7)
self.chtCurVol.axisYRight.setTitleText("V")
self.chtCurVol.addAxis(self.chtCurVol.axisYRight, Qt.AlignRight)
# 添加曲线
self.chtCurVol.seriesCur = QLineSeries()
self.chtCurVol.seriesVol = QLineSeries()
self.chtCurVol.seriesCur.setName("电流")
self.chtCurVol.seriesVol.setName("电压")
# 添加曲线上的点,添加数据用这个
# self.chtCurVol.seriesCur.append((self.cdt.addSecs(1*60)).toMSecsSinceEpoch(),300)
# --------
self.chtCurVol.seriesCur.setVisible(True)
self.chtCurVol.seriesVol.setVisible(True)
# 设置曲线上点的显示
font = QFont()
font.setPointSize(12)
self.chtCurVol.seriesCur.setPointLabelsFont(font)
self.chtCurVol.seriesVol.setPointLabelsFont(font)
# 将曲线加到坐标图里面去
self.chtCurVol.addSeries(self.chtCurVol.seriesCur)
self.chtCurVol.addSeries(self.chtCurVol.seriesVol)
self.chtCurVol.seriesCur.attachAxis(self.chtCurVol.axisX)
self.chtCurVol.seriesVol.attachAxis(self.chtCurVol.axisX)
self.chtCurVol.seriesCur.attachAxis(self.chtCurVol.axisY)
self.chtCurVol.seriesVol.attachAxis(self.chtCurVol.axisYRight)
self.chtCurVol.seriesCur.setColor(QColor(0, 0xFF, 0))
self.chtCurVol.seriesVol.setColor(QColor(0, 0, 0xFF))
self.chtCurVol.setBackgroundBrush(QBrush(QColor("lightcyan")))
'''
Chart 2
'''
self.chtIO = QChart()
self.chtIO.axisX = QDateTimeAxis()
self.chtIO.axisX.setFormat("MM-dd HH:mm:ss")
# self.chtIOcdt = QDateTime.currentDateTime()
# self.chtIO.axisX.setRange(self.chtIOcdt, self.chtIOcdt.addSecs(6000))
self.chtIO.axisX.setTickCount(21)
self.chtIO.axisX.setLabelsAngle(90)
self.chtIO.addAxis(self.chtIO.axisX, Qt.AlignBottom)
self.chtIO.axisY = QValueAxis()
self.chtIO.axisY.setRange(0, 1.2)
self.chtIO.axisY.setTickCount(7)
self.chtIO.addAxis(self.chtIO.axisY, Qt.AlignLeft)
self.chtIO.axisY.setTitleText("V")
# 添加曲线
self.chtIO.series = QLineSeries()
self.chtIO.series.setName("电平")
# 添加曲线上的点
# self.chtIO.series.append((cdt.addSecs(1*60)).toMSecsSinceEpoch(),0)
# --------
self.chtIO.series.setVisible(True)
# 设置曲线上点的显示
font = QFont()
font.setPointSize(12)
self.chtIO.series.setPointLabelsFont(font)
self.chtIO.setBackgroundBrush(QBrush(QColor("lightcyan")))
# 将曲线加到坐标图里面去
self.chtIO.addSeries(self.chtIO.series)
self.chtIO.series.attachAxis(self.chtIO.axisX)
self.chtIO.series.attachAxis(self.chtIO.axisY)
self.chtIO.series.setColor(QColor(0, 0, 0xFF))
chvCurVol = QChartView(self.chtCurVol)
chvIO = QChartView(self.chtIO)
rightLayout.addWidget(chvCurVol)
rightLayout.addWidget(chvIO)
chvCurVol.setRubberBand(QChartView.HorizontalRubberBand)
chvCurVol.setRenderHint(QPainter.Antialiasing)
chvCurVol.setDragMode(QGraphicsView.ScrollHandDrag)
chvCurVol.chart().setAnimationOptions(QChart.AllAnimations)
chvCurVol.setInteractive(True)
chvCurVol.setRenderHint(QPainter.Antialiasing)
chvCurVol.setRubberBand(QChartView.HorizontalRubberBand)
chvCurVol.setDragMode(QGraphicsView.NoDrag)
chvCurVol.chart().setAnimationOptions(QChart.AllAnimations)
chvCurVol.setRubberBandSelectionMode(Qt.IntersectsItemShape)
chvIO.setRubberBand(QChartView.HorizontalRubberBand)
chvIO.setRenderHint(QPainter.Antialiasing)
chvIO.setDragMode(QGraphicsView.ScrollHandDrag)
chvIO.chart().setAnimationOptions(QChart.AllAnimations)
chvIO.setInteractive(True)
chvIO.setRenderHint(QPainter.Antialiasing)
chvIO.setRubberBand(QChartView.HorizontalRubberBand)
chvIO.setDragMode(QGraphicsView.NoDrag)
chvIO.chart().setAnimationOptions(QChart.AllAnimations)
chvIO.setRubberBandSelectionMode(Qt.IntersectsItemShape)
'''
左边,控制区
'''
#####
settingGroup = QGroupBox('通道选择')
grid = QGridLayout()
grid.setColumnStretch(1, 1)
settingGroup.setLayout(grid)
leftLayout.addWidget(settingGroup)
grid.addWidget(QLabel('ProjectName:'), 0, 0, alignment=Qt.AlignRight)
self.let_prj_name = QLineEdit('ProjectName')
self.let_prj_name.setMaxLength(20)
ft = self.let_prj_name.font()
ft.setPointSize(ft.pointSize() + 2)
self.let_prj_name.setFont(ft)
# let_prj_name.setEnabled(False)
grid.addWidget(self.let_prj_name, 0, 1)
grid.addWidget(QLabel('GroupNo:'), 1, 0, alignment=Qt.AlignRight)
self.cbGrp = QComboBox()
grid.addWidget(self.cbGrp, 1, 1)
grp_arr = ("Grp1", "Grp2", "Grp3", "Grp4",
"Grp5", "Grp6", "Grp7", "Grp8")
self.cbGrp.addItems(grp_arr)
grid.addWidget(QLabel('ChannelNo:'), 2, 0, alignment=Qt.AlignRight)
self.cbCh = QComboBox()
grid.addWidget(self.cbCh, 2, 1)
ch_arr = ("Ch1", "Ch2", "Ch3", "Ch4", "Ch5", "Ch6", "Ch7", "Ch8", "Ch9", "Ch10",
"Ch11", "Ch12", "Ch13", "Ch14", "Ch15", "Ch16", "Ch17", "Ch18", "Ch19", "Ch20")
self.cbCh.addItems(ch_arr)
buttonGroup = QGroupBox('时间选择')
grid = QGridLayout()
grid.setColumnStretch(1, 1)
buttonGroup.setLayout(grid)
leftLayout.addWidget(buttonGroup)
grid.addWidget(QLabel('TimeStart:'), 1, 0)
now = QDateTime.currentDateTime()
now.setTime(QTime(now.time().hour(), now.time().minute(), 0))
self.dtStart = QDateTimeEdit(now)
self.dtStart.setCalendarPopup(True)
grid.addWidget(self.dtStart, 1, 1)
grid.addWidget(QLabel('TimeEnd:'), 2, 0)
now.setTime(QTime(now.time().hour(), now.time().minute(), 59))
self.dtEnd = QDateTimeEdit(now)
self.dtEnd.setCalendarPopup(True)
grid.addWidget(self.dtEnd, 2, 1)
btnQuery = QPushButton('查询')
btnQuery.setFixedHeight(50)
grid.addWidget(btnQuery, 3, 0, 1, 2)
btnQuery.setStyleSheet('''QPushButton{
background:#77FFFF;
border-radius:10px;
border:1px solid gray;
font:14px
}''')
btnClrLog = QPushButton('')
btnClrLog.setFlat(True)
btnClrLog.setIcon(QIcon('res/clear.png'))
grid.addWidget(btnClrLog, 5, 1, alignment=Qt.AlignRight)
self.te_log = QTextEdit('')
self.te_log.setReadOnly(True)
self.te_log.setStyleSheet('font-size:30')
self.te_log.setFixedHeight(490)
grid.addWidget(self.te_log, 6, 0, 5, 2)
leftLayout.addStretch()
btnClrLog.clicked.connect(self.te_log.clear)
btnQuery.clicked.connect(self.onBtnQuery)
def onBtnQuery(self):
self.chtCurVol.seriesCur.clear()
self.chtCurVol.seriesVol.clear()
self.chtIO.series.clear()
grp_index = self.cbGrp.currentText().strip('Grp')
ch_index = self.cbCh.currentText().strip('Ch')
startTime = self.dtStart.dateTime()
start_time = startTime.toString("yyyy-MM-dd_HH-mm-ss")
endTime = self.dtEnd.dateTime()
end_time = endTime.toString("yyyy-MM-dd_HH-mm-ss")
print(grp_index, ch_index, start_time, end_time)
csvName = os.path.join("Log", "{}_Grp{}_Ch{}.csv".format(
self.let_prj_name.text(), str(grp_index), str(ch_index)))
if not os.path.exists(csvName):
print(csvName + " does not exist")
self.te_log.append(csvName + " does not exist")
else:
df = pd.read_csv(csvName)
# Convert 'DateTime' column to datetime
df['DateTime'] = pd.to_datetime(
df['DateTime'], format="%Y-%m-%d_%H-%M-%S")
# Convert 'start_time' to datetime and round down to the nearest minute
start_time = pd.to_datetime(start_time, format="%Y-%m-%d_%H-%M-%S")
# Filter rows where 'DateTime' is equal to 'start_time'
df_start_time = df[df['DateTime'] >= start_time]
if not df_start_time.empty:
start_row = df_start_time.index[0]
print('fisrt row: ', start_row)
else:
self.te_log.append("No rows found with the start time")
print("No rows found with the start time", start_time)
return
# Convert 'end_time' to datetime and round up to the nearest minute
end_time = pd.to_datetime(end_time, format="%Y-%m-%d_%H-%M-%S")
# Filter rows where 'DateTime' is equal to 'end_time'
df_end_time = df[df['DateTime'] <= end_time]
if not df_end_time.empty:
end_row = df_end_time.index[-1]
print('end row: ', end_row)
else:
self.te_log.append("No rows found with the end time")
print("No rows found with the end time:", end_time)
return
filtered_df = df[(df['DateTime'] >= start_time)
& (df['DateTime'] <= end_time)]
self.chtCurVol.axisX.setRange(start_time, end_time)
self.chtIO.axisX.setRange(start_time, end_time)
# self.chtCurVol.axisX.setRange(filtered_df.iloc[0, 0], filtered_df.iloc[-1, 0])
# self.chtIO.axisX.setRange(filtered_df.iloc[0, 0], filtered_df.iloc[-1, 0])
for index, row in filtered_df.iterrows():
dt = QDateTime.fromString(row.iloc[0].strftime(
"%Y-%m-%d_%H-%M-%S"), "yyyy-MM-dd_HH-mm-ss")
seconds = dt.toMSecsSinceEpoch()
self.chtCurVol.seriesCur.append(seconds, row.iloc[1])
self.chtCurVol.seriesVol.append(seconds, row.iloc[2])
self.chtIO.series.append(seconds, row.iloc[3])
if __name__ == '__main__':
app = QApplication(sys.argv)
win = ChartWidget()
win.setWindowTitle("Chart")
win.setWindowIcon(QIcon('res/logo.png'))
win.resize(1024, 800)
win.show()
sys.exit(app.exec_())