Files
fluent_widgets_pyside6/tests/test_moju_point_set.py

260 lines
9.0 KiB
Python
Raw Normal View History

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