增加了解析功能、增加了发送全部通道、为将QTextEdit 改为 PlainText做备份

This commit is contained in:
wangxibao 2025-01-24 15:22:55 +08:00
parent 87730b1732
commit 2a48d097be
16 changed files with 1062 additions and 1867 deletions

118
PyNetAssistant/--PyNet.ini Normal file
View File

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

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

@ -0,0 +1,8 @@
# 默认忽略的文件
/shelf/
/workspace.xml
# 基于编辑器的 HTTP 客户端请求
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

8
PyNetAssistant/.idea/PyNetAssistant.iml generated Normal file
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
PyNetAssistant/.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>

8
PyNetAssistant/.idea/modules.xml generated Normal file
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/PyNetAssistant.iml" filepath="$PROJECT_DIR$/.idea/PyNetAssistant.iml" />
</modules>
</component>
</project>

6
PyNetAssistant/.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,72 @@
# -*- coding: utf-8 -*-
"""
Created on Tue May 28 15:40:48 2024
@author: WANGXIBAO
"""
# -*- coding: utf-8 -*-
import csv
import os
import re
import time
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
class HexData2Num():
def __init__(self):
super().__init__()

Binary file not shown.

View File

@ -1,45 +1,159 @@
[UI_config]
port = 9000
hex_send = 0
hex_receive = 0
add_date = 0
cr_lf = 2
auto_sav_log = 2
modbus_csv = 0
[Modbus_config]
funcode = F4
position = 5
[DisHex_config]
row00 = 浓度|0|4|1|2
row01 = 测试|1|3|1|2
row02 = ||||0
row03 = ||||0
row04 = ||||0
row05 = ||||0
row06 = ||||0
row07 = ||||0
row08 = ||||0
row09 = ||||0
row10 = ||||0
row11 = ||||0
row12 = ||||0
row13 = ||||0
row14 = ||||0
row15 = ||||0
row16 = ||||0
row17 = ||||0
row18 = ||||0
row19 = ||||0
row20 = ||||0
row21 = ||||0
row22 = ||||0
row23 = ||||0
row24 = ||||0
row25 = ||||0
row26 = ||||0
row27 = ||||0
row28 = ||||0
row29 = ||||0
row30 = ||||0
row31 = ||||0
row32 = ||||0
row33 = ||||0
row34 = ||||0
row35 = ||||0
row36 = ||||0
row37 = ||||0
row38 = ||||0
row39 = ||||0
row40 = ||||0
row41 = ||||0
row42 = ||||0
row43 = ||||0
row44 = ||||0
row45 = ||||0
row46 = ||||0
row47 = ||||0
row48 = ||||0
row49 = ||||0
row50 = ||||0
row51 = ||||0
row52 = ||||0
row53 = ||||0
row54 = ||||0
row55 = ||||0
row56 = ||||0
row57 = ||||0
row58 = ||||0
row59 = ||||0
row60 = ||||0
row61 = ||||0
row62 = ||||0
row63 = ||||0
row64 = ||||0
row65 = ||||0
row66 = ||||0
row67 = ||||0
row68 = ||||0
row69 = ||||0
row70 = ||||0
row71 = ||||0
row72 = ||||0
row73 = ||||0
row74 = ||||0
row75 = ||||0
row76 = ||||0
row77 = ||||0
row78 = ||||0
row79 = ||||0
row80 = ||||0
row81 = ||||0
row82 = ||||0
row83 = ||||0
row84 = ||||0
row85 = ||||0
row86 = ||||0
row87 = ||||0
row88 = ||||0
row89 = ||||0
row90 = ||||0
row91 = ||||0
row92 = ||||0
row93 = ||||0
row94 = ||||0
row95 = ||||0
row96 = ||||0
row97 = ||||0
row98 = ||||0
[Quick_config] [Quick_config]
log_time = 1 log_time = 10
button00 = read 0|序列号 button00 = |
button01 = read 1|激光温度 button01 = |
button02 = read 2|K*1000 button02 = |
button03 = read 3|B*1000 button03 = read|
button04 = read 4|电阻阻值 button04 = |
button05 = read 5|电阻抽头 button05 = |
button06 = read 6|输出温度 button06 = |
button07 = read 7|输出激光 button07 = |
button08 = read 8|输出状态 button08 = |
button09 = read 9|激光温补 button09 = |
button10 = read 10|噪声长度 button10 = |
button11 = read 11|扫描长度 button11 = |
button12 = | button12 = |
button13 = read 13|气温校准 button13 = |
button14 = read 14|滑动开关 button14 = |
button15 = read 15|滑动标准差 button15 = |
button16 = read 16|浓度温补 button16 = |
button17 = read all|读取全部 button17 = |
button18 = | button18 = |
button19 = | button19 = |
button20 = write 0,2024100103|序列号 button20 = |
button21 = write 1,65000|激光温度 button21 = |
button22 = write 2,1000|K*1000 button22 = |
button23 = write 3,0|B*1000 button23 = |
button24 = write 4,0|电阻阻值 button24 = |
button25 = write 5,30|电阻抽头 button25 = |
button26 = write 6,0|输出温度 button26 = |
button27 = write 7,0|输出激光 button27 = |
button28 = write 8,1|输出状态 button28 = |
button29 = write 9,0|激光温补 button29 = |
button30 = write 10,100|噪声长度 button30 = |
button31 = write 11,600|扫描长度 button31 = |
button32 = 22|eee button32 = |
button33 = write 13,30500|气温校准 button33 = |
button34 = write 14,1|滑动开关 button34 = |
button35 = write 15,10|滑动标准差 button35 = |
button36 = write 16,1|浓度温补 button36 = |
button37 = | button37 = |
button38 = | button38 = |
button39 = 01 04 01 2D 00 01 A0 3F| button39 = |
button40 = | button40 = |
button41 = | button41 = |
button42 = | button42 = |

View File

