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