from common import * from PySide6.QtWidgets import ( QWidget, QLabel, QHBoxLayout, QVBoxLayout, QDoubleSpinBox, QLayout, QApplication, QDialog, ) from qfluentwidgets import ( PrimaryPushButton, PushButton, StrongBodyLabel, SubtitleLabel, DoubleSpinBox, MessageBox, isDarkTheme, setTheme, Theme, ) import random class MoJuPointSetDialog(QDialog): def __init__(self, point_name, parent=None): super().__init__(parent) self.setWindowTitle("模具点位设置") self.resize(850, 320) # 0. 传入的点位名称 self.point_name = point_name # 1. 点位名称编号 self.current_point_num = 1 # 当前点位编号(初始为1) # 2. 存储各轴输入框:key=轴名(X/Y/Z/Rx/Ry/Rz), value=DoubleSpinBox对象 self.axis_spins = {} # 3. 存储已经设置好的点位 {点位名称1: [x, y, z, rx, ry, rz], ......} self.point_dict = {} self.init_ui() self._initThemeStyle() def init_ui(self): # 主布局:垂直排列顶部区域和“添加下一个点”按钮 main_layout = QVBoxLayout(self) main_layout.setSpacing(30) # 组件间间距 main_layout.setContentsMargins(20, 20, 20, 20) # 窗口边距 # ---------- 顶部区域:点标签 + 坐标输入 + 右侧按钮 ---------- top_layout = QHBoxLayout() top_layout.setSpacing(40) # 左右区域间距 # ---- 左侧:点标签 + 坐标输入 ---- left_layout = QVBoxLayout() left_layout.setSpacing(20) # “点1:” 标签行 point_label_layout = QHBoxLayout() self.point_label = SubtitleLabel(f"{self.point_name}{self.current_point_num}") point_label_layout.addWidget(self.point_label) point_label_layout.addStretch() # 让标签靠左 left_layout.addLayout(point_label_layout) # X/Y/Z 输入行 xyz_layout = QHBoxLayout() self._add_axis_input(xyz_layout, "X") xyz_layout.addSpacing(30) # 轴之间的间距 self._add_axis_input(xyz_layout, "Y") xyz_layout.addSpacing(30) self._add_axis_input(xyz_layout, "Z") left_layout.addLayout(xyz_layout) # Rx/Ry/Rz 输入行 rxyz_layout = QHBoxLayout() self._add_axis_input(rxyz_layout, "Rx") rxyz_layout.addSpacing(30) self._add_axis_input(rxyz_layout, "Ry") rxyz_layout.addSpacing(30) self._add_axis_input(rxyz_layout, "Rz") left_layout.addLayout(rxyz_layout) top_layout.addLayout(left_layout) # ---- 右侧:三个功能按钮 ---- right_layout = QVBoxLayout() right_layout.setSpacing(20) # 按钮间间距 # “获取机械臂点位” 按钮 get_robot_btn = PrimaryPushButton("获取机械臂点位") get_robot_btn.clicked.connect(self.onGetRobotPos) # “确认上传” 按钮 confirm_upload_btn = PrimaryPushButton("确认上传") confirm_upload_btn.clicked.connect(self.onConfirmUpload) # “返回上页” 按钮 return_btn = PrimaryPushButton("返回上页") return_btn.clicked.connect(self.onReturnBeforePage) right_layout.addWidget(get_robot_btn) right_layout.addWidget(confirm_upload_btn) right_layout.addWidget(return_btn) top_layout.addLayout(right_layout) main_layout.addLayout(top_layout) # ---------- 底部:“添加下一个点” 按钮 ---------- add_next_layout = QHBoxLayout() add_next_layout.addStretch() add_next_btn = PrimaryPushButton("添加下一个点") add_next_btn.setMinimumSize(180, 40) add_next_btn.setMaximumSize(220, 45) add_next_btn.clicked.connect(self.onAddNextPoint) add_next_layout.addWidget(add_next_btn) # 添加右侧伸缩项,将按钮固定在中间 add_next_layout.addStretch() main_layout.addLayout(add_next_layout) def _add_axis_input(self, layout: QHBoxLayout, axis_name: str): """添加“标签 + 双精度输入框”到布局""" label = StrongBodyLabel(f"{axis_name}:") spin = DoubleSpinBox() spin.setRange(-180, 180) # 数值范围 spin.setSingleStep(0.1) # 步长(滚轮或上下键的变化量) spin.setDecimals(3) # 小数位数 self.axis_spins[axis_name] = spin # 放双精度输入框的字典 layout.addWidget(label) layout.addWidget(spin) # ---------- 按钮点击槽函数 ---------- def onGetRobotPos(self): for spin in self.axis_spins.values(): random_num = round(random.uniform(-180, 180), 3) spin.setValue(random_num) def onConfirmUpload(self): # 确认上传 # 1、先保存当前界面的数据,再上传 self.__saveCurentPoint() # 2、点位写入数据库? print(self.point_dict) # 3 、提示 if self.point_dict: # 提取所有点位名(字典的key),并格式化为列表 point_names = list(self.point_dict.keys()) # 构造提示文本(用换行和符号美化显示) message = "以下点位上传成功:\n" for name in point_names: message += f"• {name}\n" # 用•符号列出每个点位名 # 弹出成功提示框 MessageBox( "上传成功", # 标题 message, # 内容 self, # 父窗口 ).exec() # 4、确认上传之后,关闭点位上传对话框 self.close() # 返回上一页 def onReturnBeforePage(self): if self.current_point_num <= 1: MessageBox( "错误", f"已处于第一个点位 ({self.point_name}1) ,无法继续返回上一页", self, ).exec() return # 直接返回,不执行后续操作 # 0. 先保存当前界面的数据,再返回上一页 self.__saveCurentPoint() # 1、当前编号减一和更新标签 self.current_point_num -= 1 self.point_label.setText(f"{self.point_name}{self.current_point_num}") # 2、显示上一页点位名的点位数据 before_point_name = self.point_label.text() if before_point_name in self.point_dict: self.__showPointValue(before_point_name) else: # 上一页点位名不存在 for spin in self.axis_spins.values(): spin.setValue(0.0) # 上一页的点位数据缺失,请重新获取并设置点位 # 这里是发生了异常,一般情况,不会没有保存上一页点位数据 MessageBox( "异常", f"上一页的点位数据缺失,请重新获取并设置点位", self, ).exec() def onAddNextPoint(self): # 0. 先保存当前界面的数据,再跳转到下一页 self.__saveCurentPoint() # 1. 跳转下一页,更新点位编号和标签 self.current_point_num += 1 self.point_label.setText(f"{self.point_name}{self.current_point_num}") # 2. 如果下一页的点位数据已经保存,则获取并显示 # 否则清空所有输入框的值(设置为0.0), 表示仍然需要设置 next_point_name = self.point_label.text() if next_point_name in self.point_dict: self.__showPointValue(next_point_name) else: for spin in self.axis_spins.values(): spin.setValue(0.0) # 保存当前界面的点位 def __saveCurentPoint(self): current_point_value = [ self.axis_spins["X"].value(), self.axis_spins["Y"].value(), self.axis_spins["Z"].value(), self.axis_spins["Rx"].value(), self.axis_spins["Ry"].value(), self.axis_spins["Rz"].value(), ] self.point_dict[f"{self.point_name}{self.current_point_num}"] = ( current_point_value ) # 根据点位名称,显示点位值 (字典中保存的) def __showPointValue(self, point_name: str): if point_name not in self.point_dict: return coords = self.point_dict[point_name] self.axis_spins["X"].setValue(coords[0]) self.axis_spins["Y"].setValue(coords[1]) self.axis_spins["Z"].setValue(coords[2]) self.axis_spins["Rx"].setValue(coords[3]) self.axis_spins["Ry"].setValue(coords[4]) self.axis_spins["Rz"].setValue(coords[5]) # 根据主题初始化样式表 def _initThemeStyle(self): if isDarkTheme(): # 深色主题 self.setStyleSheet("background-color: rgb(32, 32, 32);") else: # 浅色主题 self.setStyleSheet("background-color: rgb(243, 243, 243);") if __name__ == "__main__": app = QApplication([]) setTheme(Theme.DARK) window = MoJuPointSetDialog("吸取点") window.show() sys.exit(app.exec())