@ -4,70 +4,79 @@ Created on Sun Sep 29 09:01:22 2024
@author: WANGXIBAO @author: WANGXIBAO
""" """
import sys,os import datetime
import re,socket import os
import re
import time,datetime import socket
import sys
from PyQt5 import QtWidgets import time
from PyQt5.QtWidgets import QMessageBox ,QFileDialog,QInputDialog
from PyQt5.QtCore import QTimer
from PyNetUi import Ui_UartAssistant
from configparser import ConfigParser from configparser import ConfigParser
class Pyqt5Net(QtWidgets.QWidget,Ui_UartAssistant): from PyQt5 import QtWidgets
from PyQt5.QtCore import QTimer,Qt
from PyQt5.QtWidgets import QMessageBox, QFileDialog, QInputDialog, QTableWidgetItem
from PyNetUi import Ui_UartAssistant
class Pyqt5Net(QtWidgets.QWidget, Ui_UartAssistant):
# %%初始化程序 # %%初始化程序
def __init__(self): def __init__(self):
super(Pyqt5Net, self).__init__() super(Pyqt5Net, self).__init__()
self.setupUi(self) self.setupUi(self)
self.quick_num = 99 self.quick_num = 99
self.init() #信号和槽 self.init() #信号和槽
self.IniPath = "PyNet.ini" self.IniPath = "PyNet.ini"
self.log_time = 10 self.log_time = 10
self.CheckCfgIniData() #更改按钮的文字 self.funcode = "F4"
self.position = 5
self.CheckCfgIniData() #更改按钮的文字
self.log_count = 0 self.log_count = 0
self.log_buffer = {} #定义成一个字典,键--文件名,值--对于收到的字符串列表 self.log_buffer = {} #定义成一个字典,键--文件名,值--对于收到的字符串列表
# 设置Logo和标题 # 设置Logo和标题
#self.setWindowIcon(QIcon('favicon.ico')) #self.setWindowIcon(QIcon('favicon.ico'))
self.setWindowTitle("网口调试助手") self.setWindowTitle("网口调试助手")
# 设置禁止拉伸窗口大小 # 设置禁止拉伸窗口大小
#self.setFixedSize(self.width(), self.height()) #self.setFixedSize(self.width(), self.height())
# 发送数据和接收数据数目置零 # 发送数据和接收数据数目置零
self.data_num_sended = 0 self.data_num_sended = 0
self.lineEditSendNum.setText(str(self.data_num_sended)) self.lineEditSendNum.setText(str(self.data_num_sended))
self.data_num_received = 0 self.data_num_received = 0
self.lineEditReceiveNum.setText(str(self.data_num_received)) self.lineEditReceiveNum.setText(str(self.data_num_received))
# 串口关闭按钮使能关闭 # 串口关闭按钮使能关闭
self.pushButton_closeNet.setEnabled(False) self.pushButton_closeNet.setEnabled(False)
# 发送框、文本框清除 # 发送框、文本框清除
self.textEditReceive.setText("") self.textEditReceive.setText("")
self.textEditSend.setText("") self.textEditSend.setText("")
self.get_all_local_ips() self.get_all_local_ips()
# 定时器接收数据 # 定时器接收数据
self.timer = QTimer() #self.timer = QTimer()
self.timer.timeout.connect(self.data_receive) self.timer: QTimer = QTimer()
#self.timer.timeout.connect(self.data_receive)
timeout_signal = self.timer.timeout
timeout_signal.connect(self.data_receive)
#加载快捷指令 #加载快捷指令
self.widget_6.hide() self.widget_6.hide()
#加载快捷指令的按键值 #加载快捷指令的按键值
#建立信号与槽 #建立信号与槽
def init(self): def init(self):
self.pushButton_openNet.clicked.connect(self.open_net) self.pushButton_openNet.clicked.connect(self.open_net)
self.pushButton_closeNet.clicked.connect(self.close_net) self.pushButton_closeNet.clicked.connect(self.close_net)
self.pushButtonSend.clicked.connect(lambda:self.data_send(text_quick= None)) self.pushButtonSend.clicked.connect(lambda: self.data_send(text_quick=None))
# 清除发送按钮 # 清除发送按钮
self.pushButtonClearSend.clicked.connect(self.send_data_clear) self.pushButtonClearSend.clicked.connect(self.send_data_clear)
# 清除接收按钮 # 清除接收按钮
self.pushButtonClearReceive.clicked.connect(self.receive_data_clear) self.pushButtonClearReceive.clicked.connect(self.receive_data_clear)
# 定时发送数据 # 定时发送数据
self.timer_send = QTimer() self.timer_send = QTimer()
self.timer_send.timeout.connect(self.data_send) self.timer_send.timeout.connect(self.data_send)
@ -82,7 +91,7 @@ class Pyqt5Net(QtWidgets.QWidget,Ui_UartAssistant):
horizontalLayoutName = f"horizontalLayoutQuick_{index_str}" horizontalLayoutName = f"horizontalLayoutQuick_{index_str}"
horizontalLayout = QtWidgets.QHBoxLayout() horizontalLayout = QtWidgets.QHBoxLayout()
horizontalLayout.setObjectName(horizontalLayoutName) horizontalLayout.setObjectName(horizontalLayoutName)
# 创建 QLineEdit 并设置动态属性 # 创建 QLineEdit 并设置动态属性
lineEditName = f"lineEditQuick_{index_str}" lineEditName = f"lineEditQuick_{index_str}"
setattr(self, lineEditName, QtWidgets.QLineEdit(self.layoutWidget1)) setattr(self, lineEditName, QtWidgets.QLineEdit(self.layoutWidget1))
@ -94,41 +103,40 @@ class Pyqt5Net(QtWidgets.QWidget,Ui_UartAssistant):
getattr(self, buttonName).setObjectName(buttonName) getattr(self, buttonName).setObjectName(buttonName)
horizontalLayout.addWidget(getattr(self, buttonName)) horizontalLayout.addWidget(getattr(self, buttonName))
self.verticalLayout_8.addLayout(horizontalLayout) self.verticalLayout_8.addLayout(horizontalLayout)
# 连接按钮点击事件到槽函数 # 连接按钮点击事件到槽函数
button = getattr(self, buttonName) button = getattr(self, buttonName)
if button: if button:
button.clicked.connect(lambda checked, idx=i: self.onButtonClick(idx)) button.clicked.connect(lambda checked, idx=i: self.onButtonClick(idx))
self.double_click_timers = {} # 存储双击定时器 # 建立表格解析并显示hex
self.tableWidget.setRowCount(self.quick_num)
for i in range(self.quick_num): # 从0到20
item = QtWidgets.QTableWidgetItem()
item.setCheckState(Qt.Unchecked)
self.tableWidget.setItem(i, 0, item)
self.double_click_timers = {} # 存储双击定时器
#%% 重写关闭按钮 #%% 重写关闭按钮
def closeEvent(self, event): def closeEvent(self, event):
#关闭界面前保存快捷区域的命令和名称 self.SavConfig()
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)
self.close_net() self.close_net()
# 调用父类的关闭事件处理函数 # 调用父类的关闭事件处理函数
super().closeEvent(event) super().closeEvent(event)
#加载本地网络地址 #加载本地网络地址
def get_all_local_ips(self): def get_all_local_ips(self):
ip_addresses = [] ip_addresses = []
for interface in socket.getaddrinfo(socket.gethostname(), None): for interface in socket.getaddrinfo(socket.gethostname(), None):
address = interface[4][0] address = interface[4][0]
if ':' not in address: # IPv6地址包含冒号 if ':' not in address: # IPv6地址包含冒号
ip_addresses.append(address) ip_addresses.append(address)
print(ip_addresses) print(ip_addresses)
for ip in ip_addresses: for ip in ip_addresses:
self.comboBox_localAddr.insertItem(0,ip) self.comboBox_localAddr.insertItem(0, ip)
self.comboBox_localAddr.setCurrentIndex(0) self.comboBox_localAddr.setCurrentIndex(0)
# 打开网络连接 # 打开网络连接
@ -136,7 +144,7 @@ class Pyqt5Net(QtWidgets.QWidget,Ui_UartAssistant):
IP = self.comboBox_localAddr.currentText() IP = self.comboBox_localAddr.currentText()
port = self.lineEdit_port.text() port = self.lineEdit_port.text()
udp_addr = (IP, int(port)) udp_addr = (IP, int(port))
self.udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) #创建接收空socket self.udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) #创建接收空socket
print("绑定地址", udp_addr) print("绑定地址", udp_addr)
try: try:
self.udp_socket.bind(udp_addr) self.udp_socket.bind(udp_addr)
@ -146,16 +154,13 @@ class Pyqt5Net(QtWidgets.QWidget,Ui_UartAssistant):
except Exception as e: except Exception as e:
print(f"Error reading configuration: {e}") print(f"Error reading configuration: {e}")
return None return None
#使能相关按钮 #使能相关按钮
self.pushButton_closeNet.setEnabled(True) self.pushButton_closeNet.setEnabled(True)
self.pushButton_openNet.setEnabled(False) self.pushButton_openNet.setEnabled(False)
# 打开串口接收定时器周期为1ms # 打开串口接收定时器周期为1ms
self.timer.start(20) self.timer.start(20)
def close_net(self): def close_net(self):
if hasattr(self, 'udp_socket'): if hasattr(self, 'udp_socket'):
@ -165,28 +170,30 @@ class Pyqt5Net(QtWidgets.QWidget,Ui_UartAssistant):
self.pushButton_closeNet.setEnabled(False) self.pushButton_closeNet.setEnabled(False)
self.pushButton_openNet.setEnabled(True) self.pushButton_openNet.setEnabled(True)
print("关闭网络连接") print("关闭网络连接")
#接收数据 #接收数据
def data_receive(self): def data_receive(self):
try: try:
recv_data = self.udp_socket.recvfrom(1024) # 1024表示本次接收的最大字节数 recv_data = self.udp_socket.recvfrom(1024) # 1024表示本次接收的最大字节数
out_s = '' out_s = ''
# 打印接收到的数据 # 打印接收到的数据
if self.checkBoxHexReceive.checkState(): if self.checkBoxHexReceive.checkState():
line_utf8 = recv_data[0].hex() line_utf8 = recv_data[0].hex().upper()
out_s = ' '.join(['{:02X}'.format(b) for b in bytes.fromhex(line_utf8)])
else: else:
line_utf8 = recv_data[0].decode('utf-8',errors='replace') line_utf8 = recv_data[0].decode('utf-8', errors='replace')
print("[From %s:%d]:%s" % (recv_data[1][0], recv_data[1][1], line_utf8)) print("[From %s:%d]:%s" % (recv_data[1][0], recv_data[1][1], line_utf8))
num = len(line_utf8) num = len(line_utf8)
# 接收窗口中增加来源地址显示 # 接收窗口中增加来源地址显示
recv_addr = recv_data[1][0]+':'+str(recv_data[1][1]) recv_addr = recv_data[1][0] + ':' + str(recv_data[1][1])
if not self.is_in_comboBox_channel(recv_addr): if not self.is_in_comboBox_channel(recv_addr):
self.comboBox_channel.addItem(recv_addr) self.comboBox_channel.addItem(recv_addr)
if recv_addr==self.comboBox_channel.currentText() or self.comboBox_channel.currentText()=="ALL": if recv_addr == self.comboBox_channel.currentText() or self.comboBox_channel.currentText() == "ALL":
#self.textEditReceive.insertPlainText('<' + recv_addr+ '> ' ) #self.textEditReceive.insertPlainText('<' + recv_addr+ '> ' )
if self.checkBoxAddDate.isChecked(): if self.checkBoxAddDate.isChecked():
nowTime = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f") nowTime = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f")
nowTime = nowTime[:-3] nowTime = nowTime[:-3]
@ -195,84 +202,94 @@ class Pyqt5Net(QtWidgets.QWidget,Ui_UartAssistant):
# HEX显示数据 # HEX显示数据
if self.checkBoxHexReceive.checkState(): if self.checkBoxHexReceive.checkState():
# line_utf8_bytes = line_utf8.hex() # 编码为 UTF-8 字节串 # line_utf8_bytes = line_utf8.hex() # 编码为 UTF-8 字节串
# for byte in line_utf8_bytes: # for byte in line_utf8_bytes:
# out_s += '{:02X} '.format(byte) # 使用大写字母 X # out_s += '{:02X} '.format(byte) # 使用大写字母 X
out_s = ' '.join(['{:02X}'.format(b) for b in bytes.fromhex(line_utf8)])
# self.textEditReceive.insertPlainText(out_s) # self.textEditReceive.insertPlainText(out_s)
# self.textEditReceive.insertPlainText('\r\n') # self.textEditReceive.insertPlainText('\r\n')
self.add_line_to_textedit('<' + recv_addr+ '> ' + out_s) self.add_line_to_textedit('<' + recv_addr + '> ' + out_s)
# 解析数据
self.Disp_hex_receive(line_utf8)
# ASCII显示数据 # ASCII显示数据
else: else:
#print("解码前",datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f")) #print("解码前",datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f"))
#self.textEditReceive.insertPlainText(line_utf8) #self.textEditReceive.insertPlainText(line_utf8)
self.add_line_to_textedit('<' + recv_addr+ '> ' + line_utf8) self.add_line_to_textedit('<' + recv_addr + '> ' + line_utf8)
#print("解码数据",datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f")) #print("解码数据",datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f"))
# 接收换行 # 接收换行
if self.checkBoxCRLF.isChecked(): if self.checkBoxCRLF.isChecked():
self.textEditReceive.insertPlainText('\r\n') self.textEditReceive.insertPlainText('\r\n')
# 获取到text光标 # 获取到text光标
textCursor = self.textEditReceive.textCursor() textCursor = self.textEditReceive.textCursor()
# 滚动到底部 # 滚动到底部
textCursor.movePosition(textCursor.End) textCursor.movePosition(textCursor.End)
# 设置光标到text中去 # 设置光标到text中去
self.textEditReceive.setTextCursor(textCursor) self.textEditReceive.setTextCursor(textCursor)
# 统计接收字符的数量 # 统计接收字符的数量
self.data_num_received += num self.data_num_received += num
self.lineEditReceiveNum.setText(str(self.data_num_received)) self.lineEditReceiveNum.setText(str(self.data_num_received))
# 自动保存日志 # 自动保存日志
if self.checkBoxAutoSaveLog.isChecked(): if self.checkBoxAutoSaveLog.isChecked():
line = line_utf8.split(',') if self.checkBoxHexReceive.checkState():
if len(line) ==2: #根据功能码保存数据
sav_name = line[0] +'_'+ datetime.datetime.now().strftime("%Y-%m-%d")+'.txt' if line_utf8[2*self.position:2*self.position+2] == self.funcode:
sav_str = datetime.datetime.now().strftime("%Y-%m-%dT%H:%M:%S.%f")[:23] +" " +line[1] 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"
else:
sav_name = datetime.datetime.now().strftime("%Y-%m-%d") + '.log'
sav_str = datetime.datetime.now().strftime("%Y-%m-%dT%H:%M:%S.%f")[:23] + " " + out_s + "\r\n"
else: else:
sav_name = datetime.datetime.now().strftime("%Y-%m-%d")+'.log' line = line_utf8.split(',')
if self.checkBoxHexReceive.checkState(): if len(line) == 2:
sav_str = datetime.datetime.now().strftime("%Y-%m-%dT%H:%M:%S.%f")[:23] +" " +out_s +"\r\n" sav_name = line[0] + '_' + datetime.datetime.now().strftime("%Y-%m-%d") + '.txt'
sav_str = datetime.datetime.now().strftime("%Y-%m-%dT%H:%M:%S.%f")[:23] + " " + line[1]
else: else:
sav_str = datetime.datetime.now().strftime("%Y-%m-%dT%H:%M:%S.%f")[:23] +" " +line_utf8 sav_name = datetime.datetime.now().strftime("%Y-%m-%d") + '.log'
sav_str = datetime.datetime.now().strftime("%Y-%m-%dT%H:%M:%S.%f")[:23] + " " + line_utf8
# 将日志信息添加到缓冲区 # 将日志信息添加到缓冲区
if sav_name not in self.log_buffer: if sav_name not in self.log_buffer:
self.log_buffer[sav_name] = [] self.log_buffer[sav_name] = []
self.log_buffer[sav_name].append(sav_str) self.log_buffer[sav_name].append(sav_str)
# 当缓冲区中的记录达到10条时写入文件 # 当缓冲区中的记录达到10条时写入文件
if len(self.log_buffer[sav_name]) >= self.log_time: if len(self.log_buffer[sav_name]) >= self.log_time:
with open(sav_name, mode='a', newline='',encoding='utf-8', errors='replace') as file: with open(sav_name, mode='a', newline='', encoding='utf-8', errors='replace') as file:
file.writelines(self.log_buffer[sav_name]) file.writelines(self.log_buffer[sav_name])
self.log_buffer[sav_name].clear() self.log_buffer[sav_name].clear()
except socket.error as e: except socket.error as e:
#print(f"Socket error: {e}") #print(f"Socket error: {e}")
pass pass
def data_send(self,text_quick = None):
if text_quick== None: def data_send(self, text_quick=None):
if text_quick == None:
input_s = self.textEditSend.toPlainText() input_s = self.textEditSend.toPlainText()
else: else:
input_s = text_quick input_s = text_quick
try: try:
if input_s != "": if input_s != "":
# 时间显示 # 时间显示
if self.checkBoxAddDate.isChecked(): if self.checkBoxAddDate.isChecked():
self.textEditReceive.insertPlainText((time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())) + " ") self.textEditReceive.insertPlainText((time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())) + " ")
# HEX发送 # HEX发送
if self.checkBoxHexSend.isChecked(): if self.checkBoxHexSend.isChecked():
input_s = input_s.strip() input_s = input_s.strip()
send_list = [] send_list = []
while input_s != '': while input_s != '':
@ -281,57 +298,76 @@ class Pyqt5Net(QtWidgets.QWidget,Ui_UartAssistant):
except ValueError: except ValueError:
QMessageBox.critical(self, '串口异常', '请输入规范十六进制数据,以空格分开!') QMessageBox.critical(self, '串口异常', '请输入规范十六进制数据,以空格分开!')
return None return None
input_s = input_s[2:].strip() input_s = input_s[2:].strip()
send_list.append(num) send_list.append(num)
input_s = bytes(send_list) input_s = bytes(send_list)
# ASCII发送 # ASCII发送
else: else:
input_s = (input_s).encode('utf-8') input_s = (input_s).encode('utf-8')
input_s = re.sub(b'(?<!\r)\n', b'\r\n', input_s) input_s = re.sub(b'(?<!\r)\n', b'\r\n', input_s)
# HEX接收显示 # HEX接收显示
if self.checkBoxHexReceive.isChecked(): if self.checkBoxHexReceive.isChecked():
out_s = '' out_s = ''
for i in range(0, len(input_s)): for i in range(0, len(input_s)):
out_s = out_s + '{:02X}'.format(input_s[i]) + ' ' out_s = out_s + '{:02X}'.format(input_s[i]) + ' '
print(out_s) print(out_s)
self.textEditReceive.insertPlainText(out_s) self.add_line_to_textedit(out_s)
# ASCII接收显示 # ASCII接收显示
else: else:
self.textEditReceive.insertPlainText(input_s.decode('utf-8')) self.add_line_to_textedit(input_s.decode('utf-8'))
# 接收换行 # 接收换行
if self.checkBoxCRLF.isChecked(): if self.checkBoxCRLF.isChecked():
self.textEditReceive.insertPlainText('\r\n') self.textEditReceive.insertPlainText('\r\n')
# 获取到Text光标 # 获取到Text光标
textCursor = self.textEditReceive.textCursor() textCursor = self.textEditReceive.textCursor()
# 滚动到底部 # 滚动到底部
textCursor.movePosition(textCursor.End) textCursor.movePosition(textCursor.End)
# 设置光标到Text中去 # 设置光标到Text中去
self.textEditReceive.setTextCursor(textCursor) self.textEditReceive.setTextCursor(textCursor)
#定义服务器的IP地址和端口号 # 发送全部通道
sever = self.comboBox_channel.currentText().split(':') if self.checkBoxSendAll.isChecked():
server_ip = sever[0] # 弹出确认对话框
server_port = int(sever[1]) if QMessageBox.question(None, "警告", "发送所有通道,是否继续执行?") == QMessageBox.Yes:
server_address = (server_ip, server_port) for i in range(1,self.comboBox_channel.count()):
# 将消息发送到服务器 # 定义服务器的IP地址和端口号
num = self.udp_socket.sendto(input_s, server_address) sever = self.comboBox_channel.itemText(i).split(':')
server_ip = sever[0]
# 统计发送字符数量 server_port = int(sever[1])
self.data_num_sended += num server_address = (server_ip, server_port)
# 将消息发送到服务器
num = self.udp_socket.sendto(input_s, server_address)
# 统计发送字符数量
self.data_num_sended += num
else:
#发送单个通道
#定义服务器的IP地址和端口号
sever = self.comboBox_channel.currentText().split(':')
server_ip = sever[0]
server_port = int(sever[1])
server_address = (server_ip, server_port)
# 将消息发送到服务器
num = self.udp_socket.sendto(input_s, server_address)
# 统计发送字符数量
self.data_num_sended += num
self.lineEditSendNum.setText(str(self.data_num_sended)) self.lineEditSendNum.setText(str(self.data_num_sended))
except: except:
pass pass
# %%定时发送数据 # %%定时发送数据
def data_send_timer(self): def data_send_timer(self):
try: try:
if 1<= int(self.lineEditTime.text()) <= 30000: # 定时时间1ms~30s内 if 1 <= int(self.lineEditTime.text()) <= 30000: # 定时时间1ms~30s内
if self.checkBoxReapitSend.isChecked(): if self.checkBoxReapitSend.isChecked():
self.timer_send.start(int(self.lineEditTime.text())) self.timer_send.start(int(self.lineEditTime.text()))
self.lineEditTime.setEnabled(False) self.lineEditTime.setEnabled(False)
@ -342,28 +378,31 @@ class Pyqt5Net(QtWidgets.QWidget,Ui_UartAssistant):
QMessageBox.critical(self, '定时发送数据异常', '定时发送数据周期仅可设置在30秒内') QMessageBox.critical(self, '定时发送数据异常', '定时发送数据周期仅可设置在30秒内')
except: except:
QMessageBox.critical(self, '定时发送数据异常', '请设置正确的数值类型!') QMessageBox.critical(self, '定时发送数据异常', '请设置正确的数值类型!')
# %%保存日志 # %%保存日志
def savefiles(self): def savefiles(self):
dlg = QFileDialog() dlg = QFileDialog()
filenames = dlg.getSaveFileName(None, "保存日志文件", None, "Txt files(*.txt)") filenames = dlg.getSaveFileName(None, "保存日志文件", None, "Txt files(*.txt)")
try: try:
with open(file = filenames[0], mode='w', encoding='utf-8') as file: with open(file=filenames[0], mode='w', encoding='utf-8') as file:
file.write(self.textEditReceive.toPlainText()) file.write(self.textEditReceive.toPlainText())
except: except:
QMessageBox.critical(self, '日志异常', '保存日志文件失败!') QMessageBox.critical(self, '日志异常', '保存日志文件失败!')
#%% 加载日志 #%% 加载日志
def openfiles(self): def openfiles(self):
dlg = QFileDialog() dlg = QFileDialog()
filenames = dlg.getOpenFileName(None, "加载日志文件", None, "Txt files(*.txt)") filenames = dlg.getOpenFileName(None, "加载日志文件", None, "Txt files(*.txt)")
try: try:
with open(file = filenames[0], mode='r', encoding='utf-8') as file: with open(file=filenames[0], mode='r', encoding='utf-8') as file:
self.textEditSend.setPlainText(file.read()) self.textEditSend.setPlainText(file.read())
except: except:
QMessageBox.critical(self, '日志异常', '加载日志文件失败!') QMessageBox.critical(self, '日志异常', '加载日志文件失败!')
#%% 清除计数 #%% 清除计数
def send_data_clear(self): def send_data_clear(self):
self.textEditSend.setText("") self.textEditSend.setText("")
@ -377,13 +416,31 @@ class Pyqt5Net(QtWidgets.QWidget,Ui_UartAssistant):
self.data_num_received = 0 self.data_num_received = 0
self.lineEditSendNum.setText(str(self.data_num_received)) self.lineEditSendNum.setText(str(self.data_num_received))
def Disp_hex_receive(self,hexdata):
len = self.tableWidget.rowCount()
try:
for i in range(len):
if self.tableWidget.item(i, 0).checkState() == 2:
start = int(self.tableWidget.item(i, 1).text())
num = int(self.tableWidget.item(i, 2).text())
scale = int(self.tableWidget.item(i, 3).text())
value = int(hexdata[start*2:(start+num)*2],16)/scale
item = QTableWidgetItem(str(value))
self.tableWidget.setItem(i, 4, item)
except Exception as e:
print(e)
pass
#设置接受区域显示条数 #设置接受区域显示条数
def add_line_to_textedit(self, new_line): def add_line_to_textedit(self, new_line):
# 获取当前文本并按行分割 # 获取当前文本并按行分割
current_lines = self.textEditReceive.toPlainText().splitlines() current_lines = self.textEditReceive.toPlainText().splitlines()
# 添加新的行到列表中 # 添加新的行到列表中
current_lines.append(new_line) current_lines.append(new_line)
# 如果行数超过100则删除最早的行直到剩下100行 # 如果行数超过100则删除最早的行直到剩下100行
if len(current_lines) > 1000: if len(current_lines) > 1000:
current_lines = current_lines[-1000:] # 只保留最新的100行 current_lines = current_lines[-1000:] # 只保留最新的100行
@ -391,49 +448,113 @@ class Pyqt5Net(QtWidgets.QWidget,Ui_UartAssistant):
self.textEditReceive.setPlainText('\n'.join(current_lines)) self.textEditReceive.setPlainText('\n'.join(current_lines))
#检查是否在comboBox_channel中 #检查是否在comboBox_channel中
def is_in_comboBox_channel(self,addr_rece): def is_in_comboBox_channel(self, addr_rece):
for i in range(self.comboBox_channel.count()): for i in range(self.comboBox_channel.count()):
if addr_rece == self.comboBox_channel.itemText(i): if addr_rece == self.comboBox_channel.itemText(i):
return True return True
return False return False
def channel_clear(self): def channel_clear(self):
self.comboBox_channel.lineEdit().clear() self.comboBox_channel.lineEdit().clear()
for i in range(self.comboBox_channel.count()-1): for i in range(self.comboBox_channel.count() - 1):
self.comboBox_channel.removeItem(1) self.comboBox_channel.removeItem(1)
self.comboBox_channel.setCurrentIndex(0) self.comboBox_channel.setCurrentIndex(0)
#开关快捷指令栏 #开关快捷指令栏
def adjust_sidebar(self): def adjust_sidebar(self):
if self.widget_6.isHidden(): if self.widget_6.isHidden():
self.widget_6.show() self.widget_6.show()
else: else:
self.widget_6.hide() self.widget_6.hide()
def onPushButtonQuickClicked(self, line_edit): def onPushButtonQuickClicked(self, line_edit):
text = getattr(self, line_edit).text() text = getattr(self, line_edit).text()
#print(f"Button clicked: {text}") #print(f"Button clicked: {text}")
if self.checkBox_return.isChecked(): if self.checkBox_return.isChecked():
text = text + "\r\n" text = text + "\r\n"
self.data_send(text) self.data_send(text)
def CheckCfgIniData(self): def CheckCfgIniData(self):
if not os.path.exists(self.IniPath): if not os.path.exists(self.IniPath):
config = ConfigParser() config = ConfigParser()
#UI_config
config.add_section('UI_config')
config.set('UI_config', 'port', '9000')
config.set('UI_config', 'hex_send', '0')
config.set('UI_config', 'hex_receive', '0')
config.set('UI_config', 'add_date', '0')
config.set('UI_config', 'cr_lf', '0')
config.set('UI_config', 'auto_sav_log', '2')
config.set('UI_config', 'modbus_csv', '0')
# Modbus_config
config.add_section('Modbus_config')
config.set('Modbus_config', 'funcode', 'F4') #识别码
config.set('Modbus_config', 'position', '5') #识别码所在位置
#DisHex_config
config.add_section('DisHex_config')
for i in range(self.quick_num):
idx = f'{i:02}'
rowname = f'row{idx}'
config.set('DisHex_config', rowname, '|||||0')
#Quick_config
config.add_section('Quick_config') config.add_section('Quick_config')
config.set('Quick_config', 'log_time', '10') config.set('Quick_config', 'log_time', '10')
for i in range(self.quick_num): for i in range(self.quick_num):
idx = f'{i:02}' idx = f'{i:02}'
button_name = f'Button{idx}' # 格式化按钮名称,确保两位数 button_name = f'Button{idx}' # 格式化按钮名称,确保两位数
config.set('Quick_config', button_name, '') config.set('Quick_config', button_name, '')
with open(self.IniPath, 'w' ,encoding='utf-8') as f: with open(self.IniPath, 'w', encoding='utf-8') as f:
config.write(f) config.write(f)
#读取数据
config = ConfigParser() config = ConfigParser()
config.read(self.IniPath, encoding='utf-8') config.read(self.IniPath, encoding='utf-8')
try: try:
# UI_config
# 创建一个空字典来存储按钮名称和对应的配置 port = config.get('UI_config', 'port')
hex_send = int(config.get('UI_config', 'hex_send'))
hex_receive = int(config.get('UI_config', 'hex_receive'))
add_date = int(config.get('UI_config', 'add_date'))
cr_lf = int(config.get('UI_config', 'cr_lf'))
auto_sav_log = int(config.get('UI_config', 'auto_sav_log'))
modbus_csv = int(config.get('UI_config', 'modbus_csv'))
self.lineEdit_port.setText(port)
self.checkBoxHexSend.setChecked(hex_send)
self.checkBoxHexReceive.setChecked(hex_receive)
self.checkBoxAddDate.setChecked(add_date)
self.checkBoxCRLF.setChecked(cr_lf)
self.checkBoxAutoSaveLog.setChecked(auto_sav_log)
self.checkBoxAutoSaveCsv.setChecked(modbus_csv)
# Modbus_config
self.funcode = config.get('Modbus_config', 'funcode')
self.position = int(config.get('Modbus_config', 'position'))
# DisHex_config
for i in range(self.quick_num):
idx = f'{i:02}'
rowname = f'row{idx}'
rowstr = config.get('DisHex_config', rowname)
rowstr_split = rowstr.split('|')
for col in range(len(rowstr_split)-1):
item = QtWidgets.QTableWidgetItem()
item.setText(rowstr_split[col])
self.tableWidget.setItem(i, col, item)
select = int(rowstr_split[col+1])
item = self.tableWidget.item(i, 0) # 先反读回来再设置不然text丢失
item.setCheckState(select)
self.tableWidget.setItem(i, 0, item)
# Quick_config
# 创建一个空字典来存储按钮名称和对应的配置
self.log_time = int(config.get('Quick_config', 'log_time')) self.log_time = int(config.get('Quick_config', 'log_time'))
# 循环遍历按钮编号从0到19 # 循环遍历按钮编号从0到19
for i in range(self.quick_num): for i in range(self.quick_num):
@ -444,26 +565,57 @@ class Pyqt5Net(QtWidgets.QWidget,Ui_UartAssistant):
config_value_split = config_value.split('|') config_value_split = config_value.split('|')
# 将按钮名称和配置信息存储在字典中 # 将按钮名称和配置信息存储在字典中
if len(config_value_split) == 2: if len(config_value_split) == 2:
# 打印字典查看结果,并赋值 # 打印字典查看结果,并赋值
print(button_name,config_value_split[0],config_value_split[1]) print(button_name, config_value_split[0], config_value_split[1])
getattr(self, f'pushButtonQuick_{idx}').setText(config_value_split[1]) getattr(self, f'pushButtonQuick_{idx}').setText(config_value_split[1])
getattr(self, f'lineEditQuick_{idx}').setText(config_value_split[0]) getattr(self, f'lineEditQuick_{idx}').setText(config_value_split[0])
except Exception as e: except Exception as e:
print(f"Error reading configuration: {e}") print(f"Error reading configuration: {e}")
def SavConfig(self):
def SetCfgIniData(self,button_name,set_text): #关闭界面前保存快捷区域的命令和名称
config = ConfigParser() config = ConfigParser()
config.read(self.IniPath, encoding='utf-8') config.read(self.IniPath, encoding='utf-8')
config.set('Quick_config', button_name, set_text) # 保存UI_config
with open(self.IniPath, 'w' ,encoding='utf-8') as f: config.set('UI_config', 'port', str(self.lineEdit_port.text()))
config.set('UI_config', 'hex_send', str(self.checkBoxHexSend.checkState()))
config.set('UI_config', 'hex_receive', str(self.checkBoxHexReceive.checkState()))
config.set('UI_config', 'add_date', str(self.checkBoxAddDate.checkState()))
config.set('UI_config','cr_lf',str(self.checkBoxCRLF.checkState()))
config.set('UI_config', 'auto_sav_log', str(self.checkBoxAutoSaveLog.checkState()))
config.set('UI_config', 'modbus_csv', str(self.checkBoxAutoSaveCsv.checkState()))
# 保存DisHex_config
for i in range(self.quick_num):
rowstr = []
idx = f'{i:02}'
rowname = f'row{idx}'
for col in range(self.tableWidget.columnCount()-1):
item = self.tableWidget.item(i, col)
if item is not None:
rowstr.append(item.text())
else:
rowstr.append('') # 如果单元格为空,则添加空字符串
selectStr = str(self.tableWidget.item(i,0).checkState())
row_string = '|'.join(rowstr) + f'|{selectStr}'
config.set('DisHex_config', rowname, row_string)
# 保存快捷按钮
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()
config.set('Quick_config', button_name, set_text)
with open(self.IniPath, 'w', encoding='utf-8') as f:
config.write(f) config.write(f)
def onButtonClick(self, idx): def onButtonClick(self, idx):
# 槽函数处理按钮点击事件 # 槽函数处理按钮点击事件
if idx not in self.double_click_timers: if idx not in self.double_click_timers:
self.double_click_timers[idx] = None self.double_click_timers[idx] = None
@ -478,11 +630,11 @@ class Pyqt5Net(QtWidgets.QWidget,Ui_UartAssistant):
if self.double_click_timers[idx]: if self.double_click_timers[idx]:
self.double_click_timers[idx] = None self.double_click_timers[idx] = None
lineEdit = getattr(self, f"lineEditQuick_{index_str}") lineEdit = getattr(self, f"lineEditQuick_{index_str}")
print(f"Text in lineEdit_{idx}: {lineEdit.text()}") print(f"Text in lineEdit_{idx}: {lineEdit.text()}")
text = lineEdit.text() text = lineEdit.text()
if self.checkBox_return.isChecked(): if self.checkBox_return.isChecked():
text = text + "\r\n" text = text + "\r\n"
self.data_send(text) self.data_send(text)
def onButtonDoubleClick(self, idx): def onButtonDoubleClick(self, idx):
# 槽函数处理按钮双击事件 # 槽函数处理按钮双击事件
@ -495,12 +647,9 @@ class Pyqt5Net(QtWidgets.QWidget,Ui_UartAssistant):
button.setText(new_name) button.setText(new_name)
#执行 #执行
if __name__ == '__main__': if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv) app = QtWidgets.QApplication(sys.argv)
myshow = Pyqt5Net() myshow = Pyqt5Net()
myshow.show() myshow.show()
sys.exit(app.exec_()) sys.exit(app.exec_())

