367 lines
14 KiB
Python
367 lines
14 KiB
Python
from ui_arr_details import Ui_Widget
|
||
from PySide6.QtWidgets import QWidget, QTableWidgetItem
|
||
from PySide6.QtCore import Slot, Signal, SignalInstance
|
||
from param_data import ParamDataArr
|
||
from br_com_message import BrComMessage
|
||
from br_widget_basic_plot import BrWidgetBasicPlot
|
||
|
||
class BrWidgetArrDetails(QWidget, Ui_Widget):
|
||
signal_read: SignalInstance = Signal(list)
|
||
signal_write: SignalInstance = Signal(list)
|
||
signal_stop: SignalInstance = Signal()
|
||
|
||
def __init__(self, parent=None):
|
||
super().__init__(parent)
|
||
self.setupUi(self)
|
||
self.param_data: ParamDataArr = None
|
||
self.is_reading = False
|
||
self.is_writing = False
|
||
self.read_count = 0 # 读取计数器
|
||
self.total_read_count = 0 # 总读取数量
|
||
self.write_count = 0 # 写入计数器
|
||
self.total_write_count = 0 # 总写入数量
|
||
self.processed_read_addresses = set() # 已处理的读取地址
|
||
self.processed_write_addresses = set() # 已处理的写入地址
|
||
|
||
# 初始化按钮状态
|
||
self.pushButton_read.setEnabled(True)
|
||
self.pushButton_write.setEnabled(True)
|
||
self.pushButton_read_stop.setEnabled(False)
|
||
self.pushButton_write_stop.setEnabled(False)
|
||
|
||
self.updating = False
|
||
self.tableWidget_val.setColumnCount(2)
|
||
self.tableWidget_val.setHorizontalHeaderLabels(['Addr', 'Value'])
|
||
|
||
self.tableWidget_setval.setColumnCount(2)
|
||
self.tableWidget_setval.setHorizontalHeaderLabels(['Addr', 'Value'])
|
||
|
||
self.tableWidget_setval.itemChanged.connect(self.on_table_setval_itemChanged)
|
||
|
||
self.pushButton_read_stop.clicked.connect(self.on_pushButton_read_stop_clicked)
|
||
self.pushButton_write_stop.clicked.connect(self.on_pushButton_write_stop_clicked)
|
||
|
||
def on_table_setval_itemChanged(self, item: QTableWidgetItem):
|
||
if self.updating:
|
||
return
|
||
# 获取编辑的行index,获取输入的值
|
||
row_index = item.row()
|
||
input_val = item.text()
|
||
self.param_data.setval_list[row_index] = float(input_val)
|
||
print('item changed', row_index, input_val)
|
||
|
||
|
||
def update_param_info(self, p_data: ParamDataArr):
|
||
self.param_data = p_data
|
||
self.label_addr.setText(str(p_data.addr))
|
||
self.label_name.setText(str(p_data.name))
|
||
self.label_length.setText(str(p_data.size))
|
||
self.label_details.setText(str(p_data.details))
|
||
self.update_table()
|
||
|
||
def update_table(self):
|
||
self.updating = True
|
||
self.tableWidget_val.setRowCount(self.param_data.size)
|
||
for row in range(0, self.param_data.size):
|
||
self.tableWidget_val.setItem(
|
||
row, 0, QTableWidgetItem(
|
||
str(self.param_data.addr + row)
|
||
)
|
||
)
|
||
self.tableWidget_val.setItem(
|
||
row, 1, QTableWidgetItem(
|
||
str(self.param_data.getval_list[row]))
|
||
)
|
||
|
||
self.tableWidget_setval.setRowCount(self.param_data.size)
|
||
# 增加table写功能
|
||
for row in range(0, self.param_data.size):
|
||
self.tableWidget_setval.setItem(
|
||
row, 0, QTableWidgetItem(
|
||
str(self.param_data.addr + row)
|
||
)
|
||
)
|
||
self.tableWidget_setval.setItem(
|
||
row, 1, QTableWidgetItem(
|
||
str(self.param_data.getval_list[row]))
|
||
)
|
||
|
||
# 把设定值设置为获取到的值
|
||
self.param_data.setval_list = self.param_data.getval_list
|
||
self.updating = False
|
||
|
||
def update_val_list(self):
|
||
|
||
for i in range(0, self.param_data.size):
|
||
self.tableWidget_val.setItem(0, i, QTableWidgetItem(str(self.param_data.getval_list[i])))
|
||
|
||
def update_setval_list(self):
|
||
for i in range(0, len(self.param_data.setval_list)):
|
||
self.tableWidget_setval.setItem(0, i, QTableWidgetItem(str(self.param_data.setval_list[i])))
|
||
|
||
def reset_read_state(self):
|
||
"""重置读取状态"""
|
||
print('Resetting read state')
|
||
self.is_reading = False
|
||
self.read_count = 0
|
||
self.total_read_count = 0
|
||
self.processed_read_addresses.clear()
|
||
self.pushButton_read.setEnabled(True)
|
||
self.pushButton_write.setEnabled(True)
|
||
self.pushButton_read_stop.setEnabled(False)
|
||
self.pushButton_write_stop.setEnabled(False)
|
||
|
||
def reset_write_state(self):
|
||
"""重置写入状态"""
|
||
print('Resetting write state')
|
||
self.is_writing = False
|
||
self.write_count = 0
|
||
self.total_write_count = 0
|
||
self.processed_write_addresses.clear()
|
||
self.pushButton_write.setEnabled(True)
|
||
self.pushButton_read.setEnabled(True)
|
||
self.pushButton_write_stop.setEnabled(False)
|
||
self.pushButton_read_stop.setEnabled(False)
|
||
|
||
@Slot()
|
||
def on_pushButton_read_clicked(self):
|
||
print('[read] button clicked!')
|
||
print(f'Starting read operation for array size: {self.param_data.size}')
|
||
# 确保之前的状态被清理
|
||
self.reset_read_state()
|
||
self.reset_write_state()
|
||
|
||
# 设置新的读取状态
|
||
self.is_reading = True
|
||
self.read_count = 0
|
||
self.total_read_count = self.param_data.size
|
||
|
||
# 设置按钮状态
|
||
self.pushButton_read.setEnabled(False)
|
||
self.pushButton_write.setEnabled(False)
|
||
self.pushButton_read_stop.setEnabled(True)
|
||
self.pushButton_write_stop.setEnabled(False)
|
||
|
||
# 生成一组读取命令
|
||
_cmd_list = []
|
||
print(f'Expected addresses to read: ', end='')
|
||
for i in range(0, self.param_data.size):
|
||
addr = self.param_data.addr + i
|
||
_cmd_list.append(
|
||
BrComMessage(
|
||
BrComMessage.OP_READ,
|
||
addr
|
||
)
|
||
)
|
||
print(f'{addr} ', end='')
|
||
print() # 换行
|
||
print(f'Initialized read operation: count={self.read_count}, total={self.total_read_count}')
|
||
self.signal_read.emit(_cmd_list)
|
||
|
||
@Slot()
|
||
def on_pushButton_write_clicked(self):
|
||
print('[write] button clicked!')
|
||
# 确保之前的状态被清理
|
||
self.reset_read_state()
|
||
self.reset_write_state()
|
||
|
||
# 设置新的写入状态
|
||
self.is_writing = True
|
||
self.write_count = 0
|
||
self.total_write_count = self.param_data.size
|
||
|
||
# 设置按钮状态
|
||
self.pushButton_write.setEnabled(False)
|
||
self.pushButton_read.setEnabled(False)
|
||
self.pushButton_write_stop.setEnabled(True)
|
||
self.pushButton_read_stop.setEnabled(False)
|
||
|
||
print(f'Initialized write operation: count={self.write_count}, total={self.total_write_count}')
|
||
|
||
_cmd_list = []
|
||
for i in range(0, self.param_data.size):
|
||
_cmd_list.append(
|
||
BrComMessage(
|
||
BrComMessage.OP_WRITE,
|
||
self.param_data.addr + i,
|
||
self.param_data.getval_list[i]
|
||
)
|
||
)
|
||
self.signal_write.emit(_cmd_list)
|
||
|
||
@Slot()
|
||
def on_pushButton_read_stop_clicked(self):
|
||
print('[read stop] button clicked!')
|
||
self.reset_read_state()
|
||
self.signal_stop.emit()
|
||
|
||
@Slot()
|
||
def on_pushButton_write_stop_clicked(self):
|
||
print('[write stop] button clicked!')
|
||
self.reset_write_state()
|
||
self.signal_stop.emit()
|
||
|
||
def operation_completed(self):
|
||
"""操作完成时调用此方法"""
|
||
if self.is_reading:
|
||
self.reset_read_state()
|
||
if self.is_writing:
|
||
self.reset_write_state()
|
||
|
||
@Slot()
|
||
def on_pushButton_valplot_clicked(self):
|
||
print('[valpolt] button clicked!')
|
||
self.dialog = BrWidgetBasicPlot()
|
||
self.dialog.set_chart_data(self.param_data.getval_list, self.param_data.name)
|
||
self.dialog.show()
|
||
|
||
|
||
@Slot()
|
||
def on_pushButton_setvalplot_clicked(self):
|
||
print('[setvalplot] button clicked!')
|
||
|
||
def resend_missing_read_commands(self):
|
||
"""重新发送未处理地址的读取命令"""
|
||
if not self.is_reading:
|
||
return
|
||
|
||
array_start = self.param_data.addr
|
||
array_end = self.param_data.addr + self.param_data.size
|
||
expected_addresses = set(range(array_start, array_end))
|
||
missing_addresses = expected_addresses - self.processed_read_addresses
|
||
|
||
if missing_addresses:
|
||
print(f'Resending read commands for missing addresses: {sorted(missing_addresses)}')
|
||
_cmd_list = []
|
||
for addr in sorted(missing_addresses):
|
||
_cmd_list.append(
|
||
BrComMessage(
|
||
BrComMessage.OP_READ,
|
||
addr
|
||
)
|
||
)
|
||
self.signal_read.emit(_cmd_list)
|
||
return True
|
||
return False
|
||
|
||
def check_read_complete(self, addr):
|
||
"""检查读取是否完成"""
|
||
print(f'Checking completion for addr: {addr}')
|
||
if not self.is_reading:
|
||
print(f'Not in reading state, ignoring addr: {addr}')
|
||
return
|
||
|
||
# 检查地址是否在当前数组范围内
|
||
array_start = self.param_data.addr
|
||
array_end = self.param_data.addr + self.param_data.size
|
||
print(f'Array range: {array_start} to {array_end-1}, checking addr: {addr}')
|
||
|
||
if array_start <= addr < array_end and addr not in self.processed_read_addresses:
|
||
self.processed_read_addresses.add(addr)
|
||
self.read_count += 1
|
||
print(f'Valid address {addr}, incrementing counter. Progress: {self.read_count}/{self.total_read_count}')
|
||
|
||
# 找出未处理的地址
|
||
expected_addresses = set(range(array_start, array_end))
|
||
missing_addresses = expected_addresses - self.processed_read_addresses
|
||
print(f'Missing addresses: {sorted(missing_addresses)}')
|
||
|
||
# 如果有未处理的地址且已经读取了一定数量(比如80%)的地址,尝试重发
|
||
if missing_addresses and self.read_count >= self.total_read_count * 0.8:
|
||
print(f'Detected missing addresses at {self.read_count}/{self.total_read_count}, attempting retry')
|
||
if self.resend_missing_read_commands():
|
||
print('Resent read commands for missing addresses')
|
||
return
|
||
|
||
# 如果已经读取了预期数量的地址
|
||
if self.read_count >= self.total_read_count:
|
||
if not missing_addresses:
|
||
print(f'All data read (count={self.read_count}), completing operation')
|
||
self.reset_read_state()
|
||
self.signal_stop.emit()
|
||
print('Read operation fully completed')
|
||
else:
|
||
if addr in self.processed_read_addresses:
|
||
print(f'Address {addr} already processed')
|
||
else:
|
||
print(f'Address {addr} outside current array range ({array_start}-{array_end-1})')
|
||
|
||
def resend_missing_write_commands(self):
|
||
"""重新发送未处理地址的写入命令"""
|
||
if not self.is_writing:
|
||
return
|
||
|
||
array_start = self.param_data.addr
|
||
array_end = self.param_data.addr + self.param_data.size
|
||
expected_addresses = set(range(array_start, array_end))
|
||
missing_addresses = expected_addresses - self.processed_write_addresses
|
||
|
||
if missing_addresses:
|
||
print(f'Resending write commands for missing addresses: {sorted(missing_addresses)}')
|
||
_cmd_list = []
|
||
for addr in sorted(missing_addresses):
|
||
_cmd_list.append(
|
||
BrComMessage(
|
||
BrComMessage.OP_WRITE,
|
||
addr,
|
||
self.param_data.getval_list[addr - array_start]
|
||
)
|
||
)
|
||
self.signal_write.emit(_cmd_list)
|
||
return True
|
||
return False
|
||
|
||
def check_write_complete(self, addr):
|
||
"""检查写入是否完成"""
|
||
print(f'Checking completion for addr: {addr}')
|
||
if not self.is_writing:
|
||
print(f'Not in writing state, ignoring addr: {addr}')
|
||
return
|
||
|
||
# 检查地址是否在当前数组范围内
|
||
array_start = self.param_data.addr
|
||
array_end = self.param_data.addr + self.param_data.size
|
||
print(f'Array range: {array_start} to {array_end-1}, checking addr: {addr}')
|
||
|
||
if array_start <= addr < array_end and addr not in self.processed_write_addresses:
|
||
self.processed_write_addresses.add(addr)
|
||
self.write_count += 1
|
||
print(f'Valid address {addr}, incrementing counter. Progress: {self.write_count}/{self.total_write_count}')
|
||
|
||
# 找出未处理的地址
|
||
expected_addresses = set(range(array_start, array_end))
|
||
missing_addresses = expected_addresses - self.processed_write_addresses
|
||
print(f'Missing addresses: {sorted(missing_addresses)}')
|
||
|
||
# 如果有未处理的地址且已经写入了一定数量(比如80%)的地址,尝试重发
|
||
if missing_addresses and self.write_count >= self.total_write_count * 0.8:
|
||
print(f'Detected missing addresses at {self.write_count}/{self.total_write_count}, attempting retry')
|
||
if self.resend_missing_write_commands():
|
||
print('Resent write commands for missing addresses')
|
||
return
|
||
|
||
# 如果已经写入了预期数量的地址
|
||
if self.write_count >= self.total_write_count:
|
||
if not missing_addresses:
|
||
print(f'All data written (count={self.write_count}), completing operation')
|
||
self.reset_write_state()
|
||
self.signal_stop.emit()
|
||
print('Write operation fully completed')
|
||
else:
|
||
if addr in self.processed_write_addresses:
|
||
print(f'Address {addr} already processed')
|
||
else:
|
||
print(f'Address {addr} outside current array range ({array_start}-{array_end-1})')
|
||
|
||
if __name__ == "__main__":
|
||
from PySide6.QtWidgets import QApplication
|
||
import sys
|
||
app = QApplication()
|
||
widget = BrWidgetArrDetails()
|
||
param_data = ParamDataArr(10, 'name', 'NULL', 0, 10)
|
||
widget.update_param_info(param_data)
|
||
widget.update_val_list()
|
||
widget.update_setval_list()
|
||
widget.show()
|
||
sys.exit(app.exec())
|