怎加了非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] [UI_config]
port = 9000 port = 9000
hex_send = 0 hex_send = 0
hex_receive = 2 hex_receive = 0
add_date = 0 add_date = 0
cr_lf = 2 cr_lf = 0
auto_sav_log = 2 auto_sav_log = 2
modbus_csv = 0 modbus_csv = 0
@ -12,8 +12,8 @@ funcode = F4
position = 5 position = 5
[DisHex_config] [DisHex_config]
row00 = 浓度|0|2|1|3F10|2 row00 = |||||0
row01 = 测试|1|3|1|105678|2 row01 = |||||0
row02 = |||||0 row02 = |||||0
row03 = |||||0 row03 = |||||0
row04 = |||||0 row04 = |||||0
@ -114,103 +114,103 @@ row98 = |||||0
[Quick_config] [Quick_config]
log_time = 10 log_time = 10
button00 = | button00 =
button01 = | button01 =
button02 = | button02 =
button03 = read| button03 =
button04 = | button04 =
button05 = | button05 =
button06 = | button06 =
button07 = | button07 =
button08 = | button08 =
button09 = | button09 =
button10 = | button10 =
button11 = | button11 =
button12 = | button12 =
button13 = | button13 =
button14 = | button14 =
button15 = | button15 =
button16 = | button16 =
button17 = | button17 =
button18 = | button18 =
button19 = | button19 =
button20 = | button20 =
button21 = | button21 =
button22 = | button22 =
button23 = | button23 =
button24 = | button24 =
button25 = | button25 =
button26 = | button26 =
button27 = | button27 =
button28 = | button28 =
button29 = | button29 =
button30 = | button30 =
button31 = | button31 =
button32 = | button32 =
button33 = | button33 =
button34 = | button34 =
button35 = | button35 =
button36 = | button36 =
button37 = | button37 =
button38 = | button38 =
button39 = | button39 =
button40 = | button40 =
button41 = | button41 =
button42 = | button42 =
button43 = | button43 =
button44 = | button44 =
button45 = | button45 =
button46 = | button46 =
button47 = | button47 =
button48 = | button48 =
button49 = | button49 =
button50 = | button50 =
button51 = | button51 =
button52 = | button52 =
button53 = | button53 =
button54 = | button54 =
button55 = | button55 =
button56 = | button56 =
button57 = | button57 =
button58 = | button58 =
button59 = | button59 =
button60 = | button60 =
button61 = | button61 =
button62 = | button62 =
button63 = | button63 =
button64 = | button64 =
button65 = | button65 =
button66 = | button66 =
button67 = | button67 =
button68 = | button68 =
button69 = | button69 =
button70 = | button70 =
button71 = | button71 =
button72 = | button72 =
button73 = | button73 =
button74 = | button74 =
button75 = | button75 =
button76 = | button76 =
button77 = | button77 =
button78 = | button78 =
button79 = | button79 =
button80 = | button80 =
button81 = | button81 =
button82 = | button82 =
button83 = | button83 =
button84 = | button84 =
button85 = | button85 =
button86 = | button86 =
button87 = | button87 =
button88 = | button88 =
button89 = | button89 =
button90 = | button90 =
button91 = | button91 =
button92 = | button92 =
button93 = | button93 =
button94 = | button94 =
button95 = | button95 =
button96 = | button96 =
button97 = | button97 =
button98 = | button98 =

View File

@ -6,6 +6,7 @@ Created on Sun Sep 29 09:01:22 2024
""" """
import datetime import datetime
import os import os
os.environ['QT_OPENGL'] = 'software' # 强制使用软件渲染
import re import re
import socket import socket
import sys import sys
@ -14,7 +15,7 @@ import time
from configparser import ConfigParser from configparser import ConfigParser
from PyQt5 import QtWidgets from PyQt5 import QtWidgets
from PyQt5.QtCore import QTimer,Qt from PyQt5.QtCore import QTimer
from PyQt5.QtWidgets import QMessageBox, QFileDialog, QInputDialog, QTableWidgetItem from PyQt5.QtWidgets import QMessageBox, QFileDialog, QInputDialog, QTableWidgetItem
from PyNetUi import Ui_UartAssistant from PyNetUi import Ui_UartAssistant
@ -115,7 +116,7 @@ class Pyqt5Net(QtWidgets.QWidget, Ui_UartAssistant):
self.tableWidget.setRowCount(self.quick_num) self.tableWidget.setRowCount(self.quick_num)
for i in range(self.quick_num): # 从0到20 for i in range(self.quick_num): # 从0到20
item = QtWidgets.QTableWidgetItem() item = QtWidgets.QTableWidgetItem()
item.setCheckState(Qt.Unchecked) item.setCheckState(0)
self.tableWidget.setItem(i, 0, item) 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: 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_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" 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: else:
sav_name = datetime.datetime.now().strftime("%Y-%m-%d") + '.log' 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" 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()