怎加了非0数据单独记录功能

This commit is contained in:
wangxibao 2025-02-13 08:29:55 +08:00
parent 46e7114e95
commit 604b22695a
33 changed files with 3976 additions and 105 deletions

Binary file not shown.

View File

@ -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 =

View File

@ -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"

8
PyUartAssistantBigData/.idea/.gitignore generated vendored Normal file
View File

@ -0,0 +1,8 @@
# 默认忽略的文件
/shelf/
/workspace.xml
# Editor-based HTTP Client requests
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="PYTHON_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

View File

@ -0,0 +1,12 @@
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="PyPep8NamingInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true">
<option name="ignoredErrors">
<list>
<option value="N806" />
</list>
</option>
</inspection_tool>
</profile>
</component>

View File

@ -0,0 +1,6 @@
<component name="InspectionProjectProfileManager">
<settings>
<option name="USE_PROJECT_PROFILE" value="false" />
<version value="1.0" />
</settings>
</component>

7
PyUartAssistantBigData/.idea/misc.xml generated Normal file
View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Black">
<option name="sdkName" value="Python 3.11" />
</component>
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.11" project-jdk-type="Python SDK" />
</project>

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/PyUartAssistantBigData.iml" filepath="$PROJECT_DIR$/.idea/PyUartAssistantBigData.iml" />
</modules>
</component>
</project>

6
PyUartAssistantBigData/.idea/vcs.xml generated Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$/.." vcs="Git" />
</component>
</project>

View File

@ -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"
}
]
}

View File

@ -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()

View File

@ -0,0 +1,5 @@
[OtherData_config]
regular = \+?-?\d+(?:\.\d+)?
headstr = A+
rowtitle = time,DATA1,DATA2

Binary file not shown.

View File

@ -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 = |

View File

@ -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'(?<!\r)\n', b'\r\n', input_s)
# HEX接收显示
if self.checkBoxHexReceive.isChecked():
out_s = ''
for i in range(0, len(input_s)):
out_s = out_s + '{:02X}'.format(input_s[i]) + ' '
self.textEditReceive.insertPlainText(out_s)
# ASCII接收显示
else:
self.textEditReceive.insertPlainText(input_s.decode('utf-8',errors='replace'))
# 接收换行
if self.checkBoxCRLF.isChecked():
self.textEditReceive.insertPlainText('\r\n')
# 获取到Text光标
textCursor = self.textEditReceive.textCursor()
# 滚动到底部
textCursor.movePosition(textCursor.End)
# 设置光标到Text中去
self.textEditReceive.setTextCursor(textCursor)
# 统计发送字符数量
num = self.ser.write(input_s)
self.data_num_sended += num
self.lineEditSendNum.setText(str(self.data_num_sended))
else:
pass
# %%保存日志
def savefiles(self):
dlg = QFileDialog()
filenames = dlg.getSaveFileName(None, "保存日志文件", None, "Txt files(*.txt)")
try:
with open(file = filenames[0], mode='w', encoding='utf-8') as file:
file.write(self.textEditReceive.toPlainText())
except:
QMessageBox.critical(self, '日志异常', '保存日志文件失败!')
#%% 加载日志
def openfiles(self):
dlg = QFileDialog()
filenames = dlg.getOpenFileName(None, "加载日志文件", None, "Txt files(*.txt)")
try:
with open(file = filenames[0], mode='r', encoding='utf-8') as file:
self.textEditSend.setPlainText(file.read())
except:
QMessageBox.critical(self, '日志异常', '加载日志文件失败!')
# %%打开博客链接和公众号二维码
#webbrowser.open('https://blog.csdn.net/m0_38106923')
# %%清除发送数据显示
# 自动保存日志 log he csv
def AutoSaveLog(self):
try:
lines = self.buffer.split(b'\n') # 或者使用 b'\r\n' 根据你的需要
# 最后一个元素可能不包含完整的行,所以将其保留作为新的缓存
if len(lines)>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接收与保存csvhex下不保存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_())

View File

@ -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

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@ -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

View File

@ -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

View File

@ -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()

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

View File

@ -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_())

View File

@ -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 = |

View File

@ -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()

View File

@ -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_())

View File

@ -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("串口关闭")

View File

@ -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_()

View File

@ -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])

View File

@ -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]

View File

@ -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()