diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/core/serial_protocol.py b/core/serial_protocol.py index eb28872..641e0f7 100644 --- a/core/serial_protocol.py +++ b/core/serial_protocol.py @@ -22,6 +22,20 @@ class SerialProtocol: ] return bytes(cmd_bytes) + def cancel_all(self): + """ + 取消所有窗口选定 + """ + # 根据你的协议文档,这里填入真实的十六进制指令 + # 示例: [Head, Cmd, Data...] -> bytes + cmd_bytes = [ + 0x80, # HEAD (假设) + 0x74, # CMD (接命令) + 0x46, # 起始位置 + 0xFF, 0xFF, 0xFF, 0xFF # 填充位 (根据协议长度补齐) + ] + return bytes(cmd_bytes) + def power_on_all(self): """所有屏幕开机指令""" # 根据你的协议文档,这里填入真实的十六进制指令 @@ -94,12 +108,9 @@ class SerialProtocol: start_id = min_row * 4 + min_col + 1 # 转回物理ID start_param = start_id - 1 # 协议参数:PanelNumber - 1 - # Hcount (水平个数), Vcount (垂直个数) - Hcount = max_col - min_col + 1 - Vcount = max_row - min_row + 1 - - - BigPicID = 1 + # h_count (水平个数), Vcount (垂直个数) + h_count = max_col - min_col + 1 + v_count = max_row - min_row + 1 # --- 第四步:逻辑校验 --- # 检查这个矩形区域内是否有未被选中的屏幕(缺角情况) @@ -112,47 +123,53 @@ class SerialProtocol: return { "start": start_param, - "Hcount": Hcount, - "Vcount": Vcount, - "BigPicID": BigPicID, + "h_count": h_count, + "v_count": v_count, "missing_screens": missing_screens, # 用于提示用户 "min_row": min_row, "min_col": min_col } - - def build_mosaic_packet(self, start, hcount, vcount, cmd_type=0x01): + def build_mosaic_packet(self, start, h_count, v_count, big_pic_id, cmd_type=0x10): """ 封装拼接指令包 - :param start: 起始物理屏编号 - :param hcount: 水平数量 - :param vcount: 垂直数量 - :param cmd_type: 命令字,0x01通常代表拼接 - :return: bytes (指令字节流) + :param start: 起始物理屏编号 (int) + :param h_count: 水平数量 (int) + :param v_count: 垂直数量 (int) + :param big_pic_id: 拼接大画面序列号,默认0x01表示拼接id (int) + :param cmd_type: 命令字,默认0x01表示拼接 (int) + :return: bytes (指令字节流),失败则抛出ValueError """ - - print(hcount) + # 参数类型检查 + if not all(isinstance(i, int) for i in [start, h_count, v_count, big_pic_id, cmd_type]): + raise ValueError("所有参数必须为整数") try: # 限制数值范围,防止溢出 - start = max(0, min(255, start)) - hcount = max(1, min(16, hcount)) # 假设最大16屏 - vcount = max(1, min(16, vcount)) + start = max(0, min(255, start)) # 屏幕编号范围 0~255 + h_count = max(1, min(16, h_count)) # 最大横向16块屏幕 + v_count = max(1, min(16, v_count)) # 最大纵向16块屏幕 + + # 协议格式: [帧头][命令][起始地址][横向数][纵向数][帧尾] + frame_head_1 = 0x80 # 帧头1 + frame_head_2 = 0xD6 # 帧头2 + frame_tail = 0xFF # 帧尾 - # 组装数据包 [AA 55] [Cmd] [Start] [H] [V] [FF] + # 构造数据包列表 packet = [ - 0xAA, # 帧头1 - 0x55, # 帧头2 - cmd_type, # 命令字 - start, # 起始地址 - hcount, # 横向数量 - vcount, # 纵向数量 - 0xFF # 帧尾 + frame_head_1, + frame_head_2, + cmd_type, + start, + v_count, + h_count, + big_pic_id, + frame_tail ] - # 转换为字节流 + # 返回构造完成的数据包 return bytes(packet) except Exception as e: print(f"协议封装错误: {e}") - return None \ No newline at end of file + raise ValueError("构建拼接指令包失败") from e \ No newline at end of file diff --git a/main.py b/main.py index c4a6240..e8f7b77 100644 --- a/main.py +++ b/main.py @@ -385,14 +385,54 @@ class MatrixControlApp(QMainWindow, Ui_MainWindow): # self.update_style() # 获取选中的屏幕控件 - selected_widgets = [self.screen_labels[value] for value in ScreenLabel.click_labels] + selected_widgets = [self.screen_labels[value - 1] for value in ScreenLabel.click_labels] print(selected_widgets) # 生成拼接指令参数 params = self.serial_protocol.calculate_mosaic_params(selected_widgets) print(params) - # 生成拼接屏的指令 + # 2. 【新增】通过串口管理器发送 + # 这里的 self.serial_manager 来自于我们在 main.py 中的初始化 + if hasattr(self, 'serial_manager') and self.serial_manager.is_connected: + start = params['start'] + v_count = params['v_count'] + h_count = params['h_count'] + + # 计算拼接id + big_pic_id = 1 + for i in range(start, start + v_count * h_count): + if ScreenLabel.split_solution[i]['status'] == 3 and ScreenLabel.split_solution[i]['big_pic_id'] > 0: + big_pic_id += 1 + break + + # 生成拼接指令 + mosaic_packet_bytes = self.serial_protocol.build_mosaic_packet(start, v_count, h_count, big_pic_id) + + print(mosaic_packet_bytes) + + if not mosaic_packet_bytes: + logger.error("指令封装失败,数据无效") + return + + # send_command 方法来自 SerialManager 类 + success = self.serial_manager.send_command(mosaic_packet_bytes) + + if success: + + click_labels = ScreenLabel.click_labels + + # 1. 查找对应的 Label 对象 + # label = self.screen_labels[screen_id - 1] # 数组下标从0开始 + + logger.info(f"✅ 指令发送成功") + else: + logger.error("指令发送失败") + + else: + logger.error("指令发送失败,未连接数据大屏") + return + # if selected: # # 如果选中,设置一个红色/蓝色的边框,或者背景色 @@ -488,7 +528,7 @@ class MatrixControlApp(QMainWindow, Ui_MainWindow): print(f"准备发送指令: Start={start}, {hcount}x{vcount}") # 1. 【新增】使用协议模块封装数据 - command_bytes = self.serial_protocol.build_mosaic_packet(start, hcount, vcount) + command_bytes = build_mosaic_packet(start, hcount, vcount) if not command_bytes: logger.error("指令封装失败,数据无效")