diff --git a/LaserMehtanePT_RB/pythonProject/data_processor.py b/LaserMehtanePT_RB/pythonProject/data_processor.py new file mode 100644 index 0000000..e69de29 diff --git a/PyNetAssistant/PyNet.exe b/PyNetAssistant/PyNet.exe index f090e79..b24519f 100644 Binary files a/PyNetAssistant/PyNet.exe and b/PyNetAssistant/PyNet.exe differ diff --git a/PyNetAssistant/PyNet.ini b/PyNetAssistant/PyNet.ini index 149f789..c8d1771 100644 --- a/PyNetAssistant/PyNet.ini +++ b/PyNetAssistant/PyNet.ini @@ -1,9 +1,9 @@ [UI_config] port = 9000 hex_send = 0 -hex_receive = 2 +hex_receive = 0 add_date = 0 -cr_lf = 2 +cr_lf = 0 auto_sav_log = 2 modbus_csv = 0 @@ -12,8 +12,8 @@ funcode = F4 position = 5 [DisHex_config] -row00 = 浓度|0|2|1|3F10|2 -row01 = 测试|1|3|1|105678|2 +row00 = |||||0 +row01 = |||||0 row02 = |||||0 row03 = |||||0 row04 = |||||0 @@ -114,103 +114,103 @@ row98 = |||||0 [Quick_config] log_time = 10 -button00 = | -button01 = | -button02 = | -button03 = read| -button04 = | -button05 = | -button06 = | -button07 = | -button08 = | -button09 = | -button10 = | -button11 = | -button12 = | -button13 = | -button14 = | -button15 = | -button16 = | -button17 = | -button18 = | -button19 = | -button20 = | -button21 = | -button22 = | -button23 = | -button24 = | -button25 = | -button26 = | -button27 = | -button28 = | -button29 = | -button30 = | -button31 = | -button32 = | -button33 = | -button34 = | -button35 = | -button36 = | -button37 = | -button38 = | -button39 = | -button40 = | -button41 = | -button42 = | -button43 = | -button44 = | -button45 = | -button46 = | -button47 = | -button48 = | -button49 = | -button50 = | -button51 = | -button52 = | -button53 = | -button54 = | -button55 = | -button56 = | -button57 = | -button58 = | -button59 = | -button60 = | -button61 = | -button62 = | -button63 = | -button64 = | -button65 = | -button66 = | -button67 = | -button68 = | -button69 = | -button70 = | -button71 = | -button72 = | -button73 = | -button74 = | -button75 = | -button76 = | -button77 = | -button78 = | -button79 = | -button80 = | -button81 = | -button82 = | -button83 = | -button84 = | -button85 = | -button86 = | -button87 = | -button88 = | -button89 = | -button90 = | -button91 = | -button92 = | -button93 = | -button94 = | -button95 = | -button96 = | -button97 = | -button98 = | +button00 = +button01 = +button02 = +button03 = +button04 = +button05 = +button06 = +button07 = +button08 = +button09 = +button10 = +button11 = +button12 = +button13 = +button14 = +button15 = +button16 = +button17 = +button18 = +button19 = +button20 = +button21 = +button22 = +button23 = +button24 = +button25 = +button26 = +button27 = +button28 = +button29 = +button30 = +button31 = +button32 = +button33 = +button34 = +button35 = +button36 = +button37 = +button38 = +button39 = +button40 = +button41 = +button42 = +button43 = +button44 = +button45 = +button46 = +button47 = +button48 = +button49 = +button50 = +button51 = +button52 = +button53 = +button54 = +button55 = +button56 = +button57 = +button58 = +button59 = +button60 = +button61 = +button62 = +button63 = +button64 = +button65 = +button66 = +button67 = +button68 = +button69 = +button70 = +button71 = +button72 = +button73 = +button74 = +button75 = +button76 = +button77 = +button78 = +button79 = +button80 = +button81 = +button82 = +button83 = +button84 = +button85 = +button86 = +button87 = +button88 = +button89 = +button90 = +button91 = +button92 = +button93 = +button94 = +button95 = +button96 = +button97 = +button98 = diff --git a/PyNetAssistant/PyNet.py b/PyNetAssistant/PyNet.py index 6c4f3f5..54cfc0c 100644 --- a/PyNetAssistant/PyNet.py +++ b/PyNetAssistant/PyNet.py @@ -6,6 +6,7 @@ Created on Sun Sep 29 09:01:22 2024 """ import datetime import os +os.environ['QT_OPENGL'] = 'software' # 强制使用软件渲染 import re import socket import sys @@ -14,7 +15,7 @@ import time from configparser import ConfigParser from PyQt5 import QtWidgets -from PyQt5.QtCore import QTimer,Qt +from PyQt5.QtCore import QTimer from PyQt5.QtWidgets import QMessageBox, QFileDialog, QInputDialog, QTableWidgetItem from PyNetUi import Ui_UartAssistant @@ -115,7 +116,7 @@ class Pyqt5Net(QtWidgets.QWidget, Ui_UartAssistant): self.tableWidget.setRowCount(self.quick_num) for i in range(self.quick_num): # 从0到20 item = QtWidgets.QTableWidgetItem() - item.setCheckState(Qt.Unchecked) + item.setCheckState(0) self.tableWidget.setItem(i, 0, item) @@ -244,6 +245,13 @@ class Pyqt5Net(QtWidgets.QWidget, Ui_UartAssistant): if line_utf8[2*self.position:2*self.position+2] == self.funcode: sav_name = line_utf8[0:8] + '_' + datetime.datetime.now().strftime("%Y-%m-%d") + '.txt' sav_str = datetime.datetime.now().strftime("%Y-%m-%dT%H:%M:%S.%f")[:23] + " " + out_s[12:] + "\r\n" + #当表示浓度的字符不为0时 将数据单独记录 + if line_utf8[14:18] != '0000': + sav_name_alarm = 'alarm_' + line_utf8[0:8] + '_' + datetime.datetime.now().strftime("%Y-%m-%d") + '.txt' + sav_str_alarm = datetime.datetime.now().strftime("%Y-%m-%dT%H:%M:%S.%f")[:23] + " " + out_s[ 12:] + "\r\n" + with open(sav_name_alarm, mode='a', newline='', encoding='utf-8', errors='replace') as file: + file.writelines(sav_str_alarm) + else: sav_name = datetime.datetime.now().strftime("%Y-%m-%d") + '.log' sav_str = datetime.datetime.now().strftime("%Y-%m-%dT%H:%M:%S.%f")[:23] + " " + out_s + "\r\n" diff --git a/PyUartAssistantBigData/.idea/.gitignore b/PyUartAssistantBigData/.idea/.gitignore new file mode 100644 index 0000000..3a86cee --- /dev/null +++ b/PyUartAssistantBigData/.idea/.gitignore @@ -0,0 +1,8 @@ +# 默认忽略的文件 +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/PyUartAssistantBigData/.idea/PyUartAssistantBigData.iml b/PyUartAssistantBigData/.idea/PyUartAssistantBigData.iml new file mode 100644 index 0000000..d0876a7 --- /dev/null +++ b/PyUartAssistantBigData/.idea/PyUartAssistantBigData.iml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/PyUartAssistantBigData/.idea/inspectionProfiles/Project_Default.xml b/PyUartAssistantBigData/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 0000000..3dce9c6 --- /dev/null +++ b/PyUartAssistantBigData/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,12 @@ + + + + \ No newline at end of file diff --git a/PyUartAssistantBigData/.idea/inspectionProfiles/profiles_settings.xml b/PyUartAssistantBigData/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 0000000..105ce2d --- /dev/null +++ b/PyUartAssistantBigData/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/PyUartAssistantBigData/.idea/misc.xml b/PyUartAssistantBigData/.idea/misc.xml new file mode 100644 index 0000000..a6218fe --- /dev/null +++ b/PyUartAssistantBigData/.idea/misc.xml @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/PyUartAssistantBigData/.idea/modules.xml b/PyUartAssistantBigData/.idea/modules.xml new file mode 100644 index 0000000..3a12f49 --- /dev/null +++ b/PyUartAssistantBigData/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/PyUartAssistantBigData/.idea/vcs.xml b/PyUartAssistantBigData/.idea/vcs.xml new file mode 100644 index 0000000..6c0b863 --- /dev/null +++ b/PyUartAssistantBigData/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/PyUartAssistantBigData/.vscode/launch.json b/PyUartAssistantBigData/.vscode/launch.json new file mode 100644 index 0000000..05c523d --- /dev/null +++ b/PyUartAssistantBigData/.vscode/launch.json @@ -0,0 +1,15 @@ +{ + // 使用 IntelliSense 了解相关属性。 + // 悬停以查看现有属性的描述。 + // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "Python 调试程序: 当前文件", + "type": "debugpy", + "request": "launch", + "program": "${file}", + "console": "integratedTerminal" + } + ] +} \ No newline at end of file diff --git a/PyUartAssistantBigData/BigData_Plot.py b/PyUartAssistantBigData/BigData_Plot.py new file mode 100644 index 0000000..e2e0b07 --- /dev/null +++ b/PyUartAssistantBigData/BigData_Plot.py @@ -0,0 +1,56 @@ +from PyQt5.QtWidgets import QDialog, QGridLayout, QApplication +from matplotlib.figure import Figure +from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas +from matplotlib.backends.backend_qt5 import NavigationToolbar2QT +from PyQt5.QtCore import Qt + +class MyFigureCanvas(FigureCanvas): + def __init__(self, parent=None): + self.figure = Figure() + super(MyFigureCanvas, self).__init__(self.figure) + self.setParent(parent) + +class ChartDialog(QDialog): + def __init__(self, data=None, title="Line Chart", xlabel="X", ylabel="Y", parent=None): + super(ChartDialog, self).__init__(parent) + self.setWindowFlags(Qt.Window) + self.data = data if data is not None else (range(2, 26, 2), [15, 13, 14.5, 17, 20, 25, 26, 26, 27, 22, 18, 15]) + self.title = title + self.xlabel = xlabel + self.ylabel = ylabel + self.initUI() + + def initUI(self): + self.setWindowTitle(self.title) # 确保标题被设置 + layout = QGridLayout() + self.figureCanvas = MyFigureCanvas(self) + self.draw_figure() + self.navigationToolbar = NavigationToolbar2QT(self.figureCanvas, self) + layout.addWidget(self.navigationToolbar, 0, 0, 1, 1) + layout.addWidget(self.figureCanvas, 1, 0, 1, 1) + self.setLayout(layout) + #self.setGeometry(300, 300, 600, 400) + + def draw_figure(self): + + self.figureCanvas.figure.clear() # 清除整个 Figure + self.axes = self.figureCanvas.figure.add_subplot(111) # 添加新的 Axes + self.axes.set_title(self.title) + self.axes.set_xlabel(self.xlabel) + self.axes.set_ylabel(self.ylabel) + x, y = self.data + self.axes.plot(x, y, color='red') + self.figureCanvas.figure.canvas.draw_idle() # 更新画布上的绘图 + + def tans_data(self,data): + self.data = data + + +def main(): + app = QApplication([]) + dialog = ChartDialog() + dialog.show() + app.exec_() + +if __name__ == "__main__": + main() diff --git a/PyUartAssistantBigData/OtherData.ini b/PyUartAssistantBigData/OtherData.ini new file mode 100644 index 0000000..f0e263a --- /dev/null +++ b/PyUartAssistantBigData/OtherData.ini @@ -0,0 +1,5 @@ +[OtherData_config] +regular = \+?-?\d+(?:\.\d+)? +headstr = A+ +rowtitle = time,DATA1,DATA2 + diff --git a/PyUartAssistantBigData/PyUart.exe b/PyUartAssistantBigData/PyUart.exe new file mode 100644 index 0000000..9af3486 Binary files /dev/null and b/PyUartAssistantBigData/PyUart.exe differ diff --git a/PyUartAssistantBigData/PyUart.ini b/PyUartAssistantBigData/PyUart.ini new file mode 100644 index 0000000..3128959 --- /dev/null +++ b/PyUartAssistantBigData/PyUart.ini @@ -0,0 +1,117 @@ +[QX_config] +regular = \+?-?\d+(?:\.\d+)? +headstr = A+ +rowtitle = time,Methane,Air Temp,Laser Temp,Laser Intensity + +[TF_config] +regular = \+?-?\d+(?:\.\d+)? +headstr = A+ +rowtitle = time,Methane,Air Temp,Laser Temp,Laser Intensity,amplification,NL,ND,Sinal,SNR,PEAK,Best Piont + +[OtherData_config] +regular = \+?-?\d+(?:\.\d+)? +headstr = A+ +rowtitle = time,DATA1,DATA2 + +[Quick_config] +log_time = 10 +button00 = read 30|smooth +button01 = read 31|peak std +button02 = read 32|SNR +button03 = | +button04 = write 30,1| +button05 = write 31,10| +button06 = | +button07 = write 7,0|激光输出 +button08 = | +button09 = | +button10 = | +button11 = | +button12 = | +button13 = | +button14 = | +button15 = | +button16 = | +button17 = | +button18 = | +button19 = | +button20 = | +button21 = | +button22 = | +button23 = | +button24 = | +button25 = | +button26 = | +button27 = | +button28 = | +button29 = | +button30 = | +button31 = | +button32 = | +button33 = | +button34 = | +button35 = | +button36 = | +button37 = | +button38 = | +button39 = | +button40 = | +button41 = | +button42 = | +button43 = | +button44 = | +button45 = | +button46 = | +button47 = | +button48 = | +button49 = | +button50 = | +button51 = | +button52 = | +button53 = | +button54 = | +button55 = | +button56 = | +button57 = | +button58 = | +button59 = | +button60 = | +button61 = | +button62 = | +button63 = | +button64 = | +button65 = | +button66 = | +button67 = | +button68 = | +button69 = | +button70 = | +button71 = | +button72 = | +button73 = | +button74 = | +button75 = | +button76 = | +button77 = | +button78 = | +button79 = | +button80 = | +button81 = | +button82 = | +button83 = | +button84 = | +button85 = | +button86 = | +button87 = | +button88 = | +button89 = | +button90 = | +button91 = | +button92 = | +button93 = | +button94 = | +button95 = | +button96 = | +button97 = | +button98 = | + diff --git a/PyUartAssistantBigData/PyUart.py b/PyUartAssistantBigData/PyUart.py new file mode 100644 index 0000000..ee4c17e --- /dev/null +++ b/PyUartAssistantBigData/PyUart.py @@ -0,0 +1,858 @@ +# -*- coding: utf-8 -*- +""" +Created on Mon May 27 14:31:38 2024 + +@author: WANGXIBAO +""" + +import sys,os +import serial,re +import serial.tools.list_ports +import time,datetime + +from PyQt5 import QtWidgets +from PyQt5.Qt import QPainter +from PyQt5.QtWidgets import QMessageBox ,QFileDialog,QInputDialog, QFrame +from PyQt5.QtCore import QTimer +from serial import Serial + +from PyUartUi import Ui_UartAssistant +from UartDataPolt import QChartViewPlot,UpdateDataThread,GetDataTF +from PyQt5.QtChart import QChartView +from PyQt5.QtGui import QIcon +from configparser import ConfigParser +from BigData_Plot import ChartDialog + + + +class PyQt5Serial(QtWidgets.QWidget,Ui_UartAssistant): + ser: Serial | Serial + + # %%初始化程序 + def __init__(self): + super(PyQt5Serial, self).__init__() + self.setupUi(self) + self.quick_num = 99 + self.IniPath = "PyUart.ini" + self.log_time = 10 + self.log_buffer = {} #定义成一个字典,键--文件名,值--对于收到的字符串列表 + self.qxCfg=() + self.tfCfg=() + self.otCfg=() + self.current_lines = [] #定义一个空列表,存储待显示数据 + + self.update_data_thread = UpdateDataThread() # 创建更新波形数据线程 + self.get_data_tf = GetDataTF() + self.get_data_tf.IndOfReturn(0) #根据数据特点给一个初始值 + + self.chart_dialog = ChartDialog() + + self.init() + self.CheckCfgIniData() #更改按钮的文字 + + self.ser = serial.Serial() #创建一个空对象 + self.port_check() + + # 设置Logo和标题 + self.setWindowIcon(QIcon('./favicon.ico')) + self.setWindowTitle("调试助手") + # 设置禁止拉伸窗口大小 + #self.setFixedSize(self.width(), self.height()) + + # 发送数据和接收数据数目置零 + self.data_num_sended = 0 + self.lineEditSendNum.setText(str(self.data_num_sended)) + self.data_num_received = 0 + self.lineEditReceiveNum.setText(str(self.data_num_received)) + + # 串口关闭按钮使能关闭 + self.pushButtonCloseSerial.setEnabled(False) + + # 发送框、文本框清除 + self.textEditReceive.setPlainText("") + self.textEditReceive.setMaximumBlockCount(5000) + self.textEditSend.setText("") + # %%第二个TAB 初始化画图页面表格 + self.pushButtonStopPlot.setEnabled(False) + self.pushButtonStartPlot.setEnabled(True) + self.radioButtonCH4QX.setEnabled(True) + self.radioButtonCH4TF.setEnabled(True) + self.checkBoxAutoSaveCsv.setEnabled(False) + self.pushButton_expend.setEnabled(False) + + # 加载Qchart波形界面 + self.plot_qchart = QChartViewPlot() + #设置外边框为0 + self.plot_qchart.setBackgroundRoundness(0) + self.plot_qchart.layout().setContentsMargins(0, 0, 0, 0) + self.plot_view.setChart(self.plot_qchart) + self.plot_view.setRenderHint(QPainter.Antialiasing) # 抗锯齿 + self.plot_view.setRubberBand(QChartView.RectangleRubberBand) + # 移除外部边框 + # self.plot_view.setFrameShape(QFrame.NoFrame) + # self.plot_view.setStyleSheet("border: none;") + + + + #加载快捷指令 + self.widget_6.hide() + #加载快捷指令的按键值 + + # 用于暂存接收的串口数据 + self.buffer = b'' + # 用于暂存解码数据 + self.lineUtf8 = "" + # 用于标志是否开始存CSV + self.flag_draw = 0 + #用于暂存大数据 + self.bigdata=[] + #开启大数据模式标志位 + self.flag_bigdata =0 + + + + self.double_click_timers = {} # 存储双击定时器 + # ============================================================================= +# def wheelEvent(self, event): +# if self.plot_view.underMouse: +# # 鼠标滚轮:缩放Qchart波形 +# if event.angleDelta().y() >= 0: +# # 鼠标滚轮向上 +# if event.x() < ( +# self.plot_view.width() + self.plot_view.x()) and event.x() > self.plot_view.x(): +# if event.y() < ( +# self.plot_view.height() + self.plot_view.y()) and event.y() > self.plot_view.y(): +# self.plot_qchart.zoomIn() +# else: +# # 鼠标滚轮向下 +# if event.x() < ( +# self.plot_view.width() + self.plot_view.x()) and event.x() > self.plot_view.x(): +# if event.y() < ( +# self.plot_view.height() + self.plot_view.y()) and event.y() > self.plot_view.y(): +# self.plot_qchart.zoomOut() +# ============================================================================= + #%% 重写关闭按钮 + def closeEvent(self, event): + self.update_data_thread.stop() + # 可选:加入超时判断,防止线程未能正常退出导致程序无法关闭 + if not self.update_data_thread.wait(1000): # 等待5秒 + print("线程未在指定时间内退出,可能需要进一步处理") + + + # 如果串口已经打开,则关闭串口 + if self.ser.is_open: + self.port_close() + + #关闭界面前保存快捷区域的命令和名称 + for i in range(self.quick_num): # 假设有20个按钮 + index_str = f"{i:02}" # 确保编号为两位数字形式 + lineEditName = f"lineEditQuick_{index_str}" + buttonName = f"pushButtonQuick_{index_str}" # 格式化按钮名称,确保两位数 + button_name = f"button{index_str}" + set_text = getattr(self,lineEditName).text()+ "|" + getattr(self,buttonName).text() + self.SetCfgIniData(button_name, set_text) + + + + + # 调用父类的关闭事件处理函数 + super().closeEvent(event) + + + + + # %%建立控件信号与槽关系 + def init(self): + # 串口检测按钮 + self.pushButtonTestSerial.clicked.connect(self.port_check) + # 串口打开按钮 + self.pushButtonOpenSerial.clicked.connect(self.port_open) + # 串口关闭按钮 + self.pushButtonCloseSerial.clicked.connect(self.port_close) + + # 定时发送数据 + self.timer_send = QTimer() + self.timer_send.timeout.connect(self.data_send) + self.checkBoxReapitSend.stateChanged.connect(self.data_send_timer) + + # 发送数据按钮 + self.pushButtonSend.clicked.connect(lambda:self.data_send(text_quick= None)) + + # 保存日志 + self.pushButtonLogSave.clicked.connect(self.savefiles) + # 加载日志 + self.pushButtonLogLoad.clicked.connect(self.openfiles) + + # hexRecevie与savCsv的按键关联 + self.checkBoxHexReceive.stateChanged.connect(self.hex_link_savCsv) + + # 清除发送按钮 + self.pushButtonClearSend.clicked.connect(self.send_data_clear) + + # 清除接收按钮 + self.pushButtonClearReceive.clicked.connect(self.receive_data_clear) + + # 开始绘图 + self.pushButtonStartPlot.clicked.connect(self.btn_start_clicked) + # 关闭绘图 + self.pushButtonStopPlot.clicked.connect(self.btn_stop_clicked) + #线程信号发射 + self.update_data_thread._signal_update.connect(self.update_data_thread_slot) + # 选择绘图 + self.comboBoxPlot.currentIndexChanged.connect(self.plot_item_changed) + # 重置绘图 + self.pushButtonResetPlot.clicked.connect(self.plot_reset) + # 快捷指令扩展区域 + self.pushButton_expend.clicked.connect(self.adjust_sidebar) + #大数据模式 + self.pushButton_bigdata.clicked.connect(self.bigdata_show) + # 创建一个通用的槽函数来处理所有按钮 + # 动态创建控件并存储引用 + for i in range(self.quick_num): # 从0到20 + index_str = f"{i:02}" # 确保编号为两位数字形式 + horizontalLayoutName = f"horizontalLayoutQuick_{index_str}" + horizontalLayout = QtWidgets.QHBoxLayout() + horizontalLayout.setObjectName(horizontalLayoutName) + + # 创建 QLineEdit 并设置动态属性 + lineEditName = f"lineEditQuick_{index_str}" + setattr(self, lineEditName, QtWidgets.QLineEdit(self.layoutWidget1)) + getattr(self, lineEditName).setObjectName(lineEditName) + horizontalLayout.addWidget(getattr(self, lineEditName)) + # 创建 QPushButton 并设置动态属性 + buttonName = f"pushButtonQuick_{index_str}" + setattr(self, buttonName, QtWidgets.QPushButton(self.layoutWidget1)) + getattr(self, buttonName).setObjectName(buttonName) + horizontalLayout.addWidget(getattr(self, buttonName)) + self.verticalLayout_8.addLayout(horizontalLayout) + # 连接按钮点击事件到槽函数 + button = getattr(self, buttonName) + if button: + button.clicked.connect(lambda checked, idx=i: self.onButtonClick(idx)) + + # %% 串口检测 + def port_check(self): + # 检测所有存在的串口,将信息存储在字典中 + self.Com_Dict = {} + port_list = list(serial.tools.list_ports.comports()) + + self.comboBoxSerial.clear() + for port in port_list: + self.Com_Dict["%s" % port[0]] = "%s" % port[1] + self.comboBoxSerial.addItem(port[0]) + + # 无串口判断 + if len(self.Com_Dict) == 0: + self.comboBoxSerial.addItem("无串口") + # %%打开串口 + def port_open(self): + self.ser.port = self.comboBoxSerial.currentText() # 串口号 + self.ser.baudrate = int(self.comboBoxBaudrate.currentText()) # 波特率 + self.ser.timeout = 0.001 + + + + flag_data = int(self.comboBoxDataBits.currentText()) # 数据位 + if flag_data == 5: + self.ser.bytesize = serial.FIVEBITS + elif flag_data == 6: + self.ser.bytesize = serial.SIXBITS + elif flag_data == 7: + self.ser.bytesize = serial.SEVENBITS + else: + self.ser.bytesize = serial.EIGHTBITS + + flag_data = self.comboBoxCheckBit.currentText() # 校验位 + if flag_data == "None": + self.ser.parity = serial.PARITY_NONE + elif flag_data == "Odd": + self.ser.parity = serial.PARITY_ODD + else: + self.ser.parity = serial.PARITY_EVEN + + flag_data = int(self.comboBoxStopBit.currentText()) # 停止位 + if flag_data == 1: + self.ser.stopbits = serial.STOPBITS_ONE + else: + self.ser.stopbits = serial.STOPBITS_TWO + + flag_data = self.comboBoxFlow.currentText() # 流控 + if flag_data == "No Ctrl Flow": + self.ser.xonxoff = False #软件流控 + self.ser.dsrdtr = False #硬件流控 DTR + self.ser.rtscts = False #硬件流控 RTS + elif flag_data == "SW Ctrl Flow": + self.ser.xonxoff = True #软件流控 + else: + if self.checkBoxDTR.isChecked(): + self.ser.dsrdtr = True #硬件流控 DTR + if self.checkBoxRTS.isChecked(): + self.ser.rtscts = True #硬件流控 RTS + try: + time.sleep(0.1) + if self.ser.is_open: + self.ser.close() + self.ser.open() + except: + QMessageBox.critical(self, "串口异常", "此串口不能被打开!") + return None + + # 串口打开后,切换开关串口按钮使能状态,防止失误操作 + if self.ser.isOpen(): + self.pushButtonOpenSerial.setEnabled(False) + self.pushButtonCloseSerial.setEnabled(True) + self.comboBoxBaudrate.setEnabled(False) + self.comboBoxSerial.setEnabled(False) + self.pushButton_expend.setEnabled(True) + #self.formGroupBox1.setTitle("串口状态(开启)") + + #日志保存 + # 格式化日期时间字符串,用于文件名 + # 例如:2024-05-28_12-34-56.txt + self.file = self.ser.port+"-"+time.strftime("%Y%m%d%H%M%S", time.localtime()) + self.filename = self.file + ".txt" + + + # 定时器接收数据 + self.timer = QTimer() + self.timer.timeout.connect(self.data_receive) + # 打开串口接收定时器,周期为1ms + self.timer.start(20) + + # %%接收数据 + def data_receive(self): + + try: + num = self.ser.inWaiting() + + + if num>0 : + #print("接收数据",datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f")) + try: + data = self.ser.read(num) + except: + QMessageBox.critical(self, '串口异常') + self.buffer+=data + + #print("接收完成",datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f")) + + # 获取到text光标 + textCursor = self.textEditReceive.textCursor() + # 滚动到底部 + textCursor.movePosition(textCursor.End) + # 设置光标到text中去 + self.textEditReceive.setTextCursor(textCursor) + if self.checkBoxAddDate.isChecked(): + nowTime = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f") + nowTime = nowTime[:-3] + self.textEditReceive.insertPlainText(nowTime + " ") + #self.add_line_to_textedit(nowTime + " ") + # HEX显示数据 + if self.checkBoxHexReceive.checkState(): + out_s = '' + for i in range(0, len(data)): + out_s = out_s + '{:02X}'.format(data[i]) + ' ' + + self.textEditReceive.insertPlainText(out_s) + #self.add_line_to_textedit(out_s) + # ASCII显示数据 + else: + #print("解码前",datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f")) + self.textEditReceive.insertPlainText(data.decode('utf-8',errors='replace')) + #self.add_line_to_textedit(data.decode('utf-8',errors='replace')) + #print("解码数据",datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f")) + # 接收换行 + if self.checkBoxCRLF.isChecked(): + self.textEditReceive.insertPlainText('\r\n') + #self.add_line_to_textedit('\r\n') + + + + # 统计接收字符的数量 + self.data_num_received += num + self.lineEditReceiveNum.setText(str(self.data_num_received)) + + # 自动保存日志 + if self.checkBoxAutoSaveLog.isChecked(): + self.AutoSaveLog() + if self.flag_bigdata == 1: + self.BigDataPlot() + + + except: + # QMessageBox.critical(self, '串口异常', '串口接收数据异常,请重新连接设备!') + # 获取到text光标 + textCursor = self.textEditReceive.textCursor() + # 滚动到底部 + textCursor.movePosition(textCursor.End) + # 设置光标到text中去 + self.textEditReceive.setTextCursor(textCursor) + self.textEditReceive.insertPlainText("串口断开,重连中...\r\n") + self.ser.close() + + try: + print("重连中...") + time.sleep(1) + if not self.ser.is_open: + self.ser.open() + print("重连成功") + self.textEditReceive.insertPlainText("重连成功\r\n") + else: + print("串口已连接,无需重连") + except Exception as e: + + print(f"重连失败{e}") + + + + # %%定时发送数据 + def data_send_timer(self): + try: + if 1<= int(self.lineEditTime.text()) <= 30000: # 定时时间1ms~30s内 + if self.checkBoxReapitSend.isChecked(): + self.timer_send.start(int(self.lineEditTime.text())) + self.lineEditTime.setEnabled(False) + else: + self.timer_send.stop() + self.lineEditTime.setEnabled(True) + else: + QMessageBox.critical(self, '定时发送数据异常', '定时发送数据周期仅可设置在30秒内!') + except: + QMessageBox.critical(self, '定时发送数据异常', '请设置正确的数值类型!') + + # %%发送数据 + def data_send(self,text_quick = None): + if self.ser.isOpen(): + if text_quick== None: + input_s = self.textEditSend.toPlainText() + else: + input_s = text_quick + + # 判断是否为非空字符串 + if input_s != "": + # 时间显示 + if self.checkBoxAddDate.isChecked(): + self.textEditReceive.insertPlainText((time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())) + " ") + + # HEX发送 + if self.checkBoxHexSend.isChecked(): + input_s = input_s.strip() + send_list = [] + while input_s != '': + try: + num = int(input_s[0:2], 16) + except ValueError: + QMessageBox.critical(self, '串口异常', '请输入规范十六进制数据,以空格分开!') + return None + + input_s = input_s[2:].strip() + send_list.append(num) + + input_s = bytes(send_list) + # ASCII发送 + else: + input_s = (input_s).encode('utf-8') + input_s = re.sub(b'(?1: + self.buffer = lines.pop() + else: + self.buffer = b'' + + + # 处理每一行数据 + for line in lines: + # 注意:每行数据可能不包含结尾的换行符,所以在处理前检查一下 + if line.endswith(b'\r'): + line = line[:-1] # 移除回车 + if self.checkBoxHexReceive.checkState(): + lineUtf8 = line.hex() + out_s = ' '.join(['{:02X}'.format(b) for b in bytes.fromhex(lineUtf8)]) + saveData = datetime.datetime.now().strftime("%Y-%m-%dT%H:%M:%S.%f")[:23] +" " +out_s +"\r\n" + else: + lineUtf8 = line.decode('utf-8',errors='replace') + saveData = (time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())) + " " + lineUtf8 + "\r\n" + + # 将日志信息添加到缓冲区 + if self.filename not in self.log_buffer: + self.log_buffer[self.filename] = [] + self.log_buffer[self.filename].append(saveData) + + # 当缓冲区中的记录达到10条时,写入文件 + if len(self.log_buffer[self.filename]) >= self.log_time: + with open(self.filename, mode='a', newline='',encoding='utf-8', errors='replace') as file: + file.writelines(self.log_buffer[self.filename]) + self.log_buffer[self.filename].clear() + + + + + #判断选择的何种格式数据 + if self.radioButtonCH4QX.isChecked(): + self.get_data_tf.SetConfig(self.qxCfg) + if self.radioButtonCH4TF.isChecked(): + self.get_data_tf.SetConfig(self.tfCfg) + if self.radioButtonOtherData.isChecked(): + self.get_data_tf.SetConfig(self.otCfg) + + print(lineUtf8) + + if self.flag_draw: + + dataSplit = self.get_data_tf.Transdata(lineUtf8) + #print("dataSplit",type(dataSplit)) + if isinstance(dataSplit, (float, int)): + + self.filenameCsv= self.file + ".csv" + if self.checkBoxAutoSaveCsv.isChecked(): #写入CSV文件 + try: + self.get_data_tf.SaveCsv(self.filenameCsv,self.log_time) + except: + print("写入CSV失败") + pass + + self.update_data_thread.SetFlag(1) + #print("dataSplit",dataSplit) + self.update_data_thread.SetReceiveData(dataSplit) + #更新当前数据 + self.lineEditCurrentValue.setText(str(round(dataSplit,3))) + self.lineEditWindowMean.setText (str(round(self.plot_qchart.windowAverage,3))) + self.lineEditWindowMSE.setText (str(round(self.plot_qchart.windowStd,3))) + else: + print("Data split failed, dataSplit type:",type(dataSplit)) + + except Exception as e: + print(f"Error reading configuration: {e}") + print("自动保存日志失败") + pass + + def BigDataPlot(self): + + try: + lines = self.buffer.split(b'\n') # 或者使用 b'\r\n' 根据你的需要 + # 最后一个元素可能不包含完整的行,所以将其保留作为新的缓存 + self.buffer = lines.pop() + # 处理每一行数据 + for line in lines: + # 注意:每行数据可能不包含结尾的换行符,所以在处理前检查一下 + if line.endswith(b'\r'): + line = line[:-1] # 移除回车 + lineUtf8 = line.decode('utf-8') + if "end" in lineUtf8.lower() or len(self.bigdata) > 4999: + tansData = (range(len(self.bigdata)), self.bigdata) + self.chart_dialog.tans_data(tansData) + self.chart_dialog.draw_figure() + + self.bigdata = [] + else: + try: + self.bigdata.append(float(lineUtf8)) + # print(f'bigdata length:{len(self.bigdata)}') + except: + pass + + + except: + return None + + def send_data_clear(self): + self.textEditSend.setText("") + + self.data_num_sended = 0 + self.lineEditSendNum.setText(str(self.data_num_sended)) + + # 清除接收数据显示 + def receive_data_clear(self): + self.textEditReceive.setPlainText("") + + self.data_num_received = 0 + self.lineEditSendNum.setText(str(self.data_num_received)) + # 关联hex接收与保存csv,hex下不保存csv + def hex_link_savCsv(self): + if self.checkBoxHexReceive.isChecked(): + self.checkBoxAutoSaveCsv.setChecked(False) + else: + self.checkBoxAutoSaveCsv.setChecked(True) + + #设置接受区域显示条数 + def add_line_to_textedit(self, new_line): + # 获取当前文本并按行分割 + #current_lines = self.textEditReceive.toPlainText().splitlines() + # 添加新的行到列表中 + self.current_lines.append(new_line) + # 如果行数超过100,则删除最早的行,直到剩下100行 + if len(self.current_lines) > 100: + self.current_lines = self.current_lines[-100:] # 只保留最新的100行 + # 将更新后的行列表转换回字符串并设置为textEdit的内容 + self.textEditReceive.setPlainText(''.join(self.current_lines)) + #self.textEditReceive.setPlainText(self.current_lines) + # 关闭串口 + def port_close(self): + try: + self.timer.stop() + self.timer_send.stop() + self.btn_stop_clicked() #执行停止绘图操作 + self.ser.close() + except: + QMessageBox.critical(self, '串口异常', '关闭串口失败,请重启程序!') + return None + + # 切换开关串口按钮使能状态和定时发送使能状态 + self.pushButtonOpenSerial.setEnabled(True) + self.pushButtonCloseSerial.setEnabled(False) + self.lineEditTime.setEnabled(True) + self.comboBoxBaudrate.setEnabled(True) + self.comboBoxSerial.setEnabled(True) + self.pushButton_expend.setEnabled(False) + # 发送数据和接收数据数目置零 + self.data_num_sended = 0 + self.lineEditSendNum.setText(str(self.data_num_sended)) + self.data_num_received = 0 + self.lineEditReceiveNum.setText(str(self.data_num_received)) + + #self.formGroupBox1.setTitle("串口状态(关闭)") + #开始绘图 + def btn_start_clicked(self): + #开启按钮 + + self.update_data_thread.start() + self.update_data_thread.restart() + + self.pushButtonStartPlot.setEnabled(False) + self.pushButtonStopPlot.setEnabled(True) + self.radioButtonCH4QX.setEnabled(False) + self.radioButtonCH4TF.setEnabled(False) + self.radioButtonOtherData.setEnabled(False) + self.checkBoxAutoSaveCsv.setEnabled(True) + + iterm = self.get_data_tf.rowTitle[1:] + print("iterm",iterm) + self.comboBoxPlot.addItems(iterm) + + self.update_data_thread.SetPlotItem(0) + + self.update_data_thread.restart() + self.flag_draw = 1 + + + + #停止绘图 + def btn_stop_clicked(self): + self.update_data_thread.stop() + self.pushButtonStartPlot.setEnabled(True) + self.pushButtonStopPlot.setEnabled(False) + self.radioButtonCH4QX.setEnabled(True) + self.radioButtonCH4TF.setEnabled(True) + self.radioButtonOtherData.setEnabled(True) + self.checkBoxAutoSaveCsv.setEnabled(False) + self.comboBoxPlot.clear() + self.flag_draw = 0 + + def update_data_thread_slot(self, data): + # 线程回调函数 + #data = json.loads(data) + self.plot_qchart.handle_update(float(data)) + #print("thread ",data) + + def plot_item_changed(self,index): + print(index) + self.plot_qchart.clearSeries() + self.get_data_tf.IndOfReturn(index) + + def plot_reset(self): + self.plot_qchart.zoomReset() + #开关快捷指令栏 + def adjust_sidebar(self): + if self.widget_6.isHidden(): + self.widget_6.show() + else: + self.widget_6.hide() + def onPushButtonQuickClicked(self, line_edit): + text = getattr(self, line_edit).text() + #print(f"Button clicked: {text}") + if self.checkBox_return.isChecked(): + text = text + "\r\n" + self.data_send(text) + + + def CheckCfgIniData(self): + if not os.path.exists(self.IniPath): + config = ConfigParser() + #数据处理正则表达 + config.add_section('QX_config') + config.set('QX_config', 'regular', '\+?-?\d+(?:\.\d+)?') + config.set('QX_config', 'headStr', 'A+') + config.set('QX_config', 'rowTitle', 'time,Methane,Air Temp,Laser Temp,Laser Intensity') + + config.add_section('TF_config') + config.set('TF_config', 'regular', '\+?-?\d+(?:\.\d+)?') + config.set('TF_config', 'headStr', 'A+') + config.set('TF_config', 'rowTitle', 'time,Methane,Air Temp,Laser Temp,Laser Intensity,amplification,NL,ND,Sinal,SNR,PEAK,Best Piont') + + config.add_section('OtherData_config') + config.set('OtherData_config', 'regular', '\+?-?\d+(?:\.\d+)?') + # config.set('TF_config', 'regular', '(A\+|B\+|\s)+') + config.set('OtherData_config', 'headStr', 'A+') + config.set('OtherData_config', 'rowTitle', 'time,DATA1,DATA2') + + #按键配置 + config.add_section('Quick_config') + config.set('Quick_config', 'log_time', '10') + for i in range(self.quick_num): + idx = f'{i:02}' + button_name = f'Button{idx}' # 格式化按钮名称,确保两位数 + config.set('Quick_config', button_name, '') + with open(self.IniPath, 'w' ,encoding='utf-8') as f: + config.write(f) + + config = ConfigParser() + config.read(self.IniPath, encoding='utf-8') + try: + + # 创建一个空字典来存储按钮名称和对应的配置 + self.log_time = int(config.get('Quick_config', 'log_time')) + self.qxCfg = (config.get('QX_config','regular'),config.get('QX_config','headStr'),config.get('QX_config','rowTitle')) + print('Quick_config:',self.qxCfg) + self.tfCfg = (config.get('TF_config','regular'),config.get('TF_config','headStr'),config.get('TF_config','rowTitle')) + print('TF_config:',self.tfCfg) + self.otCfg = (config.get('OtherData_config','regular'),config.get('OtherData_config','headStr'),config.get('OtherData_config','rowTitle')) + print('OtherData_config:',self.otCfg) + + # 循环遍历按钮编号,从0到19 + for i in range(self.quick_num): + idx = f'{i:02}' + button_name = f'Button{idx}' # 格式化按钮名称,确保两位数 + # 使用 get 方法安全地获取配置,如果不存在则返回空字符串 + config_value = config.get('Quick_config', button_name, fallback='') + config_value_split = config_value.split('|') + # 将按钮名称和配置信息存储在字典中 + if len(config_value_split) == 2: + # 打印字典查看结果,并赋值 + print(button_name,config_value_split[0],config_value_split[1]) + getattr(self, f'pushButtonQuick_{idx}').setText(config_value_split[1]) + getattr(self, f'lineEditQuick_{idx}').setText(config_value_split[0]) + + except Exception as e: + print(f"Error reading configuration: {e}") + + + def SetCfgIniData(self,button_name,set_text): + config = ConfigParser() + config.read(self.IniPath, encoding='utf-8') + config.set('Quick_config', button_name, set_text) + with open(self.IniPath, 'w' ,encoding='utf-8') as f: + config.write(f) + + + def onButtonClick(self, idx): + # 槽函数处理按钮点击事件 + + if idx not in self.double_click_timers: + self.double_click_timers[idx] = None + + if self.double_click_timers[idx] is None: + self.double_click_timers[idx] = True + QTimer.singleShot(200, lambda: self.onButtonSigleClick(idx)) + else: + self.onButtonDoubleClick(idx) + + def onButtonSigleClick(self, idx): + index_str = f"{idx:02}" + if self.double_click_timers[idx]: + self.double_click_timers[idx] = None + lineEdit = getattr(self, f"lineEditQuick_{index_str}") + print(f"Text in lineEdit_{idx}: {lineEdit.text()}") + text = lineEdit.text() + if self.checkBox_return.isChecked(): + text = text + "\r\n" + self.data_send(text) + + def onButtonDoubleClick(self, idx): + # 槽函数处理按钮双击事件 + self.double_click_timers[idx] = None + index_str = f"{idx:02}" + print(f"Double click detected on Button {index_str}.") + button = getattr(self, f"pushButtonQuick_{index_str}") + new_name, ok = QInputDialog.getText(self, 'Button Rename', 'Enter new button name:') + if ok and new_name: + button.setText(new_name) + + + def bigdata_show(self): + if self.flag_bigdata == 0: + self.chart_dialog.show() + self.flag_bigdata = 1 + self.checkBoxAutoSaveLog.setChecked(False) + else: + self.chart_dialog.close() + self.flag_bigdata = 0 + self.checkBoxAutoSaveLog.setChecked(True) +#执行 +if __name__ == '__main__': + app = QtWidgets.QApplication(sys.argv) + myshow = PyQt5Serial() + myshow.show() + sys.exit(app.exec_()) \ No newline at end of file diff --git a/PyUartAssistantBigData/PyUartUi.py b/PyUartAssistantBigData/PyUartUi.py new file mode 100644 index 0000000..08b4805 --- /dev/null +++ b/PyUartAssistantBigData/PyUartUi.py @@ -0,0 +1,547 @@ +# -*- coding: utf-8 -*- + +# Form implementation generated from reading ui file 'PyUartUi.ui' +# +# Created by: PyQt5 UI code generator 5.15.10 +# +# WARNING: Any manual changes made to this file will be lost when pyuic5 is +# run again. Do not edit this file unless you know what you are doing. + + +from PyQt5 import QtCore, QtGui, QtWidgets + + +class Ui_UartAssistant(object): + def setupUi(self, UartAssistant): + UartAssistant.setObjectName("UartAssistant") + UartAssistant.resize(999, 694) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding) + sizePolicy.setHorizontalStretch(2) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(UartAssistant.sizePolicy().hasHeightForWidth()) + UartAssistant.setSizePolicy(sizePolicy) + UartAssistant.setAcceptDrops(True) + icon = QtGui.QIcon() + icon.addPixmap(QtGui.QPixmap("favicon.ico"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + UartAssistant.setWindowIcon(icon) + self.horizontalLayout_15 = QtWidgets.QHBoxLayout(UartAssistant) + self.horizontalLayout_15.setObjectName("horizontalLayout_15") + self.widget_7 = QtWidgets.QWidget(UartAssistant) + self.widget_7.setObjectName("widget_7") + self.horizontalLayout_14 = QtWidgets.QHBoxLayout(self.widget_7) + self.horizontalLayout_14.setObjectName("horizontalLayout_14") + self.splitter = QtWidgets.QSplitter(self.widget_7) + self.splitter.setMaximumSize(QtCore.QSize(16777215, 16777215)) + self.splitter.setOrientation(QtCore.Qt.Horizontal) + self.splitter.setHandleWidth(5) + self.splitter.setObjectName("splitter") + self.widget_4 = QtWidgets.QWidget(self.splitter) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred) + sizePolicy.setHorizontalStretch(1) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.widget_4.sizePolicy().hasHeightForWidth()) + self.widget_4.setSizePolicy(sizePolicy) + self.widget_4.setObjectName("widget_4") + self.horizontalLayout = QtWidgets.QHBoxLayout(self.widget_4) + self.horizontalLayout.setContentsMargins(0, 0, 0, 0) + self.horizontalLayout.setSpacing(0) + self.horizontalLayout.setObjectName("horizontalLayout") + self.widget = QtWidgets.QWidget(self.widget_4) + self.widget.setObjectName("widget") + self.verticalLayout_5 = QtWidgets.QVBoxLayout(self.widget) + self.verticalLayout_5.setObjectName("verticalLayout_5") + self.groupBox = QtWidgets.QGroupBox(self.widget) + self.groupBox.setMinimumSize(QtCore.QSize(220, 291)) + self.groupBox.setBaseSize(QtCore.QSize(271, 291)) + self.groupBox.setObjectName("groupBox") + self.pushButtonTestSerial = QtWidgets.QPushButton(self.groupBox) + self.pushButtonTestSerial.setGeometry(QtCore.QRect(10, 210, 93, 28)) + self.pushButtonTestSerial.setObjectName("pushButtonTestSerial") + self.pushButtonOpenSerial = QtWidgets.QPushButton(self.groupBox) + self.pushButtonOpenSerial.setGeometry(QtCore.QRect(120, 210, 93, 28)) + self.pushButtonOpenSerial.setStyleSheet("background-color: rgb(0, 255, 0);") + self.pushButtonOpenSerial.setObjectName("pushButtonOpenSerial") + self.pushButtonCloseSerial = QtWidgets.QPushButton(self.groupBox) + self.pushButtonCloseSerial.setGeometry(QtCore.QRect(10, 240, 201, 28)) + self.pushButtonCloseSerial.setObjectName("pushButtonCloseSerial") + self.layoutWidget_3 = QtWidgets.QWidget(self.groupBox) + self.layoutWidget_3.setGeometry(QtCore.QRect(10, 30, 74, 171)) + self.layoutWidget_3.setObjectName("layoutWidget_3") + self.verticalLayout = QtWidgets.QVBoxLayout(self.layoutWidget_3) + self.verticalLayout.setContentsMargins(0, 0, 0, 0) + self.verticalLayout.setObjectName("verticalLayout") + self.label = QtWidgets.QLabel(self.layoutWidget_3) + self.label.setObjectName("label") + self.verticalLayout.addWidget(self.label) + self.label_2 = QtWidgets.QLabel(self.layoutWidget_3) + self.label_2.setObjectName("label_2") + self.verticalLayout.addWidget(self.label_2) + self.label_3 = QtWidgets.QLabel(self.layoutWidget_3) + self.label_3.setObjectName("label_3") + self.verticalLayout.addWidget(self.label_3) + self.label_4 = QtWidgets.QLabel(self.layoutWidget_3) + self.label_4.setObjectName("label_4") + self.verticalLayout.addWidget(self.label_4) + self.label_5 = QtWidgets.QLabel(self.layoutWidget_3) + self.label_5.setObjectName("label_5") + self.verticalLayout.addWidget(self.label_5) + self.label_6 = QtWidgets.QLabel(self.layoutWidget_3) + self.label_6.setObjectName("label_6") + self.verticalLayout.addWidget(self.label_6) + self.layoutWidget_4 = QtWidgets.QWidget(self.groupBox) + self.layoutWidget_4.setGeometry(QtCore.QRect(80, 30, 128, 171)) + self.layoutWidget_4.setObjectName("layoutWidget_4") + self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.layoutWidget_4) + self.verticalLayout_2.setContentsMargins(0, 0, 0, 0) + self.verticalLayout_2.setObjectName("verticalLayout_2") + self.comboBoxSerial = QtWidgets.QComboBox(self.layoutWidget_4) + self.comboBoxSerial.setObjectName("comboBoxSerial") + self.verticalLayout_2.addWidget(self.comboBoxSerial) + self.comboBoxBaudrate = QtWidgets.QComboBox(self.layoutWidget_4) + self.comboBoxBaudrate.setToolTipDuration(0) + self.comboBoxBaudrate.setEditable(True) + self.comboBoxBaudrate.setObjectName("comboBoxBaudrate") + self.comboBoxBaudrate.addItem("") + self.comboBoxBaudrate.addItem("") + self.comboBoxBaudrate.addItem("") + self.comboBoxBaudrate.addItem("") + self.comboBoxBaudrate.addItem("") + self.comboBoxBaudrate.addItem("") + self.comboBoxBaudrate.addItem("") + self.comboBoxBaudrate.addItem("") + self.comboBoxBaudrate.addItem("") + self.comboBoxBaudrate.addItem("") + self.comboBoxBaudrate.addItem("") + self.verticalLayout_2.addWidget(self.comboBoxBaudrate) + self.comboBoxDataBits = QtWidgets.QComboBox(self.layoutWidget_4) + self.comboBoxDataBits.setEditable(True) + self.comboBoxDataBits.setObjectName("comboBoxDataBits") + self.comboBoxDataBits.addItem("") + self.comboBoxDataBits.addItem("") + self.comboBoxDataBits.addItem("") + self.comboBoxDataBits.addItem("") + self.verticalLayout_2.addWidget(self.comboBoxDataBits) + self.comboBoxCheckBit = QtWidgets.QComboBox(self.layoutWidget_4) + self.comboBoxCheckBit.setEditable(True) + self.comboBoxCheckBit.setObjectName("comboBoxCheckBit") + self.comboBoxCheckBit.addItem("") + self.comboBoxCheckBit.addItem("") + self.comboBoxCheckBit.addItem("") + self.verticalLayout_2.addWidget(self.comboBoxCheckBit) + self.comboBoxStopBit = QtWidgets.QComboBox(self.layoutWidget_4) + self.comboBoxStopBit.setEditable(True) + self.comboBoxStopBit.setObjectName("comboBoxStopBit") + self.comboBoxStopBit.addItem("") + self.comboBoxStopBit.addItem("") + self.verticalLayout_2.addWidget(self.comboBoxStopBit) + self.comboBoxFlow = QtWidgets.QComboBox(self.layoutWidget_4) + self.comboBoxFlow.setEditable(True) + self.comboBoxFlow.setObjectName("comboBoxFlow") + self.comboBoxFlow.addItem("") + self.comboBoxFlow.addItem("") + self.verticalLayout_2.addWidget(self.comboBoxFlow) + self.verticalLayout_5.addWidget(self.groupBox) + self.groupBox_2 = QtWidgets.QGroupBox(self.widget) + self.groupBox_2.setMinimumSize(QtCore.QSize(220, 165)) + self.groupBox_2.setBaseSize(QtCore.QSize(271, 165)) + self.groupBox_2.setObjectName("groupBox_2") + self.layoutWidget_5 = QtWidgets.QWidget(self.groupBox_2) + self.layoutWidget_5.setGeometry(QtCore.QRect(10, 20, 197, 79)) + self.layoutWidget_5.setObjectName("layoutWidget_5") + self.verticalLayout_6 = QtWidgets.QVBoxLayout(self.layoutWidget_5) + self.verticalLayout_6.setContentsMargins(0, 0, 0, 0) + self.verticalLayout_6.setObjectName("verticalLayout_6") + self.horizontalLayout_10 = QtWidgets.QHBoxLayout() + self.horizontalLayout_10.setObjectName("horizontalLayout_10") + self.checkBoxHexSend = QtWidgets.QCheckBox(self.layoutWidget_5) + self.checkBoxHexSend.setObjectName("checkBoxHexSend") + self.horizontalLayout_10.addWidget(self.checkBoxHexSend) + self.checkBoxHexReceive = QtWidgets.QCheckBox(self.layoutWidget_5) + self.checkBoxHexReceive.setObjectName("checkBoxHexReceive") + self.horizontalLayout_10.addWidget(self.checkBoxHexReceive) + self.verticalLayout_6.addLayout(self.horizontalLayout_10) + self.horizontalLayout_11 = QtWidgets.QHBoxLayout() + self.horizontalLayout_11.setObjectName("horizontalLayout_11") + self.checkBoxDTR = QtWidgets.QCheckBox(self.layoutWidget_5) + self.checkBoxDTR.setObjectName("checkBoxDTR") + self.horizontalLayout_11.addWidget(self.checkBoxDTR) + self.checkBoxRTS = QtWidgets.QCheckBox(self.layoutWidget_5) + self.checkBoxRTS.setObjectName("checkBoxRTS") + self.horizontalLayout_11.addWidget(self.checkBoxRTS) + self.verticalLayout_6.addLayout(self.horizontalLayout_11) + self.horizontalLayout_12 = QtWidgets.QHBoxLayout() + self.horizontalLayout_12.setObjectName("horizontalLayout_12") + self.checkBoxAddDate = QtWidgets.QCheckBox(self.layoutWidget_5) + self.checkBoxAddDate.setObjectName("checkBoxAddDate") + self.horizontalLayout_12.addWidget(self.checkBoxAddDate) + self.checkBoxCRLF = QtWidgets.QCheckBox(self.layoutWidget_5) + self.checkBoxCRLF.setObjectName("checkBoxCRLF") + self.horizontalLayout_12.addWidget(self.checkBoxCRLF) + self.verticalLayout_6.addLayout(self.horizontalLayout_12) + self.layoutWidget_6 = QtWidgets.QWidget(self.groupBox_2) + self.layoutWidget_6.setGeometry(QtCore.QRect(10, 130, 195, 30)) + self.layoutWidget_6.setObjectName("layoutWidget_6") + self.horizontalLayout_13 = QtWidgets.QHBoxLayout(self.layoutWidget_6) + self.horizontalLayout_13.setContentsMargins(0, 0, 0, 0) + self.horizontalLayout_13.setObjectName("horizontalLayout_13") + self.pushButtonLogSave = QtWidgets.QPushButton(self.layoutWidget_6) + self.pushButtonLogSave.setObjectName("pushButtonLogSave") + self.horizontalLayout_13.addWidget(self.pushButtonLogSave) + self.pushButtonLogLoad = QtWidgets.QPushButton(self.layoutWidget_6) + self.pushButtonLogLoad.setObjectName("pushButtonLogLoad") + self.horizontalLayout_13.addWidget(self.pushButtonLogLoad) + self.checkBoxAutoSaveLog = QtWidgets.QCheckBox(self.groupBox_2) + self.checkBoxAutoSaveLog.setGeometry(QtCore.QRect(12, 103, 90, 16)) + self.checkBoxAutoSaveLog.setChecked(True) + self.checkBoxAutoSaveLog.setObjectName("checkBoxAutoSaveLog") + self.verticalLayout_5.addWidget(self.groupBox_2) + self.groupBox_3 = QtWidgets.QGroupBox(self.widget) + self.groupBox_3.setMinimumSize(QtCore.QSize(220, 80)) + self.groupBox_3.setBaseSize(QtCore.QSize(271, 80)) + self.groupBox_3.setObjectName("groupBox_3") + self.checkBoxReapitSend = QtWidgets.QCheckBox(self.groupBox_3) + self.checkBoxReapitSend.setGeometry(QtCore.QRect(10, 30, 91, 19)) + self.checkBoxReapitSend.setObjectName("checkBoxReapitSend") + self.label_7 = QtWidgets.QLabel(self.groupBox_3) + self.label_7.setGeometry(QtCore.QRect(170, 30, 51, 16)) + self.label_7.setObjectName("label_7") + self.lineEditTime = QtWidgets.QLineEdit(self.groupBox_3) + self.lineEditTime.setGeometry(QtCore.QRect(110, 30, 51, 21)) + self.lineEditTime.setObjectName("lineEditTime") + self.verticalLayout_5.addWidget(self.groupBox_3) + spacerItem = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) + self.verticalLayout_5.addItem(spacerItem) + self.groupBox_6 = QtWidgets.QGroupBox(self.widget) + self.groupBox_6.setMinimumSize(QtCore.QSize(220, 80)) + self.groupBox_6.setBaseSize(QtCore.QSize(281, 80)) + self.groupBox_6.setTitle("") + self.groupBox_6.setObjectName("groupBox_6") + self.label_9 = QtWidgets.QLabel(self.groupBox_6) + self.label_9.setGeometry(QtCore.QRect(120, 20, 72, 15)) + self.label_9.setObjectName("label_9") + self.lineEditSendNum = QtWidgets.QLineEdit(self.groupBox_6) + self.lineEditSendNum.setGeometry(QtCore.QRect(40, 20, 61, 21)) + self.lineEditSendNum.setObjectName("lineEditSendNum") + self.lineEditReceiveNum = QtWidgets.QLineEdit(self.groupBox_6) + self.lineEditReceiveNum.setGeometry(QtCore.QRect(140, 20, 61, 21)) + self.lineEditReceiveNum.setObjectName("lineEditReceiveNum") + self.label_10 = QtWidgets.QLabel(self.groupBox_6) + self.label_10.setGeometry(QtCore.QRect(20, 40, 131, 16)) + self.label_10.setObjectName("label_10") + self.label_SendNum = QtWidgets.QLabel(self.groupBox_6) + self.label_SendNum.setGeometry(QtCore.QRect(20, 20, 72, 15)) + self.label_SendNum.setObjectName("label_SendNum") + self.verticalLayout_5.addWidget(self.groupBox_6) + self.horizontalLayout.addWidget(self.widget) + self.widget_5 = QtWidgets.QWidget(self.splitter) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred) + sizePolicy.setHorizontalStretch(1) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.widget_5.sizePolicy().hasHeightForWidth()) + self.widget_5.setSizePolicy(sizePolicy) + self.widget_5.setObjectName("widget_5") + self.horizontalLayout_9 = QtWidgets.QHBoxLayout(self.widget_5) + self.horizontalLayout_9.setContentsMargins(0, 0, 0, 0) + self.horizontalLayout_9.setSpacing(0) + self.horizontalLayout_9.setObjectName("horizontalLayout_9") + self.tabWidget = QtWidgets.QTabWidget(self.widget_5) + self.tabWidget.setMouseTracking(False) + self.tabWidget.setObjectName("tabWidget") + self.tab = QtWidgets.QWidget() + self.tab.setObjectName("tab") + self.verticalLayout_3 = QtWidgets.QVBoxLayout(self.tab) + self.verticalLayout_3.setObjectName("verticalLayout_3") + self.groupBox_4 = QtWidgets.QGroupBox(self.tab) + self.groupBox_4.setObjectName("groupBox_4") + self.horizontalLayout_2 = QtWidgets.QHBoxLayout(self.groupBox_4) + self.horizontalLayout_2.setObjectName("horizontalLayout_2") + self.textEditReceive = QtWidgets.QPlainTextEdit(self.groupBox_4) + self.textEditReceive.setSizeIncrement(QtCore.QSize(1, 1)) + self.textEditReceive.setObjectName("textEditReceive") + self.horizontalLayout_2.addWidget(self.textEditReceive) + self.verticalLayout_3.addWidget(self.groupBox_4) + self.groupBox_5 = QtWidgets.QGroupBox(self.tab) + self.groupBox_5.setObjectName("groupBox_5") + self.gridLayout = QtWidgets.QGridLayout(self.groupBox_5) + self.gridLayout.setObjectName("gridLayout") + self.pushButtonClearReceive = QtWidgets.QPushButton(self.groupBox_5) + self.pushButtonClearReceive.setObjectName("pushButtonClearReceive") + self.gridLayout.addWidget(self.pushButtonClearReceive, 1, 1, 1, 1) + self.pushButtonSend = QtWidgets.QPushButton(self.groupBox_5) + font = QtGui.QFont() + font.setFamily("3ds") + font.setPointSize(12) + self.pushButtonSend.setFont(font) + self.pushButtonSend.setAutoFillBackground(False) + self.pushButtonSend.setStyleSheet("background-color: rgb(0, 255, 0);") + self.pushButtonSend.setCheckable(False) + self.pushButtonSend.setFlat(False) + self.pushButtonSend.setObjectName("pushButtonSend") + self.gridLayout.addWidget(self.pushButtonSend, 3, 1, 1, 1) + self.pushButtonClearSend = QtWidgets.QPushButton(self.groupBox_5) + self.pushButtonClearSend.setObjectName("pushButtonClearSend") + self.gridLayout.addWidget(self.pushButtonClearSend, 2, 1, 1, 1) + self.pushButton_expend = QtWidgets.QPushButton(self.groupBox_5) + self.pushButton_expend.setObjectName("pushButton_expend") + self.gridLayout.addWidget(self.pushButton_expend, 0, 1, 1, 1) + self.textEditSend = QtWidgets.QTextEdit(self.groupBox_5) + self.textEditSend.setObjectName("textEditSend") + self.gridLayout.addWidget(self.textEditSend, 0, 0, 4, 1) + self.verticalLayout_3.addWidget(self.groupBox_5) + self.verticalLayout_3.setStretch(0, 6) + self.verticalLayout_3.setStretch(1, 2) + self.tabWidget.addTab(self.tab, "") + self.tab_2 = QtWidgets.QWidget() + self.tab_2.setObjectName("tab_2") + self.verticalLayout_7 = QtWidgets.QVBoxLayout(self.tab_2) + self.verticalLayout_7.setObjectName("verticalLayout_7") + self.verticalLayout_4 = QtWidgets.QVBoxLayout() + self.verticalLayout_4.setObjectName("verticalLayout_4") + self.widget_2 = QtWidgets.QWidget(self.tab_2) + self.widget_2.setObjectName("widget_2") + self.layoutWidget = QtWidgets.QWidget(self.widget_2) + self.layoutWidget.setGeometry(QtCore.QRect(9, 9, 429, 25)) + self.layoutWidget.setObjectName("layoutWidget") + self.horizontalLayout_6 = QtWidgets.QHBoxLayout(self.layoutWidget) + self.horizontalLayout_6.setContentsMargins(0, 0, 0, 0) + self.horizontalLayout_6.setObjectName("horizontalLayout_6") + self.pushButtonStartPlot = QtWidgets.QPushButton(self.layoutWidget) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.pushButtonStartPlot.sizePolicy().hasHeightForWidth()) + self.pushButtonStartPlot.setSizePolicy(sizePolicy) + self.pushButtonStartPlot.setObjectName("pushButtonStartPlot") + self.horizontalLayout_6.addWidget(self.pushButtonStartPlot) + spacerItem1 = QtWidgets.QSpacerItem(20, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) + self.horizontalLayout_6.addItem(spacerItem1) + self.radioButtonCH4QX = QtWidgets.QRadioButton(self.layoutWidget) + self.radioButtonCH4QX.setEnabled(True) + self.radioButtonCH4QX.setMouseTracking(True) + self.radioButtonCH4QX.setContextMenuPolicy(QtCore.Qt.ActionsContextMenu) + self.radioButtonCH4QX.setAcceptDrops(True) + self.radioButtonCH4QX.setToolTipDuration(1) + self.radioButtonCH4QX.setStatusTip("") + self.radioButtonCH4QX.setAutoFillBackground(False) + self.radioButtonCH4QX.setChecked(False) + self.radioButtonCH4QX.setObjectName("radioButtonCH4QX") + self.horizontalLayout_6.addWidget(self.radioButtonCH4QX) + self.radioButtonCH4TF = QtWidgets.QRadioButton(self.layoutWidget) + self.radioButtonCH4TF.setChecked(True) + self.radioButtonCH4TF.setObjectName("radioButtonCH4TF") + self.horizontalLayout_6.addWidget(self.radioButtonCH4TF) + self.radioButtonOtherData = QtWidgets.QRadioButton(self.layoutWidget) + self.radioButtonOtherData.setChecked(False) + self.radioButtonOtherData.setObjectName("radioButtonOtherData") + self.horizontalLayout_6.addWidget(self.radioButtonOtherData) + self.checkBoxAutoSaveCsv = QtWidgets.QCheckBox(self.layoutWidget) + self.checkBoxAutoSaveCsv.setChecked(True) + self.checkBoxAutoSaveCsv.setObjectName("checkBoxAutoSaveCsv") + self.horizontalLayout_6.addWidget(self.checkBoxAutoSaveCsv) + self.layoutWidget1 = QtWidgets.QWidget(self.widget_2) + self.layoutWidget1.setGeometry(QtCore.QRect(9, 40, 261, 25)) + self.layoutWidget1.setObjectName("layoutWidget1") + self.horizontalLayout_8 = QtWidgets.QHBoxLayout(self.layoutWidget1) + self.horizontalLayout_8.setContentsMargins(0, 0, 0, 0) + self.horizontalLayout_8.setObjectName("horizontalLayout_8") + self.pushButtonStopPlot = QtWidgets.QPushButton(self.layoutWidget1) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.pushButtonStopPlot.sizePolicy().hasHeightForWidth()) + self.pushButtonStopPlot.setSizePolicy(sizePolicy) + self.pushButtonStopPlot.setObjectName("pushButtonStopPlot") + self.horizontalLayout_8.addWidget(self.pushButtonStopPlot) + spacerItem2 = QtWidgets.QSpacerItem(20, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) + self.horizontalLayout_8.addItem(spacerItem2) + self.comboBoxPlot = QtWidgets.QComboBox(self.layoutWidget1) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred) + sizePolicy.setHorizontalStretch(100) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.comboBoxPlot.sizePolicy().hasHeightForWidth()) + self.comboBoxPlot.setSizePolicy(sizePolicy) + self.comboBoxPlot.setObjectName("comboBoxPlot") + self.horizontalLayout_8.addWidget(self.comboBoxPlot) + self.pushButton_bigdata = QtWidgets.QPushButton(self.widget_2) + self.pushButton_bigdata.setGeometry(QtCore.QRect(340, 40, 75, 20)) + self.pushButton_bigdata.setObjectName("pushButton_bigdata") + self.verticalLayout_4.addWidget(self.widget_2) + self.plot_view = QChartView(self.tab_2) + self.plot_view.setEnabled(True) + self.plot_view.setAcceptDrops(False) + self.plot_view.setToolTipDuration(-1) + self.plot_view.setObjectName("plot_view") + self.verticalLayout_4.addWidget(self.plot_view) + self.widget_3 = QtWidgets.QWidget(self.tab_2) + self.widget_3.setObjectName("widget_3") + self.horizontalLayout_4 = QtWidgets.QHBoxLayout(self.widget_3) + self.horizontalLayout_4.setObjectName("horizontalLayout_4") + self.pushButtonResetPlot = QtWidgets.QPushButton(self.widget_3) + self.pushButtonResetPlot.setObjectName("pushButtonResetPlot") + self.horizontalLayout_4.addWidget(self.pushButtonResetPlot) + spacerItem3 = QtWidgets.QSpacerItem(80, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) + self.horizontalLayout_4.addItem(spacerItem3) + self.horizontalLayout_5 = QtWidgets.QHBoxLayout() + self.horizontalLayout_5.setObjectName("horizontalLayout_5") + self.label_SendNum_2 = QtWidgets.QLabel(self.widget_3) + self.label_SendNum_2.setObjectName("label_SendNum_2") + self.horizontalLayout_5.addWidget(self.label_SendNum_2) + self.lineEditCurrentValue = QtWidgets.QLineEdit(self.widget_3) + self.lineEditCurrentValue.setObjectName("lineEditCurrentValue") + self.horizontalLayout_5.addWidget(self.lineEditCurrentValue) + self.horizontalLayout_4.addLayout(self.horizontalLayout_5) + self.horizontalLayout_3 = QtWidgets.QHBoxLayout() + self.horizontalLayout_3.setObjectName("horizontalLayout_3") + self.label_SendNum_3 = QtWidgets.QLabel(self.widget_3) + self.label_SendNum_3.setObjectName("label_SendNum_3") + self.horizontalLayout_3.addWidget(self.label_SendNum_3) + self.lineEditWindowMean = QtWidgets.QLineEdit(self.widget_3) + self.lineEditWindowMean.setObjectName("lineEditWindowMean") + self.horizontalLayout_3.addWidget(self.lineEditWindowMean) + self.horizontalLayout_4.addLayout(self.horizontalLayout_3) + self.horizontalLayout_7 = QtWidgets.QHBoxLayout() + self.horizontalLayout_7.setObjectName("horizontalLayout_7") + self.label_SendNum_4 = QtWidgets.QLabel(self.widget_3) + self.label_SendNum_4.setObjectName("label_SendNum_4") + self.horizontalLayout_7.addWidget(self.label_SendNum_4) + self.lineEditWindowMSE = QtWidgets.QLineEdit(self.widget_3) + self.lineEditWindowMSE.setObjectName("lineEditWindowMSE") + self.horizontalLayout_7.addWidget(self.lineEditWindowMSE) + self.horizontalLayout_4.addLayout(self.horizontalLayout_7) + self.verticalLayout_4.addWidget(self.widget_3) + self.verticalLayout_4.setStretch(0, 12) + self.verticalLayout_4.setStretch(1, 80) + self.verticalLayout_4.setStretch(2, 8) + self.verticalLayout_7.addLayout(self.verticalLayout_4) + self.tabWidget.addTab(self.tab_2, "") + self.horizontalLayout_9.addWidget(self.tabWidget) + self.widget_6 = QtWidgets.QWidget(self.splitter) + self.widget_6.setEnabled(True) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred) + sizePolicy.setHorizontalStretch(2) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.widget_6.sizePolicy().hasHeightForWidth()) + self.widget_6.setSizePolicy(sizePolicy) + self.widget_6.setMinimumSize(QtCore.QSize(260, 0)) + self.widget_6.setObjectName("widget_6") + self.horizontalLayout_16 = QtWidgets.QHBoxLayout(self.widget_6) + self.horizontalLayout_16.setContentsMargins(0, 0, 0, 0) + self.horizontalLayout_16.setSpacing(0) + self.horizontalLayout_16.setObjectName("horizontalLayout_16") + self.scrollArea = QtWidgets.QScrollArea(self.widget_6) + self.scrollArea.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOn) + self.scrollArea.setWidgetResizable(False) + self.scrollArea.setObjectName("scrollArea") + self.scrollAreaWidgetContents = QtWidgets.QWidget() + self.scrollAreaWidgetContents.setGeometry(QtCore.QRect(0, 0, 241, 3000)) + self.scrollAreaWidgetContents.setObjectName("scrollAreaWidgetContents") + self.widget_8 = QtWidgets.QWidget(self.scrollAreaWidgetContents) + self.widget_8.setGeometry(QtCore.QRect(12, 2, 221, 34)) + self.widget_8.setObjectName("widget_8") + self.horizontalLayout_17 = QtWidgets.QHBoxLayout(self.widget_8) + self.horizontalLayout_17.setContentsMargins(0, 0, 0, 0) + self.horizontalLayout_17.setObjectName("horizontalLayout_17") + self.label_8 = QtWidgets.QLabel(self.widget_8) + self.label_8.setObjectName("label_8") + self.horizontalLayout_17.addWidget(self.label_8) + self.checkBox_return = QtWidgets.QCheckBox(self.widget_8) + self.checkBox_return.setChecked(True) + self.checkBox_return.setObjectName("checkBox_return") + self.horizontalLayout_17.addWidget(self.checkBox_return) + self.widget_9 = QtWidgets.QWidget(self.scrollAreaWidgetContents) + self.widget_9.setGeometry(QtCore.QRect(12, 42, 231, 3000)) + self.widget_9.setObjectName("widget_9") + self.layoutWidget2 = QtWidgets.QWidget(self.widget_9) + self.layoutWidget2.setGeometry(QtCore.QRect(12, 12, 201, 2801)) + self.layoutWidget2.setObjectName("layoutWidget2") + self.verticalLayout_8 = QtWidgets.QVBoxLayout(self.layoutWidget2) + self.verticalLayout_8.setContentsMargins(0, 0, 0, 0) + self.verticalLayout_8.setObjectName("verticalLayout_8") + self.scrollArea.setWidget(self.scrollAreaWidgetContents) + self.horizontalLayout_16.addWidget(self.scrollArea) + self.horizontalLayout_14.addWidget(self.splitter) + self.horizontalLayout_15.addWidget(self.widget_7) + + self.retranslateUi(UartAssistant) + self.comboBoxBaudrate.setCurrentIndex(0) + self.comboBoxDataBits.setCurrentIndex(3) + self.comboBoxCheckBit.setCurrentIndex(0) + self.tabWidget.setCurrentIndex(0) + QtCore.QMetaObject.connectSlotsByName(UartAssistant) + + def retranslateUi(self, UartAssistant): + _translate = QtCore.QCoreApplication.translate + UartAssistant.setWindowTitle(_translate("UartAssistant", "串口助手py版")) + self.groupBox.setTitle(_translate("UartAssistant", "串口设置")) + self.pushButtonTestSerial.setText(_translate("UartAssistant", "检测串口")) + self.pushButtonOpenSerial.setText(_translate("UartAssistant", "打开串口")) + self.pushButtonCloseSerial.setText(_translate("UartAssistant", "关闭串口")) + self.label.setText(_translate("UartAssistant", "串口号")) + self.label_2.setText(_translate("UartAssistant", "波特率")) + self.label_3.setText(_translate("UartAssistant", "数据位")) + self.label_4.setText(_translate("UartAssistant", "校验位")) + self.label_5.setText(_translate("UartAssistant", "停止位")) + self.label_6.setText(_translate("UartAssistant", "流控方式")) + self.comboBoxBaudrate.setCurrentText(_translate("UartAssistant", "4800")) + self.comboBoxBaudrate.setItemText(0, _translate("UartAssistant", "4800")) + self.comboBoxBaudrate.setItemText(1, _translate("UartAssistant", "9600")) + self.comboBoxBaudrate.setItemText(2, _translate("UartAssistant", "14400")) + self.comboBoxBaudrate.setItemText(3, _translate("UartAssistant", "19200")) + self.comboBoxBaudrate.setItemText(4, _translate("UartAssistant", "115200")) + self.comboBoxBaudrate.setItemText(5, _translate("UartAssistant", "921600")) + self.comboBoxBaudrate.setItemText(6, _translate("UartAssistant", "1500000")) + self.comboBoxBaudrate.setItemText(7, _translate("UartAssistant", "新建项目")) + self.comboBoxBaudrate.setItemText(8, _translate("UartAssistant", "新建项目")) + self.comboBoxBaudrate.setItemText(9, _translate("UartAssistant", "新建项目")) + self.comboBoxBaudrate.setItemText(10, _translate("UartAssistant", "自定义")) + self.comboBoxDataBits.setCurrentText(_translate("UartAssistant", "8")) + self.comboBoxDataBits.setItemText(0, _translate("UartAssistant", "5")) + self.comboBoxDataBits.setItemText(1, _translate("UartAssistant", "6")) + self.comboBoxDataBits.setItemText(2, _translate("UartAssistant", "7")) + self.comboBoxDataBits.setItemText(3, _translate("UartAssistant", "8")) + self.comboBoxCheckBit.setItemText(0, _translate("UartAssistant", "None")) + self.comboBoxCheckBit.setItemText(1, _translate("UartAssistant", "Odd")) + self.comboBoxCheckBit.setItemText(2, _translate("UartAssistant", "Even")) + self.comboBoxStopBit.setItemText(0, _translate("UartAssistant", "1")) + self.comboBoxStopBit.setItemText(1, _translate("UartAssistant", "2")) + self.comboBoxFlow.setItemText(0, _translate("UartAssistant", "No Ctrl Flow")) + self.comboBoxFlow.setItemText(1, _translate("UartAssistant", "SW Ctrl Flow")) + self.groupBox_2.setTitle(_translate("UartAssistant", "收发设置")) + self.checkBoxHexSend.setText(_translate("UartAssistant", "HEX发送")) + self.checkBoxHexReceive.setText(_translate("UartAssistant", "HEX接收")) + self.checkBoxDTR.setText(_translate("UartAssistant", "DTR")) + self.checkBoxRTS.setText(_translate("UartAssistant", "RTS")) + self.checkBoxAddDate.setText(_translate("UartAssistant", "收/发时间")) + self.checkBoxCRLF.setText(_translate("UartAssistant", "收发换行")) + self.pushButtonLogSave.setText(_translate("UartAssistant", "保存日志")) + self.pushButtonLogLoad.setText(_translate("UartAssistant", "加载日志")) + self.checkBoxAutoSaveLog.setText(_translate("UartAssistant", "自动保存日志")) + self.groupBox_3.setTitle(_translate("UartAssistant", "定时发送")) + self.checkBoxReapitSend.setText(_translate("UartAssistant", "定时发送")) + self.label_7.setText(_translate("UartAssistant", "ms/次")) + self.lineEditTime.setText(_translate("UartAssistant", "1000")) + self.label_9.setText(_translate("UartAssistant", "Rx")) + self.label_10.setText(_translate("UartAssistant", "Powerd by Byan")) + self.label_SendNum.setText(_translate("UartAssistant", "Tx")) + self.groupBox_4.setTitle(_translate("UartAssistant", "数据接收区")) + self.groupBox_5.setTitle(_translate("UartAssistant", "数据发送区")) + self.pushButtonClearReceive.setText(_translate("UartAssistant", "清除接收")) + self.pushButtonSend.setText(_translate("UartAssistant", "发送")) + self.pushButtonClearSend.setText(_translate("UartAssistant", "清除发送")) + self.pushButton_expend.setText(_translate("UartAssistant", "快捷指令")) + self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab), _translate("UartAssistant", "串口数据")) + self.pushButtonStartPlot.setText(_translate("UartAssistant", "开始绘图")) + self.radioButtonCH4QX.setText(_translate("UartAssistant", "CH4QX")) + self.radioButtonCH4TF.setText(_translate("UartAssistant", "CH4TF")) + self.radioButtonOtherData.setText(_translate("UartAssistant", "其他数据")) + self.checkBoxAutoSaveCsv.setText(_translate("UartAssistant", "自动保存Csv(慢)")) + self.pushButtonStopPlot.setText(_translate("UartAssistant", "停止绘图")) + self.pushButton_bigdata.setText(_translate("UartAssistant", "大数据模式")) + self.pushButtonResetPlot.setText(_translate("UartAssistant", "重置图形")) + self.label_SendNum_2.setText(_translate("UartAssistant", "当前数值")) + self.label_SendNum_3.setText(_translate("UartAssistant", "窗口均值")) + self.label_SendNum_4.setText(_translate("UartAssistant", "窗口标准差")) + self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_2), _translate("UartAssistant", "曲线绘制")) + self.label_8.setText(_translate("UartAssistant", "快捷指令")) + self.checkBox_return.setText(_translate("UartAssistant", "添加\"\\r\\n\"")) +from PyQt5.QtChart import QChartView diff --git a/PyUartAssistantBigData/PyUartUi.ui b/PyUartAssistantBigData/PyUartUi.ui new file mode 100644 index 0000000..da77ce9 --- /dev/null +++ b/PyUartAssistantBigData/PyUartUi.ui @@ -0,0 +1,1139 @@ + + + UartAssistant + + + + 0 + 0 + 999 + 694 + + + + + 2 + 0 + + + + true + + + 串口助手py版 + + + + favicon.icofavicon.ico + + + + + + + + + + 16777215 + 16777215 + + + + Qt::Horizontal + + + 5 + + + + + 1 + 0 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + + 220 + 291 + + + + + 271 + 291 + + + + 串口设置 + + + + + 10 + 210 + 93 + 28 + + + + 检测串口 + + + + + + 120 + 210 + 93 + 28 + + + + background-color: rgb(0, 255, 0); + + + 打开串口 + + + + + + 10 + 240 + 201 + 28 + + + + 关闭串口 + + + + + + 10 + 30 + 74 + 171 + + + + + + + 串口号 + + + + + + + 波特率 + + + + + + + 数据位 + + + + + + + 校验位 + + + + + + + 停止位 + + + + + + + 流控方式 + + + + + + + + + 80 + 30 + 128 + 171 + + + + + + + + + + 0 + + + true + + + 4800 + + + 0 + + + + 4800 + + + + + 9600 + + + + + 14400 + + + + + 19200 + + + + + 115200 + + + + + 921600 + + + + + 1500000 + + + + + 新建项目 + + + + + 新建项目 + + + + + 新建项目 + + + + + 自定义 + + + + + + + + true + + + 8 + + + 3 + + + + 5 + + + + + 6 + + + + + 7 + + + + + 8 + + + + + + + + true + + + 0 + + + + None + + + + + Odd + + + + + Even + + + + + + + + true + + + + 1 + + + + + 2 + + + + + + + + true + + + + No Ctrl Flow + + + + + SW Ctrl Flow + + + + + + + + + + + + + 220 + 165 + + + + + 271 + 165 + + + + 收发设置 + + + + + 10 + 20 + 197 + 79 + + + + + + + + + HEX发送 + + + + + + + HEX接收 + + + + + + + + + + + DTR + + + + + + + RTS + + + + + + + + + + + 收/发时间 + + + + + + + 收发换行 + + + + + + + + + + + 10 + 130 + 195 + 30 + + + + + + + 保存日志 + + + + + + + 加载日志 + + + + + + + + + 12 + 103 + 90 + 16 + + + + 自动保存日志 + + + true + + + + + + + + + 220 + 80 + + + + + 271 + 80 + + + + 定时发送 + + + + + 10 + 30 + 91 + 19 + + + + 定时发送 + + + + + + 170 + 30 + 51 + 16 + + + + ms/次 + + + + + + 110 + 30 + 51 + 21 + + + + 1000 + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + 220 + 80 + + + + + 281 + 80 + + + + + + + + + 120 + 20 + 72 + 15 + + + + Rx + + + + + + 40 + 20 + 61 + 21 + + + + + + + 140 + 20 + 61 + 21 + + + + + + + 20 + 40 + 131 + 16 + + + + Powerd by Byan + + + + + + 20 + 20 + 72 + 15 + + + + Tx + + + + + + + + + + + + + 1 + 0 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + false + + + 0 + + + + 串口数据 + + + + + + 数据接收区 + + + + + + + 1 + 1 + + + + + + + + + + + 数据发送区 + + + + + + 清除接收 + + + + + + + + 3ds + 12 + + + + false + + + background-color: rgb(0, 255, 0); + + + 发送 + + + false + + + false + + + + + + + 清除发送 + + + + + + + 快捷指令 + + + + + + + + + + + + + + 曲线绘制 + + + + + + + + + + 9 + 9 + 429 + 25 + + + + + + + + 0 + 0 + + + + 开始绘图 + + + + + + + Qt::Horizontal + + + + 20 + 20 + + + + + + + + true + + + true + + + Qt::ActionsContextMenu + + + true + + + 1 + + + + + + false + + + CH4QX + + + false + + + + + + + CH4TF + + + true + + + + + + + 其他数据 + + + false + + + + + + + 自动保存Csv(慢) + + + true + + + + + + + + + 9 + 40 + 261 + 25 + + + + + + + + 0 + 0 + + + + 停止绘图 + + + + + + + Qt::Horizontal + + + + 20 + 20 + + + + + + + + + 100 + 0 + + + + + + + + + + 340 + 40 + 75 + 20 + + + + 大数据模式 + + + + + + + + true + + + false + + + -1 + + + + + + + + + + 重置图形 + + + + + + + Qt::Horizontal + + + + 80 + 20 + + + + + + + + + + 当前数值 + + + + + + + + + + + + + + 窗口均值 + + + + + + + + + + + + + + 窗口标准差 + + + + + + + + + + + + + + + + + + + + + + true + + + + 2 + 0 + + + + + 260 + 0 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Qt::ScrollBarAlwaysOn + + + false + + + + + 0 + 0 + 241 + 3000 + + + + + + 12 + 2 + 221 + 34 + + + + + + + 快捷指令 + + + + + + + 添加"\r\n" + + + true + + + + + + + + + 12 + 42 + 231 + 3000 + + + + + + 12 + 12 + 201 + 2801 + + + + + + + + + + + + + + + + + + + + QChartView + QGraphicsView +
PyQt5.QtChart
+
+
+ + +
diff --git a/PyUartAssistantBigData/PyUart标准.exe b/PyUartAssistantBigData/PyUart标准.exe new file mode 100644 index 0000000..5e57def Binary files /dev/null and b/PyUartAssistantBigData/PyUart标准.exe differ diff --git a/PyUartAssistantBigData/UartDataPolt.py b/PyUartAssistantBigData/UartDataPolt.py new file mode 100644 index 0000000..f390dba --- /dev/null +++ b/PyUartAssistantBigData/UartDataPolt.py @@ -0,0 +1,227 @@ +# -*- coding: utf-8 -*- +""" +Created on Tue May 28 15:40:48 2024 + +@author: WANGXIBAO +""" +# -*- coding: utf-8 -*- + + + +import csv +import math +import os +import re +import time + +from PyQt5.QtChart import QChart, QValueAxis, QLineSeries +from PyQt5.QtCore import QThread, pyqtSignal, Qt +from PyQt5.QtGui import QPen +from PyQt5.QtWidgets import QMessageBox + + +# 波形显示 +class QChartViewPlot(QChart): + + # 相位振动波形 + def __init__(self, parent=None): + super(QChartViewPlot, self).__init__(parent) + self.window = parent + self.xRange = 60 + self.counter = 0 + self.seriesList = [] + self.legend().show() + + self.axisX = QValueAxis() + self.axisX.setRange(0, self.xRange) + self.addAxis(self.axisX, Qt.AlignBottom) + # self.setAxisX(self.axisX, series) + # 增加X轴网格设置 + self.axisX.setTickCount(13) + grid_pen_x = QPen(Qt.black, 0.5, Qt.DotLine) # 设置网格线的颜色、宽度和样式 + self.axisX.setGridLinePen(grid_pen_x) + + self.y_min = 0 + self.y_max = 100 + self.axisY = QValueAxis() + self.axisY.setRange(self.y_min, self.y_max) + self.addAxis(self.axisY, Qt.AlignLeft) + # self.setAxisY(self.axisY, series) + # 增加Y轴网格设置 + self.axisY.setTickCount(11) + grid_pen_y = QPen(Qt.black, 0.5, Qt.DotLine) # 设置网格线的颜色、宽度和样式 + self.axisY.setGridLinePen(grid_pen_y) + + #self.series = QSplineSeries() + self.series = QLineSeries() + self.series.setName("波形") + self.series.setUseOpenGL(True) + self.addSeries(self.series) + + + self.series.attachAxis(self.axisX) + self.series.attachAxis(self.axisY) + + self.curretValue = 0 + self.windowAverage =0 + self.windowStd = 0 + + def handle_update(self, ydata): + # 更新y值 + if self.counter < self.xRange: + self.series.append(self.counter, ydata) + self.counter += 1 + points = self.series.pointsVector() + self.y_min = min(points, key=lambda point: point.y()).y() + self.y_max = max(points, key=lambda point: point.y()).y() + + + + else: + points = self.series.pointsVector() + for i in range(self.xRange - 1): + points[i].setY(points[i + 1].y()) + points[-1].setY(ydata) + self.y_min = min(points, key=lambda point: point.y()).y() + self.y_max = max(points, key=lambda point: point.y()).y() + self.series.replace(points) + + # 计算总和 + total_sum = sum(point.y() for point in points) + # 计算点的数量 + num_points = len(points) + # 计算均值,确保除数不为零 + self.windowAverage = total_sum / num_points if num_points > 0 else 0 + print("windowMean:",self.windowAverage) + + # 计算每个点与均值的差的平方,然后求和 + variance_sum = sum((point.y() - self.windowAverage) ** 2 for point in points) + # 计算方差,除以数据点的总数 + variance = variance_sum / len(points) + self.axisY.setRange(math.floor(self.y_min-0.1),math.ceil( self.y_max+0.1)) + # 计算标准差,即方差的平方根 + self.windowStd = variance ** 0.5 + print("standard_deviation", self.windowStd) + + def clearSeries(self): + self.series.clear() + self.counter = 0 +# 使用线程不断更新波形数据 + +class UpdateDataThread(QThread): + _signal_update = pyqtSignal(float) # 信号 + + def __init__(self, parent=None): + super(UpdateDataThread, self).__init__(parent) + self.is_exit = False + self.x_range = 1024 + self.flag = 0 + + + + def run(self): + print("run start") + while not self.is_exit: # 直接在循环中检查退出标志 + # for i in range(self.x_range): + # print(i,self.sin.get_data(i)) + + # self._signal_update.emit(str(self.sin.get_data(i))) # 发射信号 + # time.sleep(0.01) # 实际应用中推荐使用QTimer代替 + + # 这里应该有一个 flag 默认是 0 外部调用可以传紧来1,没循环完自己置零,while 只起到监控左右 + + if self.flag == 1: + #print("flag",self.flag) + + #data = self.setReceiveData + #print("发数",datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f")) + print("data receive ",self.setReceiveData) + # print(f"{data:.3f}") + try: + + self._signal_update.emit(self.setReceiveData) + self.flag = 0 + + + except Exception: + QMessageBox.critical(self, '数据异常', '数据格式不对,不能绘图') + pass + + + + + def SetReceiveData(self,data_in): + self.setReceiveData = data_in + + def SetFlag(self,flag): + self.flag = flag + + def SetFilenameCsv(self,filename): + self.filenameCsv = filename + + def SetPlotItem(self,ind): #设置显示项目 + self.ind = ind + + def stop(self): + self.is_exit = True # 设置退出标志 + print("停止绘图") + def restart(self): + self.is_exit = False + + + + + +class GetDataTF(): #读取费加罗或者自定义数据 + def __init__(self, parent=None): + super().__init__() + self.indOfReturn =0 + self.TIME_FORMAT = "%Y-%m-%d %H:%M:%S" + self.headStr = "" + self.rowTitle=[] + self.csv_buffer = [] + + def SetConfig(self,config_in): + self.regex= re.compile(config_in[0]) #正则表达 + self.headStr = config_in[1] + self.rowTitleStr = config_in[2] + #print(self.rowTitleStr) + self.rowTitle = self.rowTitleStr.split(',') + + + def Transdata(self,data): + if data[:2] ==self.headStr: + + self.data2csv = self.regex.findall(data) + + returnData = float(self.data2csv[self.indOfReturn]) + print("returnData",returnData) + return returnData + else: + return "noNum" + + def SaveCsv(self,filenameCsv,num): + # 打开一个文件用于写入,如果文件不存在则创建 + # 增加num 写入文件间隔 + if os.path.isfile(filenameCsv) == 0: + # 文件为空,需要写入表头 + with open(filenameCsv, mode='w', newline='') as file: + writer = csv.writer(file) + writer.writerow(self.rowTitle) + else: + timeCrvt=time.strftime(self.TIME_FORMAT, time.localtime()) + self.data2csv.insert(0, timeCrvt) + print(self.data2csv) + self.csv_buffer.append(self.data2csv) + if len(self.csv_buffer)>= num: + with open(filenameCsv, mode='a', newline='') as file: + # 创建一个写入器对象 + writer = csv.writer(file) + # 写入数据行 + writer.writerows(self.csv_buffer) + self.csv_buffer.clear() + + def IndOfReturn(self,ind): + self.indOfReturn = ind + + diff --git a/PyUartAssistantBigData/dym_plot_qchart.py b/PyUartAssistantBigData/dym_plot_qchart.py new file mode 100644 index 0000000..b5e2403 --- /dev/null +++ b/PyUartAssistantBigData/dym_plot_qchart.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +""" +Created on Tue May 28 14:36:16 2024 + +@author: WANGXIBAO +""" + +# -*- coding: utf-8 -*- + +# Form implementation generated from reading ui file 'dym_plot_qchart.ui' +# +# Created by: PyQt5 UI code generator 5.15.4 +# +# WARNING: Any manual changes made to this file will be lost when pyuic5 is +# run again. Do not edit this file unless you know what you are doing. + + +from PyQt5 import QtCore, QtGui, QtWidgets + + +class Ui_MainWindow(object): + def setupUi(self, MainWindow): + MainWindow.setObjectName("MainWindow") + MainWindow.resize(800, 600) + self.centralwidget = QtWidgets.QWidget(MainWindow) + self.centralwidget.setObjectName("centralwidget") + self.btn_start = QtWidgets.QPushButton(self.centralwidget) + self.btn_start.setGeometry(QtCore.QRect(40, 50, 93, 28)) + self.btn_start.setObjectName("btn_start") + self.plot_view = QChartView(self.centralwidget) + self.plot_view.setGeometry(QtCore.QRect(20, 130, 751, 281)) + self.plot_view.setObjectName("plot_view") + MainWindow.setCentralWidget(self.centralwidget) + self.menubar = QtWidgets.QMenuBar(MainWindow) + self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 26)) + self.menubar.setObjectName("menubar") + MainWindow.setMenuBar(self.menubar) + self.statusbar = QtWidgets.QStatusBar(MainWindow) + self.statusbar.setObjectName("statusbar") + MainWindow.setStatusBar(self.statusbar) + + self.retranslateUi(MainWindow) + QtCore.QMetaObject.connectSlotsByName(MainWindow) + + def retranslateUi(self, MainWindow): + _translate = QtCore.QCoreApplication.translate + MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow")) + self.btn_start.setText(_translate("MainWindow", "开始")) +from PyQt5.QtChart import QChartView + + + + diff --git a/PyUartAssistantBigData/dym_plot_qchart_main.py b/PyUartAssistantBigData/dym_plot_qchart_main.py new file mode 100644 index 0000000..72c9e4a --- /dev/null +++ b/PyUartAssistantBigData/dym_plot_qchart_main.py @@ -0,0 +1,167 @@ +# -*- coding: utf-8 -*- +""" +Created on Tue May 28 15:37:25 2024 + +@author: WANGXIBAO +""" + +# !/usr/bin/python +# -*- coding: utf-8 -*- + +""" +@contact: 微信 1257309054 +@file: main_das.py +@time: 2022/3/25 14:27 +@author: LDC +""" +import json +import time + +import numpy as np +import sys + +from PyQt5.Qt import * +from dym_plot_qchart import Ui_MainWindow +from PyQt5.QtChart import QChart, QValueAxis, QChartView, QSplineSeries + + +class Window(QMainWindow, Ui_MainWindow): + def __init__(self, app): + super(QMainWindow, self).__init__() + self.app = app + self.setup_ui() # 渲染画布 + self.update_data_thread = UpdateDataThread() # 创建更新波形数据线程 + self.connect_signals() # 绑定触发事件 + + def setup_ui(self): + self.setupUi(self) # 调用Ui_MainWindow的setupUi渲染界面 + + # 加载Qchart波形界面 + self.plot_qchart = QChartViewPlot() + self.plot_view.setChart(self.plot_qchart) + self.plot_view.setRenderHint(QPainter.Antialiasing) # 抗锯齿 + self.plot_view.setRubberBand(QChartView.RectangleRubberBand) + + def connect_signals(self): + # 绑定触发事件 + self.btn_start.clicked.connect(self.btn_start_clicked) + + self.update_data_thread._signal_update.connect(self.update_data_thread_slot) + + def btn_start_clicked(self): + # 开启按钮 + self.update_data_thread.start() + + def update_data_thread_slot(self, data): + # 线程回调函数 + data = json.loads(data) + self.plot_qchart.handle_update(data['sin_data']) + + def wheelEvent(self, event): + # 鼠标滚轮:缩放Qchart波形 + if event.angleDelta().y() >= 0: + # 鼠标滚轮向上 + if event.x() < ( + self.plot_view.width() + self.plot_view.x()) and event.x() > self.plot_view.x(): + if event.y() < ( + self.plot_view.height() + self.plot_view.y()) and event.y() > self.plot_view.y(): + self.plot_qchart.zoomIn() + else: + # 鼠标滚轮向下 + if event.x() < ( + self.plot_view.width() + self.plot_view.x()) and event.x() > self.plot_view.x(): + if event.y() < ( + self.plot_view.height() + self.plot_view.y()) and event.y() > self.plot_view.y(): + self.plot_qchart.zoomOut() + + +# 波形显示 +class QChartViewPlot(QChart): + # 相位振动波形 + def __init__(self, parent=None): + super(QChartViewPlot, self).__init__(parent) + self.window = parent + self.xRange = 1024 + self.counter = 0 + self.seriesList = [] + self.legend().show() + + self.axisX = QValueAxis() + self.axisX.setRange(0, self.xRange) + self.addAxis(self.axisX, Qt.AlignBottom) + # self.setAxisX(self.axisX, series) + self.y_min = 0 + self.y_max = 100 + self.axisY = QValueAxis() + self.axisY.setRange(self.y_min, self.y_max) + self.addAxis(self.axisY, Qt.AlignLeft) + # self.setAxisY(self.axisY, series) + + self.series = QSplineSeries() + self.series.setName("波形") + self.series.setUseOpenGL(True) + self.addSeries(self.series) + self.series.attachAxis(self.axisX) + self.series.attachAxis(self.axisY) + + def handle_update(self, ydata): + # 更新y值 + if self.counter < self.xRange: + self.series.append(self.counter, ydata) + self.counter += 1 + else: + points = self.series.pointsVector() + for i in range(self.xRange - 1): + points[i].setY(points[i + 1].y()) + points[-1].setY(ydata) + self.y_min = min(points, key=lambda point: point.y()).y() + self.y_max = max(points, key=lambda point: point.y()).y() + self.series.replace(points) + self.axisY.setRange(self.y_min - 20, self.y_max + 20) + + +# 使用线程不断更新波形数据 +class UpdateDataThread(QThread): + _signal_update = pyqtSignal(str) # 信号 + + def __init__(self, parent=None): + super(UpdateDataThread, self).__init__(parent) + self.qmut = QMutex() + self.is_exit = False + self.x_range = 1024 + self.sin = Sin() + + def run(self): + while True: + self.qmut.lock() + if self.is_exit: + break + self.qmut.unlock() + for i in range(self.x_range): + self._signal_update.emit(json.dumps({'sin_data': self.sin.get_data(i)})) # 发送信号给槽函数 + time.sleep(0.01) + + self.qmut.unlock() + + +class Sin(): + # 创建一个正弦波数据 + def __init__(self, pha=0): + self.pha = pha # 初始相位 + + def get_data(self, index): + self.pha += 10 + if self.pha > 1000: + self.pha = 0 + return 1000 * np.sin(8 * np.pi * index + self.pha * np.pi / 180.0) + + +def main(): + app = QApplication(sys.argv) + mywindow = Window(app) + mywindow.show() + sys.exit(app.exec_()) + + +if __name__ == "__main__": + main() diff --git a/PyUartAssistantBigData/favicon.ico b/PyUartAssistantBigData/favicon.ico new file mode 100644 index 0000000..500f64e Binary files /dev/null and b/PyUartAssistantBigData/favicon.ico differ diff --git a/PyUartAssistantBigData/ppp.py b/PyUartAssistantBigData/ppp.py new file mode 100644 index 0000000..5da06c0 --- /dev/null +++ b/PyUartAssistantBigData/ppp.py @@ -0,0 +1,236 @@ +# -*- coding: utf-8 -*- + +# Form implementation generated from reading ui file '.\PyUartUi.ui' +# +# Created by: PyQt5 UI code generator 5.15.10 +# +# WARNING: Any manual changes made to this file will be lost when pyuic5 is +# run again. Do not edit this file unless you know what you are doing. + + +from PyQt5 import QtCore, QtGui, QtWidgets + + +class Ui_UartAssistant(object): + def setupUi(self, UartAssistant): + UartAssistant.setObjectName("UartAssistant") + UartAssistant.resize(1121, 714) + self.groupBox = QtWidgets.QGroupBox(UartAssistant) + self.groupBox.setGeometry(QtCore.QRect(30, 20, 241, 281)) + self.groupBox.setObjectName("groupBox") + self.pushButton = QtWidgets.QPushButton(self.groupBox) + self.pushButton.setGeometry(QtCore.QRect(10, 210, 93, 28)) + self.pushButton.setObjectName("pushButton") + self.pushButton_2 = QtWidgets.QPushButton(self.groupBox) + self.pushButton_2.setGeometry(QtCore.QRect(120, 210, 93, 28)) + self.pushButton_2.setStyleSheet("background-color: rgb(0, 255, 0);") + self.pushButton_2.setObjectName("pushButton_2") + self.pushButton_3 = QtWidgets.QPushButton(self.groupBox) + self.pushButton_3.setGeometry(QtCore.QRect(10, 240, 201, 28)) + self.pushButton_3.setObjectName("pushButton_3") + self.widget = QtWidgets.QWidget(self.groupBox) + self.widget.setGeometry(QtCore.QRect(10, 30, 74, 171)) + self.widget.setObjectName("widget") + self.verticalLayout = QtWidgets.QVBoxLayout(self.widget) + self.verticalLayout.setContentsMargins(0, 0, 0, 0) + self.verticalLayout.setObjectName("verticalLayout") + self.label = QtWidgets.QLabel(self.widget) + self.label.setObjectName("label") + self.verticalLayout.addWidget(self.label) + self.label_2 = QtWidgets.QLabel(self.widget) + self.label_2.setObjectName("label_2") + self.verticalLayout.addWidget(self.label_2) + self.label_3 = QtWidgets.QLabel(self.widget) + self.label_3.setObjectName("label_3") + self.verticalLayout.addWidget(self.label_3) + self.label_4 = QtWidgets.QLabel(self.widget) + self.label_4.setObjectName("label_4") + self.verticalLayout.addWidget(self.label_4) + self.label_5 = QtWidgets.QLabel(self.widget) + self.label_5.setObjectName("label_5") + self.verticalLayout.addWidget(self.label_5) + self.label_6 = QtWidgets.QLabel(self.widget) + self.label_6.setObjectName("label_6") + self.verticalLayout.addWidget(self.label_6) + self.widget1 = QtWidgets.QWidget(self.groupBox) + self.widget1.setGeometry(QtCore.QRect(120, 30, 91, 171)) + self.widget1.setObjectName("widget1") + self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.widget1) + self.verticalLayout_2.setContentsMargins(0, 0, 0, 0) + self.verticalLayout_2.setObjectName("verticalLayout_2") + self.comboBox_2 = QtWidgets.QComboBox(self.widget1) + self.comboBox_2.setObjectName("comboBox_2") + self.verticalLayout_2.addWidget(self.comboBox_2) + self.comboBox = QtWidgets.QComboBox(self.widget1) + self.comboBox.setToolTipDuration(0) + self.comboBox.setObjectName("comboBox") + self.comboBox.addItem("") + self.comboBox.addItem("") + self.comboBox.addItem("") + self.comboBox.addItem("") + self.comboBox.addItem("") + self.comboBox.addItem("") + self.verticalLayout_2.addWidget(self.comboBox) + self.comboBox_3 = QtWidgets.QComboBox(self.widget1) + self.comboBox_3.setObjectName("comboBox_3") + self.verticalLayout_2.addWidget(self.comboBox_3) + self.comboBox_4 = QtWidgets.QComboBox(self.widget1) + self.comboBox_4.setObjectName("comboBox_4") + self.verticalLayout_2.addWidget(self.comboBox_4) + self.comboBox_5 = QtWidgets.QComboBox(self.widget1) + self.comboBox_5.setObjectName("comboBox_5") + self.verticalLayout_2.addWidget(self.comboBox_5) + self.comboBox_6 = QtWidgets.QComboBox(self.widget1) + self.comboBox_6.setObjectName("comboBox_6") + self.verticalLayout_2.addWidget(self.comboBox_6) + self.groupBox_2 = QtWidgets.QGroupBox(UartAssistant) + self.groupBox_2.setGeometry(QtCore.QRect(30, 310, 241, 171)) + self.groupBox_2.setObjectName("groupBox_2") + self.widget2 = QtWidgets.QWidget(self.groupBox_2) + self.widget2.setGeometry(QtCore.QRect(10, 40, 197, 79)) + self.widget2.setObjectName("widget2") + self.verticalLayout_3 = QtWidgets.QVBoxLayout(self.widget2) + self.verticalLayout_3.setContentsMargins(0, 0, 0, 0) + self.verticalLayout_3.setObjectName("verticalLayout_3") + self.horizontalLayout = QtWidgets.QHBoxLayout() + self.horizontalLayout.setObjectName("horizontalLayout") + self.checkBox = QtWidgets.QCheckBox(self.widget2) + self.checkBox.setObjectName("checkBox") + self.horizontalLayout.addWidget(self.checkBox) + self.checkBox_2 = QtWidgets.QCheckBox(self.widget2) + self.checkBox_2.setObjectName("checkBox_2") + self.horizontalLayout.addWidget(self.checkBox_2) + self.verticalLayout_3.addLayout(self.horizontalLayout) + self.horizontalLayout_2 = QtWidgets.QHBoxLayout() + self.horizontalLayout_2.setObjectName("horizontalLayout_2") + self.checkBox_3 = QtWidgets.QCheckBox(self.widget2) + self.checkBox_3.setObjectName("checkBox_3") + self.horizontalLayout_2.addWidget(self.checkBox_3) + self.checkBox_4 = QtWidgets.QCheckBox(self.widget2) + self.checkBox_4.setObjectName("checkBox_4") + self.horizontalLayout_2.addWidget(self.checkBox_4) + self.verticalLayout_3.addLayout(self.horizontalLayout_2) + self.horizontalLayout_3 = QtWidgets.QHBoxLayout() + self.horizontalLayout_3.setObjectName("horizontalLayout_3") + self.checkBox_6 = QtWidgets.QCheckBox(self.widget2) + self.checkBox_6.setObjectName("checkBox_6") + self.horizontalLayout_3.addWidget(self.checkBox_6) + self.checkBox_5 = QtWidgets.QCheckBox(self.widget2) + self.checkBox_5.setObjectName("checkBox_5") + self.horizontalLayout_3.addWidget(self.checkBox_5) + self.verticalLayout_3.addLayout(self.horizontalLayout_3) + self.widget3 = QtWidgets.QWidget(self.groupBox_2) + self.widget3.setGeometry(QtCore.QRect(10, 130, 195, 30)) + self.widget3.setObjectName("widget3") + self.horizontalLayout_4 = QtWidgets.QHBoxLayout(self.widget3) + self.horizontalLayout_4.setContentsMargins(0, 0, 0, 0) + self.horizontalLayout_4.setObjectName("horizontalLayout_4") + self.pushButton_4 = QtWidgets.QPushButton(self.widget3) + self.pushButton_4.setObjectName("pushButton_4") + self.horizontalLayout_4.addWidget(self.pushButton_4) + self.pushButton_5 = QtWidgets.QPushButton(self.widget3) + self.pushButton_5.setObjectName("pushButton_5") + self.horizontalLayout_4.addWidget(self.pushButton_5) + self.groupBox_3 = QtWidgets.QGroupBox(UartAssistant) + self.groupBox_3.setGeometry(QtCore.QRect(30, 480, 241, 71)) + self.groupBox_3.setObjectName("groupBox_3") + self.checkBox_7 = QtWidgets.QCheckBox(self.groupBox_3) + self.checkBox_7.setGeometry(QtCore.QRect(10, 30, 91, 19)) + self.checkBox_7.setObjectName("checkBox_7") + self.label_7 = QtWidgets.QLabel(self.groupBox_3) + self.label_7.setGeometry(QtCore.QRect(180, 30, 51, 16)) + self.label_7.setObjectName("label_7") + self.lineEdit = QtWidgets.QLineEdit(self.groupBox_3) + self.lineEdit.setGeometry(QtCore.QRect(110, 30, 51, 21)) + self.lineEdit.setObjectName("lineEdit") + self.groupBox_4 = QtWidgets.QGroupBox(UartAssistant) + self.groupBox_4.setGeometry(QtCore.QRect(290, 20, 771, 521)) + self.groupBox_4.setObjectName("groupBox_4") + self.textEditReceive = QtWidgets.QTextEdit(self.groupBox_4) + self.textEditReceive.setGeometry(QtCore.QRect(20, 30, 741, 471)) + self.textEditReceive.setObjectName("textEditReceive") + self.groupBox_5 = QtWidgets.QGroupBox(UartAssistant) + self.groupBox_5.setGeometry(QtCore.QRect(290, 550, 771, 151)) + self.groupBox_5.setObjectName("groupBox_5") + self.textEditSend = QtWidgets.QTextEdit(self.groupBox_5) + self.textEditSend.setGeometry(QtCore.QRect(20, 20, 621, 111)) + self.textEditSend.setObjectName("textEditSend") + self.pushButtonSend = QtWidgets.QPushButton(self.groupBox_5) + self.pushButtonSend.setGeometry(QtCore.QRect(660, 80, 93, 51)) + font = QtGui.QFont() + font.setFamily("3ds") + font.setPointSize(12) + self.pushButtonSend.setFont(font) + self.pushButtonSend.setAutoFillBackground(False) + self.pushButtonSend.setStyleSheet("background-color: rgb(0, 255, 0);") + self.pushButtonSend.setCheckable(False) + self.pushButtonSend.setFlat(False) + self.pushButtonSend.setObjectName("pushButtonSend") + self.lineEdit_2 = QtWidgets.QLineEdit(UartAssistant) + self.lineEdit_2.setGeometry(QtCore.QRect(50, 580, 61, 21)) + self.lineEdit_2.setObjectName("lineEdit_2") + self.label_8 = QtWidgets.QLabel(UartAssistant) + self.label_8.setGeometry(QtCore.QRect(30, 580, 72, 15)) + self.label_8.setObjectName("label_8") + self.label_9 = QtWidgets.QLabel(UartAssistant) + self.label_9.setGeometry(QtCore.QRect(130, 580, 72, 15)) + self.label_9.setObjectName("label_9") + self.lineEdit_3 = QtWidgets.QLineEdit(UartAssistant) + self.lineEdit_3.setGeometry(QtCore.QRect(150, 580, 61, 21)) + self.lineEdit_3.setObjectName("lineEdit_3") + self.label_10 = QtWidgets.QLabel(UartAssistant) + self.label_10.setGeometry(QtCore.QRect(40, 650, 131, 16)) + self.label_10.setObjectName("label_10") + + self.retranslateUi(UartAssistant) + QtCore.QMetaObject.connectSlotsByName(UartAssistant) + + def retranslateUi(self, UartAssistant): + _translate = QtCore.QCoreApplication.translate + UartAssistant.setWindowTitle(_translate("UartAssistant", "串口助手py版")) + self.groupBox.setTitle(_translate("UartAssistant", "串口设置")) + self.pushButton.setText(_translate("UartAssistant", "检测串口")) + self.pushButton_2.setText(_translate("UartAssistant", "打开串口")) + self.pushButton_3.setText(_translate("UartAssistant", "关闭串口")) + self.label.setText(_translate("UartAssistant", "串口号")) + self.label_2.setText(_translate("UartAssistant", "波特率")) + self.label_3.setText(_translate("UartAssistant", "数据位")) + self.label_4.setText(_translate("UartAssistant", "校验位")) + self.label_5.setText(_translate("UartAssistant", "停止位")) + self.label_6.setText(_translate("UartAssistant", "流控方式")) + self.comboBox.setCurrentText(_translate("UartAssistant", "9600")) + self.comboBox.setItemText(0, _translate("UartAssistant", "4800")) + self.comboBox.setItemText(1, _translate("UartAssistant", "9600")) + self.comboBox.setItemText(2, _translate("UartAssistant", "14400")) + self.comboBox.setItemText(3, _translate("UartAssistant", "19200")) + self.comboBox.setItemText(4, _translate("UartAssistant", "115200")) + self.comboBox.setItemText(5, _translate("UartAssistant", "自定义")) + self.groupBox_2.setTitle(_translate("UartAssistant", "收发设置")) + self.checkBox.setText(_translate("UartAssistant", "HEX发送")) + self.checkBox_2.setText(_translate("UartAssistant", "HEX接收")) + self.checkBox_3.setText(_translate("UartAssistant", "DTR")) + self.checkBox_4.setText(_translate("UartAssistant", "RTS")) + self.checkBox_6.setText(_translate("UartAssistant", "收/发时间")) + self.checkBox_5.setText(_translate("UartAssistant", "收发换行")) + self.pushButton_4.setText(_translate("UartAssistant", "保持日志")) + self.pushButton_5.setText(_translate("UartAssistant", "接收日志")) + self.groupBox_3.setTitle(_translate("UartAssistant", "定时发送")) + self.checkBox_7.setText(_translate("UartAssistant", "定时发送")) + self.label_7.setText(_translate("UartAssistant", "ms/次")) + self.lineEdit.setText(_translate("UartAssistant", "1000")) + self.groupBox_4.setTitle(_translate("UartAssistant", "数据接收区")) + self.groupBox_5.setTitle(_translate("UartAssistant", "数据发送区")) + self.pushButtonSend.setText(_translate("UartAssistant", "发送")) + self.label_8.setText(_translate("UartAssistant", "Tx")) + self.label_9.setText(_translate("UartAssistant", "Rx")) + self.label_10.setText(_translate("UartAssistant", "Powerd by Byan")) + + +if __name__ == "__main__": + import sys + app = QtWidgets.QApplication(sys.argv) + UartAssistant = QtWidgets.QWidget() + ui = Ui_UartAssistant() + ui.setupUi(UartAssistant) + UartAssistant.show() + sys.exit(app.exec_()) diff --git a/PyUartAssistantBigData/regular.ini b/PyUartAssistantBigData/regular.ini new file mode 100644 index 0000000..250e622 --- /dev/null +++ b/PyUartAssistantBigData/regular.ini @@ -0,0 +1,27 @@ +[TF_config] +regular = \+?-?\d+(?:\.\d+)? +headstr = A+ +rowtitle = time,Methane,Air Temp,Laser Temp,Laser Intensity,amplification,NL,ND,Sinal,SNR,PEAK,Best Piont + +[Quick_config] +button00 = write 0,2024100101|序列号 +button01 = write 1,66000|激光温度 +button02 = write 2,1000|K*1000 +button03 = write 3,0|B*1000 +button04 = write 4,0|可调电阻 +button05 = write 5,30|电阻抽头 +button06 = write 6,0|输出温度 +button07 = write 7,0|输出激光 +button08 = write 8,1|输出状态 +button09 = write 9,0|激光温补 +button10 = write 10,100|噪声长度 +button11 = write 11,600|扫描长度 +button12 = |空闲 +button13 = write 13,30500|气温校准 +button14 = write 14,1|滑动开关 +button15 = write 15,10|滑动标准差 +button16 = write 16,1|浓度温补 +button17 = read all|读取所有 +button18 = | +button19 = | + diff --git a/PyUartAssistantBigData/tansUi2Py.py b/PyUartAssistantBigData/tansUi2Py.py new file mode 100644 index 0000000..facebee --- /dev/null +++ b/PyUartAssistantBigData/tansUi2Py.py @@ -0,0 +1,38 @@ +# -*- coding: utf-8 -*- +""" +Created on Sun May 26 21:10:12 2024 + +@author: wxb51 +""" + +#使用Python脚本的方式将UI文件转换为Python文件 +import os +import os.path + +dir ='./' #文件所在的路径 + +#找出路径下所有的.ui文件 +def listUiFile(): + list = [] + files = os.listdir(dir) + for filename in files: + #print(filename) + if os.path.splitext(filename)[1] == '.ui': + list.append(filename) + + return list + +#把扩展名未.ui的转换成.py的文件 +def transPyFile(filename): + return os.path.splitext(filename)[0] + '.py' + +#通过命令把.ui文件转换成.py文件 +def runMain(): + list = listUiFile() + for uifile in list: + pyfile = transPyFile(uifile) + cmd = 'pyuic5 -o {pyfile} {uifile}'.format(pyfile=pyfile, uifile=uifile) + os.system(cmd) + +if __name__ =="__main__": + runMain() \ No newline at end of file diff --git a/PyUartAssistantBigData/test.py b/PyUartAssistantBigData/test.py new file mode 100644 index 0000000..f7e9dc0 --- /dev/null +++ b/PyUartAssistantBigData/test.py @@ -0,0 +1,17 @@ +# -*- coding: utf-8 -*- +""" +Created on Mon May 27 09:37:57 2024 + +@author: WANGXIBAO +""" +import sys +from PyQt5 import QtWidgets +from PyUartUi import Ui_UartAssistant +if __name__ == "__main__": + + app = QtWidgets.QApplication(sys.argv) + UartAssistant = QtWidgets.QWidget() + ui = Ui_UartAssistant() + ui.setupUi(UartAssistant) + UartAssistant.show() + sys.exit(app.exec_()) \ No newline at end of file diff --git a/PyUartAssistantBigData/testSerical.py b/PyUartAssistantBigData/testSerical.py new file mode 100644 index 0000000..6c496eb --- /dev/null +++ b/PyUartAssistantBigData/testSerical.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +""" +Created on Mon May 27 11:44:23 2024 + +@author: WANGXIBAO +""" + +import serial,datetime +import serial.tools.list_ports +import chardet + +# 获取所有串口设备实例。 +# 如果没找到串口设备,则输出:“无串口设备。” +# 如果找到串口设备,则依次输出每个设备对应的串口号和描述信息。 +ports_list = list(serial.tools.list_ports.comports()) +if len(ports_list) <= 0: + print("无串口设备。") +else: + print("可用的串口设备如下:") + for comport in ports_list: + #print(list(comport)[0], list(comport)[1]) + print(comport) +ser = serial.Serial() +ser.port = "COM1" +ser.baudrate = 115200 +ser.timeout = 0.005 + +try : + ser.open() + print("串口打开") + while True: + + buffer = ser.readline() + if buffer: + # result = chardet.detect(buffer) + # print(result['encoding']) # 输出检测到的编码 + data = buffer.decode('utf-8') + nowTime = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f") + nowTime = nowTime[:-3] + print(nowTime,data) + + + +except: + + print("串口打开失败") +finally: + ser.close() + print("串口关闭") + + + + diff --git a/PyUartAssistantBigData/testchart.py b/PyUartAssistantBigData/testchart.py new file mode 100644 index 0000000..a1f0e3f --- /dev/null +++ b/PyUartAssistantBigData/testchart.py @@ -0,0 +1,45 @@ +from PyQt5.QtWidgets import QFrame, QWidget, QVBoxLayout +from PyQt5.QtGui import QPainter +from PyQt5.QtChart import QChart, QChartView + + +class YourClassName(QWidget): + def __init__(self): + super().__init__() + + self.plot_qchart = QChart() + self.plot_view = QChartView() + + # 设置图表到视图 + self.plot_view.setChart(self.plot_qchart) + + # 开启抗锯齿 + self.plot_view.setRenderHint(QPainter.Antialiasing) + + # 设置矩形橡皮筋 + self.plot_view.setRubberBand(QChartView.RectangleRubberBand) + + # 移除外部边框 + self.plot_view.setFrameShape(QFrame.NoFrame) + + # 使用样式表进一步移除边框 + self.plot_view.setStyleSheet("border: none;") + + self.plot_qchart.setBackgroundRoundness(0) + self.plot_qchart.layout().setContentsMargins(0, 0, 0, 0) + + + # 将 QChartView 添加到布局中(如果需要) + layout = QVBoxLayout(self) + layout.addWidget(self.plot_view) + + +# 创建并显示窗口 +if __name__ == "__main__": + from PyQt5.QtWidgets import QApplication + + + app = QApplication([]) + window = YourClassName() + window.show() + app.exec_() \ No newline at end of file diff --git a/PyUartAssistantBigData/未命名0.py b/PyUartAssistantBigData/未命名0.py new file mode 100644 index 0000000..075290a --- /dev/null +++ b/PyUartAssistantBigData/未命名0.py @@ -0,0 +1,38 @@ +# -*- coding: utf-8 -*- +""" +Created on Thu Jul 11 10:17:34 2024 + +@author: WANGXIBAO +""" + +import re,os,csv + +data = "A+000.00 +31.5 0057.92 +00.442 B+010 NL00.195 ND00.000 S00.313 SNR 02.04 P168 B250 1A" +regex = re.compile(r'\+?-?\d+(?:\.\d+)?') # 编译正则表达式 +parts = re.split(regex,data) +parts2 = [part for part in parts if part] + + + +# 使用 findall 方法找到所有匹配的数字 +numbers = regex.findall(data) + +# 输出结果 +print(numbers) + +filenameCsv = "TTTTTTTTTTTTtest.csv" +if os.path.isfile(filenameCsv) == 0: +# 文件为空,需要写入表头 + + with open(filenameCsv, mode='w', newline='') as file: + writer = csv.writer(file) + steee = "'time', 'Methane', 'Air Temp', 'Laser Temp', 'Laser Intensity'" + stlist = steee.split(',') + writer.writerow(stlist) + #writer.writerow(self.rowTitle) +else: + with open(filenameCsv, mode='a', newline='') as file: + # 创建一个写入器对象 + writer = csv.writer(file) + # 写入数据行 + writer.writerows([numbers]) \ No newline at end of file diff --git a/PyUartAssistantBigData/未命名1.py b/PyUartAssistantBigData/未命名1.py new file mode 100644 index 0000000..dfeaa61 --- /dev/null +++ b/PyUartAssistantBigData/未命名1.py @@ -0,0 +1,10 @@ +# -*- coding: utf-8 -*- +""" +Created on Thu Jul 11 13:36:48 2024 + +@author: WANGXIBAO +""" + +my_list = ['1',' 2', '3',' 4',' 5'] +my_list.pop(0) # 移除第一个元素 +print(my_list) # 输出: [2, 3, 4, 5] diff --git a/PyUartAssistantBigData/未命名2.py b/PyUartAssistantBigData/未命名2.py new file mode 100644 index 0000000..a14839b --- /dev/null +++ b/PyUartAssistantBigData/未命名2.py @@ -0,0 +1,160 @@ +# -*- coding: utf-8 -*- +""" +Created on Tue May 28 15:40:48 2024 + +@author: WANGXIBAO +""" +# -*- coding: utf-8 -*- + + +import json +import time + +import numpy as np +import sys + +from PyQt5.Qt import * +from PyUartUi import Ui_UartAssistant +from PyQt5.QtChart import QChart, QValueAxis, QChartView, QSplineSeries + + +class Window(QMainWindow, Ui_UartAssistant): + def __init__(self, app): + super(QMainWindow, self).__init__() + self.app = app + self.setup_ui() # 渲染画布 + self.update_data_thread = UpdateDataThread() # 创建更新波形数据线程 + self.connect_signals() # 绑定触发事件 + + def setup_ui(self): + self.setupUi(self) # 调用Ui_MainWindow的setupUi渲染界面 + + # 加载Qchart波形界面 + self.plot_qchart = QChartViewPlot() + self.plot_view.setChart(self.plot_qchart) + self.plot_view.setRenderHint(QPainter.Antialiasing) # 抗锯齿 + self.plot_view.setRubberBand(QChartView.RectangleRubberBand) + + def connect_signals(self): + # 绑定触发事件 + #self.btn_start.clicked.connect(self.btn_start_clicked) + self.radioButtonCH4QX.clicked.connect(self.btn_start_clicked) + self.update_data_thread._signal_update.connect(self.update_data_thread_slot) + + def btn_start_clicked(self): + # 开启按钮 + self.update_data_thread.start() + + def update_data_thread_slot(self, data): + # 线程回调函数 + data = json.loads(data) + self.plot_qchart.handle_update(data['sin_data']) + + def wheelEvent(self, event): + # 鼠标滚轮:缩放Qchart波形 + if event.angleDelta().y() >= 0: + # 鼠标滚轮向上 + if event.x() < ( + self.plot_view.width() + self.plot_view.x()) and event.x() > self.plot_view.x(): + if event.y() < ( + self.plot_view.height() + self.plot_view.y()) and event.y() > self.plot_view.y(): + self.plot_qchart.zoomIn() + else: + # 鼠标滚轮向下 + if event.x() < ( + self.plot_view.width() + self.plot_view.x()) and event.x() > self.plot_view.x(): + if event.y() < ( + self.plot_view.height() + self.plot_view.y()) and event.y() > self.plot_view.y(): + self.plot_qchart.zoomOut() + + +# 波形显示 +class QChartViewPlot(QChart): + # 相位振动波形 + def __init__(self, parent=None): + super(QChartViewPlot, self).__init__(parent) + self.window = parent + self.xRange = 1024 + self.counter = 0 + self.seriesList = [] + self.legend().show() + + self.axisX = QValueAxis() + self.axisX.setRange(0, self.xRange) + self.addAxis(self.axisX, Qt.AlignBottom) + # self.setAxisX(self.axisX, series) + self.y_min = 0 + self.y_max = 100 + self.axisY = QValueAxis() + self.axisY.setRange(self.y_min, self.y_max) + self.addAxis(self.axisY, Qt.AlignLeft) + # self.setAxisY(self.axisY, series) + + self.series = QSplineSeries() + self.series.setName("波形") + self.series.setUseOpenGL(True) + self.addSeries(self.series) + self.series.attachAxis(self.axisX) + self.series.attachAxis(self.axisY) + + def handle_update(self, ydata): + # 更新y值 + if self.counter < self.xRange: + self.series.append(self.counter, ydata) + self.counter += 1 + else: + points = self.series.pointsVector() + for i in range(self.xRange - 1): + points[i].setY(points[i + 1].y()) + points[-1].setY(ydata) + self.y_min = min(points, key=lambda point: point.y()).y() + self.y_max = max(points, key=lambda point: point.y()).y() + self.series.replace(points) + self.axisY.setRange(self.y_min - 20, self.y_max + 20) + + +# 使用线程不断更新波形数据 +class UpdateDataThread(QThread): + _signal_update = pyqtSignal(str) # 信号 + + def __init__(self, parent=None): + super(UpdateDataThread, self).__init__(parent) + self.qmut = QMutex() + self.is_exit = False + self.x_range = 1024 + self.sin = Sin() + + def run(self): + while True: + self.qmut.lock() + if self.is_exit: + break + self.qmut.unlock() + for i in range(self.x_range): + self._signal_update.emit(json.dumps({'sin_data': self.sin.get_data(i)})) # 发送信号给槽函数 + time.sleep(0.01) + + self.qmut.unlock() + + +class Sin(): + # 创建一个正弦波数据 + def __init__(self, pha=0): + self.pha = pha # 初始相位 + + def get_data(self, index): + self.pha += 10 + if self.pha > 1000: + self.pha = 0 + return 1000 * np.sin(8 * np.pi * index + self.pha * np.pi / 180.0) + + +def main(): + app = QApplication(sys.argv) + mywindow = Window(app) + mywindow.show() + sys.exit(app.exec_()) + + +if __name__ == "__main__": + main()