View File

@ -24,8 +24,8 @@ class Ui_UartAssistant(object):
icon = QtGui.QIcon() icon = QtGui.QIcon()
icon.addPixmap(QtGui.QPixmap("favicon.ico"), QtGui.QIcon.Normal, QtGui.QIcon.Off) icon.addPixmap(QtGui.QPixmap("favicon.ico"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
UartAssistant.setWindowIcon(icon) UartAssistant.setWindowIcon(icon)
self.horizontalLayout_15 = QtWidgets.QHBoxLayout(UartAssistant) self.horizontalLayout_2 = QtWidgets.QHBoxLayout(UartAssistant)
self.horizontalLayout_15.setObjectName("horizontalLayout_15") self.horizontalLayout_2.setObjectName("horizontalLayout_2")
self.widget_7 = QtWidgets.QWidget(UartAssistant) self.widget_7 = QtWidgets.QWidget(UartAssistant)
self.widget_7.setObjectName("widget_7") self.widget_7.setObjectName("widget_7")
self.horizontalLayout_14 = QtWidgets.QHBoxLayout(self.widget_7) self.horizontalLayout_14 = QtWidgets.QHBoxLayout(self.widget_7)
@ -37,7 +37,7 @@ class Ui_UartAssistant(object):
self.splitter.setObjectName("splitter") self.splitter.setObjectName("splitter")
self.widget_4 = QtWidgets.QWidget(self.splitter) self.widget_4 = QtWidgets.QWidget(self.splitter)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(3) sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0) sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.widget_4.sizePolicy().hasHeightForWidth()) sizePolicy.setHeightForWidth(self.widget_4.sizePolicy().hasHeightForWidth())
self.widget_4.setSizePolicy(sizePolicy) self.widget_4.setSizePolicy(sizePolicy)
@ -132,10 +132,20 @@ class Ui_UartAssistant(object):
self.pushButtonLogLoad = QtWidgets.QPushButton(self.layoutWidget_6) self.pushButtonLogLoad = QtWidgets.QPushButton(self.layoutWidget_6)
self.pushButtonLogLoad.setObjectName("pushButtonLogLoad") self.pushButtonLogLoad.setObjectName("pushButtonLogLoad")
self.horizontalLayout_13.addWidget(self.pushButtonLogLoad) self.horizontalLayout_13.addWidget(self.pushButtonLogLoad)
self.checkBoxAutoSaveLog = QtWidgets.QCheckBox(self.groupBox_2) self.layoutWidget1 = QtWidgets.QWidget(self.groupBox_2)
self.checkBoxAutoSaveLog.setGeometry(QtCore.QRect(12, 103, 90, 16)) self.layoutWidget1.setGeometry(QtCore.QRect(12, 100, 191, 31))
self.layoutWidget1.setObjectName("layoutWidget1")
self.horizontalLayout_4 = QtWidgets.QHBoxLayout(self.layoutWidget1)
self.horizontalLayout_4.setContentsMargins(0, 0, 0, 0)
self.horizontalLayout_4.setObjectName("horizontalLayout_4")
self.checkBoxAutoSaveLog = QtWidgets.QCheckBox(self.layoutWidget1)
self.checkBoxAutoSaveLog.setChecked(True) self.checkBoxAutoSaveLog.setChecked(True)
self.checkBoxAutoSaveLog.setObjectName("checkBoxAutoSaveLog") self.checkBoxAutoSaveLog.setObjectName("checkBoxAutoSaveLog")
self.horizontalLayout_4.addWidget(self.checkBoxAutoSaveLog)
self.checkBoxAutoSaveCsv = QtWidgets.QCheckBox(self.layoutWidget1)
self.checkBoxAutoSaveCsv.setChecked(False)
self.checkBoxAutoSaveCsv.setObjectName("checkBoxAutoSaveCsv")
self.horizontalLayout_4.addWidget(self.checkBoxAutoSaveCsv)
self.verticalLayout_5.addWidget(self.groupBox_2) self.verticalLayout_5.addWidget(self.groupBox_2)
self.groupBox_3 = QtWidgets.QGroupBox(self.widget) self.groupBox_3 = QtWidgets.QGroupBox(self.widget)
self.groupBox_3.setMinimumSize(QtCore.QSize(0, 0)) self.groupBox_3.setMinimumSize(QtCore.QSize(0, 0))
@ -187,27 +197,58 @@ class Ui_UartAssistant(object):
self.widget_5.setSizePolicy(sizePolicy) self.widget_5.setSizePolicy(sizePolicy)
self.widget_5.setMinimumSize(QtCore.QSize(400, 0)) self.widget_5.setMinimumSize(QtCore.QSize(400, 0))
self.widget_5.setObjectName("widget_5") self.widget_5.setObjectName("widget_5")
self.horizontalLayout_9 = QtWidgets.QHBoxLayout(self.widget_5) self.verticalLayout_3 = QtWidgets.QVBoxLayout(self.widget_5)
self.horizontalLayout_9.setContentsMargins(0, 0, 0, 0) self.verticalLayout_3.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.verticalLayout_3.setObjectName("verticalLayout_3")
self.groupBox_4 = QtWidgets.QGroupBox(self.tab) self.tabWidget = QtWidgets.QTabWidget(self.widget_5)
self.groupBox_4.setObjectName("groupBox_4") self.tabWidget.setObjectName("tabWidget")
self.horizontalLayout_2 = QtWidgets.QHBoxLayout(self.groupBox_4) self.tab1 = QtWidgets.QWidget()
self.horizontalLayout_2.setObjectName("horizontalLayout_2") self.tab1.setFocusPolicy(QtCore.Qt.TabFocus)
self.textEditReceive = QtWidgets.QTextEdit(self.groupBox_4) self.tab1.setObjectName("tab1")
self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.tab1)
self.verticalLayout_2.setObjectName("verticalLayout_2")
self.textEditReceive = QtWidgets.QTextEdit(self.tab1)
self.textEditReceive.setSizeIncrement(QtCore.QSize(0, 0)) self.textEditReceive.setSizeIncrement(QtCore.QSize(0, 0))
self.textEditReceive.setObjectName("textEditReceive") self.textEditReceive.setObjectName("textEditReceive")
self.horizontalLayout_2.addWidget(self.textEditReceive) self.verticalLayout_2.addWidget(self.textEditReceive)
self.verticalLayout_3.addWidget(self.groupBox_4) self.tabWidget.addTab(self.tab1, "")
self.groupBox_7 = QtWidgets.QGroupBox(self.tab) self.tab2 = QtWidgets.QWidget()
self.tab2.setEnabled(True)
self.tab2.setFocusPolicy(QtCore.Qt.NoFocus)
self.tab2.setObjectName("tab2")
self.verticalLayout_4 = QtWidgets.QVBoxLayout(self.tab2)
self.verticalLayout_4.setObjectName("verticalLayout_4")
self.tableWidget = QtWidgets.QTableWidget(self.tab2)
self.tableWidget.setGridStyle(QtCore.Qt.SolidLine)
self.tableWidget.setRowCount(10)
self.tableWidget.setColumnCount(5)
self.tableWidget.setObjectName("tableWidget")
item = QtWidgets.QTableWidgetItem()
item.setBackground(QtGui.QColor(172, 172, 172))
self.tableWidget.setHorizontalHeaderItem(0, item)
item = QtWidgets.QTableWidgetItem()
item.setBackground(QtGui.QColor(172, 172, 172))
self.tableWidget.setHorizontalHeaderItem(1, item)
item = QtWidgets.QTableWidgetItem()
item.setBackground(QtGui.QColor(172, 172, 172))
self.tableWidget.setHorizontalHeaderItem(2, item)
item = QtWidgets.QTableWidgetItem()
self.tableWidget.setHorizontalHeaderItem(3, item)
item = QtWidgets.QTableWidgetItem()
item.setBackground(QtGui.QColor(172, 172, 172))
self.tableWidget.setHorizontalHeaderItem(4, item)
self.tableWidget.horizontalHeader().setCascadingSectionResizes(False)
self.tableWidget.horizontalHeader().setDefaultSectionSize(50)
self.tableWidget.horizontalHeader().setMinimumSectionSize(20)
self.tableWidget.horizontalHeader().setSortIndicatorShown(True)
self.tableWidget.horizontalHeader().setStretchLastSection(True)
self.tableWidget.verticalHeader().setVisible(False)
self.tableWidget.verticalHeader().setCascadingSectionResizes(False)
self.tableWidget.verticalHeader().setDefaultSectionSize(25)
self.verticalLayout_4.addWidget(self.tableWidget)
self.tabWidget.addTab(self.tab2, "")
self.verticalLayout_3.addWidget(self.tabWidget)
self.groupBox_7 = QtWidgets.QGroupBox(self.widget_5)
self.groupBox_7.setObjectName("groupBox_7") self.groupBox_7.setObjectName("groupBox_7")
self.horizontalLayout_3 = QtWidgets.QHBoxLayout(self.groupBox_7) self.horizontalLayout_3 = QtWidgets.QHBoxLayout(self.groupBox_7)
self.horizontalLayout_3.setObjectName("horizontalLayout_3") self.horizontalLayout_3.setObjectName("horizontalLayout_3")
@ -222,13 +263,33 @@ class Ui_UartAssistant(object):
self.horizontalLayout_3.setStretch(0, 8) self.horizontalLayout_3.setStretch(0, 8)
self.horizontalLayout_3.setStretch(1, 1) self.horizontalLayout_3.setStretch(1, 1)
self.verticalLayout_3.addWidget(self.groupBox_7) self.verticalLayout_3.addWidget(self.groupBox_7)
self.groupBox_5 = QtWidgets.QGroupBox(self.tab) self.groupBox_5 = QtWidgets.QGroupBox(self.widget_5)
self.groupBox_5.setObjectName("groupBox_5") self.groupBox_5.setObjectName("groupBox_5")
self.gridLayout = QtWidgets.QGridLayout(self.groupBox_5) self.gridLayout = QtWidgets.QGridLayout(self.groupBox_5)
self.gridLayout.setObjectName("gridLayout") self.gridLayout.setObjectName("gridLayout")
self.textEditSend = QtWidgets.QTextEdit(self.groupBox_5)
self.textEditSend.setObjectName("textEditSend")
self.gridLayout.addWidget(self.textEditSend, 0, 0, 3, 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.pushButtonClearReceive = QtWidgets.QPushButton(self.groupBox_5) self.pushButtonClearReceive = QtWidgets.QPushButton(self.groupBox_5)
self.pushButtonClearReceive.setObjectName("pushButtonClearReceive") self.pushButtonClearReceive.setObjectName("pushButtonClearReceive")
self.gridLayout.addWidget(self.pushButtonClearReceive, 1, 1, 1, 1) self.gridLayout.addWidget(self.pushButtonClearReceive, 1, 1, 1, 1)
self.pushButtonClearSend = QtWidgets.QPushButton(self.groupBox_5)
self.pushButtonClearSend.setObjectName("pushButtonClearSend")
self.gridLayout.addWidget(self.pushButtonClearSend, 2, 1, 2, 1)
self.widget_2 = QtWidgets.QWidget(self.groupBox_5)
self.widget_2.setObjectName("widget_2")
self.horizontalLayout_5 = QtWidgets.QHBoxLayout(self.widget_2)
self.horizontalLayout_5.setObjectName("horizontalLayout_5")
self.checkBoxSendAll = QtWidgets.QCheckBox(self.widget_2)
self.checkBoxSendAll.setObjectName("checkBoxSendAll")
self.horizontalLayout_5.addWidget(self.checkBoxSendAll)
self.checkBoxAddCRC = QtWidgets.QCheckBox(self.widget_2)
self.checkBoxAddCRC.setObjectName("checkBoxAddCRC")
self.horizontalLayout_5.addWidget(self.checkBoxAddCRC)
self.gridLayout.addWidget(self.widget_2, 3, 0, 2, 1)
self.pushButtonSend = QtWidgets.QPushButton(self.groupBox_5) self.pushButtonSend = QtWidgets.QPushButton(self.groupBox_5)
font = QtGui.QFont() font = QtGui.QFont()
font.setFamily("3ds") font.setFamily("3ds")
@ -239,22 +300,11 @@ class Ui_UartAssistant(object):
self.pushButtonSend.setCheckable(False) self.pushButtonSend.setCheckable(False)
self.pushButtonSend.setFlat(False) self.pushButtonSend.setFlat(False)
self.pushButtonSend.setObjectName("pushButtonSend") self.pushButtonSend.setObjectName("pushButtonSend")
self.gridLayout.addWidget(self.pushButtonSend, 3, 1, 1, 1) self.gridLayout.addWidget(self.pushButtonSend, 4, 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.addWidget(self.groupBox_5)
self.verticalLayout_3.setStretch(0, 6) self.verticalLayout_3.setStretch(0, 7)
self.verticalLayout_3.setStretch(1, 1) self.verticalLayout_3.setStretch(1, 1)
self.verticalLayout_3.setStretch(2, 2) self.verticalLayout_3.setStretch(2, 2)
self.tabWidget.addTab(self.tab, "")
self.horizontalLayout_9.addWidget(self.tabWidget)
self.widget_6 = QtWidgets.QWidget(self.splitter) self.widget_6 = QtWidgets.QWidget(self.splitter)
self.widget_6.setEnabled(True) self.widget_6.setEnabled(True)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
@ -273,7 +323,7 @@ class Ui_UartAssistant(object):
self.scrollArea.setWidgetResizable(False) self.scrollArea.setWidgetResizable(False)
self.scrollArea.setObjectName("scrollArea") self.scrollArea.setObjectName("scrollArea")
self.scrollAreaWidgetContents = QtWidgets.QWidget() self.scrollAreaWidgetContents = QtWidgets.QWidget()
self.scrollAreaWidgetContents.setGeometry(QtCore.QRect(0, -2388, 241, 3000)) self.scrollAreaWidgetContents.setGeometry(QtCore.QRect(0, 0, 241, 3000))
self.scrollAreaWidgetContents.setObjectName("scrollAreaWidgetContents") self.scrollAreaWidgetContents.setObjectName("scrollAreaWidgetContents")
self.widget_8 = QtWidgets.QWidget(self.scrollAreaWidgetContents) self.widget_8 = QtWidgets.QWidget(self.scrollAreaWidgetContents)
self.widget_8.setGeometry(QtCore.QRect(12, 2, 221, 34)) self.widget_8.setGeometry(QtCore.QRect(12, 2, 221, 34))
@ -291,17 +341,17 @@ class Ui_UartAssistant(object):
self.widget_9 = QtWidgets.QWidget(self.scrollAreaWidgetContents) self.widget_9 = QtWidgets.QWidget(self.scrollAreaWidgetContents)
self.widget_9.setGeometry(QtCore.QRect(10, 40, 231, 3000)) self.widget_9.setGeometry(QtCore.QRect(10, 40, 231, 3000))
self.widget_9.setObjectName("widget_9") self.widget_9.setObjectName("widget_9")
self.layoutWidget1 = QtWidgets.QWidget(self.widget_9) self.layoutWidget2 = QtWidgets.QWidget(self.widget_9)
self.layoutWidget1.setGeometry(QtCore.QRect(12, 12, 218, 2941)) self.layoutWidget2.setGeometry(QtCore.QRect(12, 12, 218, 2941))
self.layoutWidget1.setObjectName("layoutWidget1") self.layoutWidget2.setObjectName("layoutWidget2")
self.verticalLayout_8 = QtWidgets.QVBoxLayout(self.layoutWidget1) self.verticalLayout_8 = QtWidgets.QVBoxLayout(self.layoutWidget2)
self.verticalLayout_8.setSizeConstraint(QtWidgets.QLayout.SetMaximumSize) self.verticalLayout_8.setSizeConstraint(QtWidgets.QLayout.SetMaximumSize)
self.verticalLayout_8.setContentsMargins(0, 0, 0, 0) self.verticalLayout_8.setContentsMargins(0, 0, 0, 0)
self.verticalLayout_8.setObjectName("verticalLayout_8") self.verticalLayout_8.setObjectName("verticalLayout_8")
self.scrollArea.setWidget(self.scrollAreaWidgetContents) self.scrollArea.setWidget(self.scrollAreaWidgetContents)
self.horizontalLayout_16.addWidget(self.scrollArea) self.horizontalLayout_16.addWidget(self.scrollArea)
self.horizontalLayout_14.addWidget(self.splitter) self.horizontalLayout_14.addWidget(self.splitter)
self.horizontalLayout_15.addWidget(self.widget_7) self.horizontalLayout_2.addWidget(self.widget_7)
self.retranslateUi(UartAssistant) self.retranslateUi(UartAssistant)
self.comboBox_localAddr.setCurrentIndex(0) self.comboBox_localAddr.setCurrentIndex(0)
@ -330,6 +380,7 @@ class Ui_UartAssistant(object):
self.pushButtonLogSave.setText(_translate("UartAssistant", "保存日志")) self.pushButtonLogSave.setText(_translate("UartAssistant", "保存日志"))
self.pushButtonLogLoad.setText(_translate("UartAssistant", "加载日志")) self.pushButtonLogLoad.setText(_translate("UartAssistant", "加载日志"))
self.checkBoxAutoSaveLog.setText(_translate("UartAssistant", "自动保存日志")) self.checkBoxAutoSaveLog.setText(_translate("UartAssistant", "自动保存日志"))
self.checkBoxAutoSaveCsv.setText(_translate("UartAssistant", "modbus2csv"))
self.groupBox_3.setTitle(_translate("UartAssistant", "定时发送")) self.groupBox_3.setTitle(_translate("UartAssistant", "定时发送"))
self.checkBoxReapitSend.setText(_translate("UartAssistant", "定时发送")) self.checkBoxReapitSend.setText(_translate("UartAssistant", "定时发送"))
self.label_7.setText(_translate("UartAssistant", "ms/次")) self.label_7.setText(_translate("UartAssistant", "ms/次"))
@ -337,15 +388,27 @@ class Ui_UartAssistant(object):
self.label_9.setText(_translate("UartAssistant", "Rx")) self.label_9.setText(_translate("UartAssistant", "Rx"))
self.label_10.setText(_translate("UartAssistant", "Powerd by Byan")) self.label_10.setText(_translate("UartAssistant", "Powerd by Byan"))
self.label_SendNum.setText(_translate("UartAssistant", "Tx")) self.label_SendNum.setText(_translate("UartAssistant", "Tx"))
self.groupBox_4.setTitle(_translate("UartAssistant", "数据接收区")) self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab1), _translate("UartAssistant", "数据"))
item = self.tableWidget.horizontalHeaderItem(0)
item.setText(_translate("UartAssistant", "select"))
item = self.tableWidget.horizontalHeaderItem(1)
item.setText(_translate("UartAssistant", "start"))
item = self.tableWidget.horizontalHeaderItem(2)
item.setText(_translate("UartAssistant", "num"))
item = self.tableWidget.horizontalHeaderItem(3)
item.setText(_translate("UartAssistant", "scale"))
item = self.tableWidget.horizontalHeaderItem(4)
item.setText(_translate("UartAssistant", "value"))
self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab2), _translate("UartAssistant", "解析"))
self.groupBox_7.setTitle(_translate("UartAssistant", "选择通道")) self.groupBox_7.setTitle(_translate("UartAssistant", "选择通道"))
self.comboBox_channel.setItemText(0, _translate("UartAssistant", "ALL")) self.comboBox_channel.setItemText(0, _translate("UartAssistant", "ALL"))
self.pushButtonClearChannel.setText(_translate("UartAssistant", "清空")) self.pushButtonClearChannel.setText(_translate("UartAssistant", "清空"))
self.groupBox_5.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.pushButton_expend.setText(_translate("UartAssistant", "快捷指令"))
self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab), _translate("UartAssistant", "数据")) self.pushButtonClearReceive.setText(_translate("UartAssistant", "清除接收"))
self.pushButtonClearSend.setText(_translate("UartAssistant", "清除发送"))
self.checkBoxSendAll.setText(_translate("UartAssistant", "发送全部通道"))
self.checkBoxAddCRC.setText(_translate("UartAssistant", "附加校验"))
self.pushButtonSend.setText(_translate("UartAssistant", "发送"))
self.label_8.setText(_translate("UartAssistant", "快捷指令")) self.label_8.setText(_translate("UartAssistant", "快捷指令"))
self.checkBox_return.setText(_translate("UartAssistant", "添加\"\\r\\n\"")) self.checkBox_return.setText(_translate("UartAssistant", "添加\"\\r\\n\""))

View File

@ -26,7 +26,7 @@
<iconset> <iconset>
<normaloff>favicon.ico</normaloff>favicon.ico</iconset> <normaloff>favicon.ico</normaloff>favicon.ico</iconset>
</property> </property>
<layout class="QHBoxLayout" name="horizontalLayout_15"> <layout class="QHBoxLayout" name="horizontalLayout_2">
<item> <item>
<widget class="QWidget" name="widget_7" native="true"> <widget class="QWidget" name="widget_7" native="true">
<layout class="QHBoxLayout" name="horizontalLayout_14" stretch="0"> <layout class="QHBoxLayout" name="horizontalLayout_14" stretch="0">
@ -47,7 +47,7 @@
<widget class="QWidget" name="widget_4" native="true"> <widget class="QWidget" name="widget_4" native="true">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred"> <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>3</horstretch> <horstretch>0</horstretch>
<verstretch>0</verstretch> <verstretch>0</verstretch>
</sizepolicy> </sizepolicy>
</property> </property>
@ -278,21 +278,37 @@
</item> </item>
</layout> </layout>
</widget> </widget>
<widget class="QCheckBox" name="checkBoxAutoSaveLog"> <widget class="QWidget" name="layoutWidget">
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>12</x> <x>12</x>
<y>103</y> <y>100</y>
<width>90</width> <width>191</width>
<height>16</height> <height>31</height>
</rect> </rect>
</property> </property>
<property name="text"> <layout class="QHBoxLayout" name="horizontalLayout_4">
<string>自动保存日志</string> <item>
</property> <widget class="QCheckBox" name="checkBoxAutoSaveLog">
<property name="checked"> <property name="text">
<bool>true</bool> <string>自动保存日志</string>
</property> </property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="checkBoxAutoSaveCsv">
<property name="text">
<string>modbus2csv</string>
</property>
<property name="checked">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</widget> </widget>
</widget> </widget>
</item> </item>
@ -463,139 +479,251 @@
<height>0</height> <height>0</height>
</size> </size>
</property> </property>
<layout class="QHBoxLayout" name="horizontalLayout_9"> <layout class="QVBoxLayout" name="verticalLayout_3" stretch="7,1,2">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item> <item>
<widget class="QTabWidget" name="tabWidget"> <widget class="QTabWidget" name="tabWidget">
<property name="mouseTracking">
<bool>false</bool>
</property>
<property name="currentIndex"> <property name="currentIndex">
<number>0</number> <number>0</number>
</property> </property>
<widget class="QWidget" name="tab"> <widget class="QWidget" name="tab1">
<property name="focusPolicy">
<enum>Qt::TabFocus</enum>
</property>
<attribute name="title"> <attribute name="title">
<string>数据</string> <string>数据</string>
</attribute> </attribute>
<layout class="QVBoxLayout" name="verticalLayout_3" stretch="6,1,2"> <layout class="QVBoxLayout" name="verticalLayout_2">
<item> <item>
<widget class="QGroupBox" name="groupBox_4"> <widget class="QPlainTextEdit" name="plainTextEditReceive">
<property name="title"> <property name="sizeIncrement">
<string>数据接收区</string> <size>
<width>0</width>
<height>0</height>
</size>
</property> </property>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QTextEdit" name="textEditReceive">
<property name="sizeIncrement">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_7">
<property name="title">
<string>选择通道</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_3" stretch="8,1">
<item>
<widget class="QComboBox" name="comboBox_channel">
<property name="editable">
<bool>true</bool>
</property>
<item>
<property name="text">
<string>ALL</string>
</property>
</item>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButtonClearChannel">
<property name="text">
<string>清空</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_5">
<property name="title">
<string>数据发送区</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="1" column="1">
<widget class="QPushButton" name="pushButtonClearReceive">
<property name="text">
<string>清除接收</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QPushButton" name="pushButtonSend">
<property name="font">
<font>
<family>3ds</family>
<pointsize>12</pointsize>
</font>
</property>
<property name="autoFillBackground">
<bool>false</bool>
</property>
<property name="styleSheet">
<string notr="true">background-color: rgb(0, 255, 0);</string>
</property>
<property name="text">
<string>发送</string>
</property>
<property name="checkable">
<bool>false</bool>
</property>
<property name="flat">
<bool>false</bool>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QPushButton" name="pushButtonClearSend">
<property name="text">
<string>清除发送</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QPushButton" name="pushButton_expend">
<property name="text">
<string>快捷指令</string>
</property>
</widget>
</item>
<item row="0" column="0" rowspan="4">
<widget class="QTextEdit" name="textEditSend"/>
</item>
</layout>
</widget> </widget>
</item> </item>
</layout> </layout>
</widget> </widget>
<widget class="QWidget" name="tab2">
<property name="enabled">
<bool>true</bool>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<attribute name="title">
<string>解析</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<widget class="QTableWidget" name="tableWidget">
<property name="gridStyle">
<enum>Qt::SolidLine</enum>
</property>
<property name="rowCount">
<number>10</number>
</property>
<property name="columnCount">
<number>5</number>
</property>
<attribute name="horizontalHeaderCascadingSectionResizes">
<bool>false</bool>
</attribute>
<attribute name="horizontalHeaderMinimumSectionSize">
<number>20</number>
</attribute>
<attribute name="horizontalHeaderDefaultSectionSize">
<number>50</number>
</attribute>
<attribute name="horizontalHeaderShowSortIndicator" stdset="0">
<bool>true</bool>
</attribute>
<attribute name="horizontalHeaderStretchLastSection">
<bool>true</bool>
</attribute>
<attribute name="verticalHeaderVisible">
<bool>false</bool>
</attribute>
<attribute name="verticalHeaderCascadingSectionResizes">
<bool>false</bool>
</attribute>
<attribute name="verticalHeaderDefaultSectionSize">
<number>25</number>
</attribute>
<row/>
<row/>
<row/>
<row/>
<row/>
<row/>
<row/>
<row/>
<row/>
<row/>
<column>
<property name="text">
<string>select</string>
</property>
<property name="background">
<color>
<red>172</red>
<green>172</green>
<blue>172</blue>
</color>
</property>
</column>
<column>
<property name="text">
<string>start</string>
</property>
<property name="background">
<color>
<red>172</red>
<green>172</green>
<blue>172</blue>
</color>
</property>
</column>
<column>
<property name="text">
<string>num</string>
</property>
<property name="background">
<color>
<red>172</red>
<green>172</green>
<blue>172</blue>
</color>
</property>
</column>
<column>
<property name="text">
<string>scale</string>
</property>
</column>
<column>
<property name="text">
<string>value</string>
</property>
<property name="background">
<color>
<red>172</red>
<green>172</green>
<blue>172</blue>
</color>
</property>
</column>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_7">
<property name="title">
<string>选择通道</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_3" stretch="8,1">
<item>
<widget class="QComboBox" name="comboBox_channel">
<property name="editable">
<bool>true</bool>
</property>
<item>
<property name="text">
<string>ALL</string>
</property>
</item>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButtonClearChannel">
<property name="text">
<string>清空</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_5">
<property name="title">
<string>数据发送区</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0" rowspan="3">
<widget class="QTextEdit" name="textEditSend"/>
</item>
<item row="0" column="1">
<widget class="QPushButton" name="pushButton_expend">
<property name="text">
<string>快捷指令</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QPushButton" name="pushButtonClearReceive">
<property name="text">
<string>清除接收</string>
</property>
</widget>
</item>
<item row="2" column="1" rowspan="2">
<widget class="QPushButton" name="pushButtonClearSend">
<property name="text">
<string>清除发送</string>
</property>
</widget>
</item>
<item row="3" column="0" rowspan="2">
<widget class="QWidget" name="widget_2" native="true">
<layout class="QHBoxLayout" name="horizontalLayout_5">
<item>
<widget class="QCheckBox" name="checkBoxSendAll">
<property name="text">
<string>发送全部通道</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="checkBoxAddCRC">
<property name="text">
<string>附加校验</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="4" column="1">
<widget class="QPushButton" name="pushButtonSend">
<property name="font">
<font>
<family>3ds</family>
<pointsize>12</pointsize>
</font>
</property>
<property name="autoFillBackground">
<bool>false</bool>
</property>
<property name="styleSheet">
<string notr="true">background-color: rgb(0, 255, 0);</string>
</property>
<property name="text">
<string>发送</string>
</property>
<property name="checkable">
<bool>false</bool>
</property>
<property name="flat">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</widget> </widget>
</item> </item>
</layout> </layout>
@ -644,7 +772,7 @@
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>0</x> <x>0</x>
<y>-2388</y> <y>0</y>
<width>241</width> <width>241</width>
<height>3000</height> <height>3000</height>
</rect> </rect>

File diff suppressed because it is too large Load Diff

View File

@ -1,347 +0,0 @@
# -*- coding: utf-8 -*-
"""
Created on Tue May 28 15:40:48 2024
@author: WANGXIBAO
"""
# -*- coding: utf-8 -*-
import time,math,os
import re,csv,datetime
from PyQt5.QtCore import QThread, pyqtSignal
from PyQt5.QtWidgets import QMessageBox
from PyQt5.QtGui import QPen
from configparser import ConfigParser
# 波形显示
# 使用线程不断更新波形数据
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.getDateQx = GetDataQX()
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 GetDataQX(): #读取请芯数据
def __init__(self, parent=None):
super().__init__()
self.indOfReturn =0
self.regexQx = re.compile(r'(A\+|B\+|\s)+') # 编译正则表达式
self.TIME_FORMAT = "%Y-%m-%d %H:%M:%S"
def Transdata(self,data):
parts = re.split(self.regexQx,data)
# 过滤掉空字符串
parts = [part for part in parts if part]
#print(parts)
methane = float(parts[1])
airTemp = float(parts[3])
laserTemp = float( parts[5])/1
laerIntensity = float(parts[7])*10
timeCrvt=time.strftime(self.TIME_FORMAT, time.localtime())
self.data2csv =[(timeCrvt,methane,airTemp,laserTemp,laerIntensity)]
#print(self.data2csv)
if self.indOfReturn == 0:
returnData = methane
elif self.indOfReturn == 1:
returnData = airTemp
elif self.indOfReturn == 2:
returnData = laserTemp
elif self.indOfReturn == 3:
returnData = laerIntensity
print(returnData)
return returnData
def SaveCsv(self,filenameCsv):
# 打开一个文件用于写入,如果文件不存在则创建
if os.path.isfile(filenameCsv) == 0:
# 文件为空,需要写入表头
with open(filenameCsv, mode='w', newline='') as file:
writer = csv.writer(file)
writer.writerow(('time', 'Methane', 'Air Temp', 'Laser Temp', 'Laser Intensity'))
else:
with open(filenameCsv, mode='a', newline='') as file:
# 创建一个写入器对象
writer = csv.writer(file)
# 写入数据行
writer.writerows(self.data2csv)
def IndOfReturn(self,ind):
self.indOfReturn = ind
class GetDataTF(): #读取费加罗或者自定义数据
def __init__(self, parent=None):
super().__init__()
self.indOfReturn =0
#self.regex = re.compile(r'(A\+|B\+|\s)+') # 编译正则表达式
self.TIME_FORMAT = "%Y-%m-%d %H:%M:%S"
self.regularIniPath = "regular.ini" # 配置文件默认路径
self.headStr = ""
self.rowTitle=[]
self.buttons_config = [[None for _ in range(3)] for _ in range(20)]
#存放快捷按键配置
self.CheckCfgIniData() # 初始化配置文件
def Transdata(self,data):
if data[:2] ==self.headStr:
# parts = re.split(self.regex,data)
# # 过滤掉空字符串
# parts = [part for part in parts if part]
#print(parts)
# methane = float(parts[1])
# airTemp = float(parts[3])
# laserTemp = float( parts[5])/1
# laerIntensity = float(parts[7])*10
# self.data2csv =[(timeCrvt,methane,airTemp,laserTemp,laerIntensity)]
self.data2csv = self.regex.findall(data)
#print(self.data2csv)
# if self.indOfReturn == 0:
# returnData = methane
# elif self.indOfReturn == 1:
# returnData = airTemp
# elif self.indOfReturn == 2:
# returnData = laserTemp
# elif self.indOfReturn == 3:
# returnData = laerIntensity
returnData = float(self.data2csv[self.indOfReturn])
print("returnData",returnData)
return returnData
else:
return "noNum"
def SaveCsv(self,filenameCsv):
# 打开一个文件用于写入,如果文件不存在则创建
if os.path.isfile(filenameCsv) == 0:
# 文件为空,需要写入表头
with open(filenameCsv, mode='w', newline='') as file:
writer = csv.writer(file)
#writer.writerow(('time', 'Methane', 'Air Temp', 'Laser Temp', 'Laser Intensity'))
writer.writerow(self.rowTitle)
else:
with open(filenameCsv, mode='a', newline='') as file:
# 创建一个写入器对象
writer = csv.writer(file)
# 写入数据行
timeCrvt=time.strftime(self.TIME_FORMAT, time.localtime())
self.data2csv.insert(0, timeCrvt)
print(self.data2csv)
writer.writerows([self.data2csv])
def IndOfReturn(self,ind):
self.indOfReturn = ind
def CheckCfgIniData(self):
if not os.path.exists(self.regularIniPath):
config = ConfigParser()
config.add_section('TF_config')
config.set('TF_config', 'regular', '\+?-?\d+(?:\.\d+)?')
#config.set('TF_config', 'regular', '(A\+|B\+|\s)+')
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('Quick_config')
config.set('Quick_config', 'Button00', 'write 0,2024100101|序列号')
config.set('Quick_config', 'Button01', 'write 1,65000|激光温度')
config.set('Quick_config', 'Button02', 'write 2,1000|K*1000')
config.set('Quick_config', 'Button03', 'write 3,0|B*1000')
config.set('Quick_config', 'Button04', 'write 4,0|可调电阻')
config.set('Quick_config', 'Button05', 'write 5,30|电阻抽头')
config.set('Quick_config', 'Button06', 'write 6,0|输出温度')
config.set('Quick_config', 'Button07', 'write 7,0|输出激光')
config.set('Quick_config', 'Button08', 'write 8,1|输出状态')
config.set('Quick_config', 'Button09', 'write 9,0|激光温补')
config.set('Quick_config', 'Button10', 'write 10,100|噪声长度')
config.set('Quick_config', 'Button11', 'write 11,600|扫描长度')
config.set('Quick_config', 'Button12', '')
config.set('Quick_config', 'Button13', 'write 13,30500|气温校准')
config.set('Quick_config', 'Button14', 'write 14,1|滑动开关')
config.set('Quick_config', 'Button15', 'write 15,10|滑动标准差')
config.set('Quick_config', 'Button16', 'write 16,1|浓度温补')
config.set('Quick_config', 'Button17', '')
config.set('Quick_config', 'Button18', '')
config.set('Quick_config', 'Button19', '')
with open(self.regularIniPath, 'w' ,encoding='utf-8') as f:
config.write(f)
config = ConfigParser()
config.read(self.regularIniPath, encoding='utf-8')
try:
self.headStr = config.get('TF_config', 'headStr')
self.regex = re.compile(config.get('TF_config', 'regular'))
self.rowTitleStr = config.get('TF_config', 'rowTitle')
self.rowTitle = self.rowTitleStr.split(',')
print(type(self.rowTitle))
print(f"Configuration read successfully: {self.headStr}, {self.regex}, {self.rowTitle}")
# 创建一个空字典来存储按钮名称和对应的配置
# 循环遍历按钮编号从0到19
for i in range(20):
button_name = f'Button{i:02}' # 格式化按钮名称,确保两位数
# 使用 get 方法安全地获取配置,如果不存在则返回空字符串
config_value = config.get('Quick_config', button_name, fallback='')
config_value_split = config_value.split('|')
# 将按钮名称和配置信息存储在字典中
self.buttons_config[i][0] = button_name
if len(config_value_split) == 2:
self.buttons_config[i][1] = config_value_split[0]
self.buttons_config[i][2] = config_value_split[1]
# 打印字典查看结果
for i in range(20):
print(f'{self.buttons_config[i][0]}: {self.buttons_config[i][1]}|{self.buttons_config[i][2]}')
except Exception as e:
print(f"Error reading configuration: {e}")
def SetCfgIniData(self,button_name,set_text):
config = ConfigParser()
config.read(self.regularIniPath, encoding='utf-8')
config.set('Quick_config', button_name, set_text)
with open(self.regularIniPath, 'w' ,encoding='utf-8') as f:
config.write(f)
class GetDataOther(): #读取费加罗或者自定义数据
def __init__(self, parent=None):
super().__init__()
self.indOfReturn =0
#self.regex = re.compile(r'(A\+|B\+|\s)+') # 编译正则表达式
self.TIME_FORMAT = "%Y-%m-%d %H:%M:%S"
self.OtherIniPath = "OtherData.ini" # 配置文件默认路径
self.headStr = ""
self.rowTitle=[]
self.CheckCfgIniData() # 初始化配置文件
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):
# 打开一个文件用于写入,如果文件不存在则创建
if os.path.isfile(filenameCsv) == 0:
# 文件为空,需要写入表头
with open(filenameCsv, mode='w', newline='') as file:
writer = csv.writer(file)
#writer.writerow(('time', 'Methane', 'Air Temp', 'Laser Temp', 'Laser Intensity'))
writer.writerow(self.rowTitle)
else:
with open(filenameCsv, mode='a', newline='') as file:
# 创建一个写入器对象
writer = csv.writer(file)
# 写入数据行
timeCrvt=time.strftime(self.TIME_FORMAT, time.localtime())
self.data2csv.insert(0, timeCrvt)
print(self.data2csv)
writer.writerows([self.data2csv])
def IndOfReturn(self,ind):
self.indOfReturn = ind
def CheckCfgIniData(self):
if not os.path.exists(self.OtherIniPath):
config = ConfigParser()
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')
with open(self.OtherIniPath, 'w') as f:
config.write(f)
config = ConfigParser()
config.read(self.OtherIniPath, encoding='utf-8')
try:
self.headStr = config.get('OtherData_config', 'headStr')
self.regex = re.compile(config.get('OtherData_config', 'regular'))
self.rowTitleStr = config.get('OtherData_config', 'rowTitle')
self.rowTitle = self.rowTitleStr.split(',')
print(type(self.rowTitle))
print(f"Configuration read successfully: {self.headStr}, {self.regex}, {self.rowTitle}")
except Exception as e:
print(f"Error reading configuration: {e}")