修改好了零件库功能

This commit is contained in:
Robofish 2025-06-18 14:28:31 +08:00
parent f680b91816
commit ffad148fcc
2 changed files with 68 additions and 54 deletions

BIN
.DS_Store vendored

Binary file not shown.

122
MRobot.py
View File

@ -180,77 +180,81 @@ class SerialTerminalInterface(BaseInterface):
def __init__(self, parent=None): def __init__(self, parent=None):
super().__init__(parent=parent) super().__init__(parent=parent)
self.setObjectName("serialTerminalInterface") self.setObjectName("serialTerminalInterface")
layout = QVBoxLayout(self) main_layout = QVBoxLayout(self)
main_layout.setSpacing(12)
# 串口选择和连接 # 顶部:串口设置区
hbox = QHBoxLayout() top_hbox = QHBoxLayout()
top_hbox.addWidget(BodyLabel("串口:"))
self.port_combo = ComboBox() self.port_combo = ComboBox()
self.refresh_ports() self.refresh_ports()
top_hbox.addWidget(self.port_combo)
top_hbox.addWidget(BodyLabel("波特率:"))
self.baud_combo = ComboBox() self.baud_combo = ComboBox()
self.baud_combo.addItems(['9600', '115200', '57600', '38400', '19200', '4800']) self.baud_combo.addItems(['9600', '115200', '57600', '38400', '19200', '4800'])
top_hbox.addWidget(self.baud_combo)
self.connect_btn = PushButton("连接") self.connect_btn = PushButton("连接")
self.connect_btn.clicked.connect(self.toggle_connection) self.connect_btn.clicked.connect(self.toggle_connection)
hbox.addWidget(BodyLabel("串口:")) top_hbox.addWidget(self.connect_btn)
hbox.addWidget(self.port_combo) self.refresh_btn = PushButton(FluentIcon.SYNC, "刷新")
hbox.addWidget(BodyLabel("波特率:")) self.refresh_btn.clicked.connect(self.refresh_ports)
hbox.addWidget(self.baud_combo) top_hbox.addWidget(self.refresh_btn)
hbox.addWidget(self.connect_btn) top_hbox.addStretch()
layout.addLayout(hbox) main_layout.addLayout(top_hbox)
# 自动回车复选框 main_layout.addWidget(HorizontalSeparator())
self.auto_enter_checkbox = CheckBox("自动回车")
self.auto_enter_checkbox.setChecked(True)
layout.addWidget(self.auto_enter_checkbox)
# 预设命令区不使用QGroupBox直接用布局和分隔线 # 中部:左侧预设命令,右侧显示区
layout.addWidget(HorizontalSeparator()) center_hbox = QHBoxLayout()
preset_label = BodyLabel("预设命令") # 左侧:预设命令竖排
layout.addWidget(preset_label) preset_vbox = QVBoxLayout()
# ...existing code... preset_vbox.addWidget(SubtitleLabel("快捷指令"))
#快捷指令居中
preset_vbox.setAlignment(Qt.AlignmentFlag.AlignCenter)
# 预设命令区不使用QGroupBox直接用布局和分隔线
layout.addWidget(HorizontalSeparator())
preset_label = BodyLabel("预设命令")
layout.addWidget(preset_label)
preset_layout = QGridLayout()
self.preset_commands = [ self.preset_commands = [
("线程监视器", "RESET"), ("线程监视器", "RESET"),
("陀螺仪校准", "GET_VERSION"), ("陀螺仪校准", "GET_VERSION"),
("性能监视", "START"), ("性能监视", "START"),
("重启", "STOP"), ("重启", "STOP"),
("显示所有device", "SELF_TEST"), ("显示所有设备", "SELF_TEST"),
("查询id", "STATUS"), ("查询id", "STATUS"),
] ]
for i, (label, cmd) in enumerate(self.preset_commands): for label, cmd in self.preset_commands:
btn = PushButton(label) btn = PushButton(label)
btn.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred) btn.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred)
btn.clicked.connect(lambda _, c=cmd: self.send_preset_command(c)) btn.clicked.connect(lambda _, c=cmd: self.send_preset_command(c))
preset_layout.addWidget(btn, i // 3, i % 3) preset_vbox.addWidget(btn)
layout.addLayout(preset_layout) preset_vbox.addStretch()
layout.addWidget(HorizontalSeparator()) main_layout.addLayout(center_hbox, stretch=1)
# 右侧:串口数据显示区
# 显示区
self.text_edit = TextEdit() self.text_edit = TextEdit()
self.text_edit.setReadOnly(True) self.text_edit.setReadOnly(True)
layout.addWidget(self.text_edit) self.text_edit.setMinimumWidth(400)
center_hbox.addWidget(self.text_edit, 3)
center_hbox.addLayout(preset_vbox, 1)
# 输入区 main_layout.addWidget(HorizontalSeparator())
input_hbox = QHBoxLayout()
# 底部:输入区
bottom_hbox = QHBoxLayout()
self.input_line = LineEdit() self.input_line = LineEdit()
self.input_line.setPlaceholderText("输入内容,回车发送") self.input_line.setPlaceholderText("输入内容,回车发送")
self.input_line.returnPressed.connect(self.send_data) self.input_line.returnPressed.connect(self.send_data)
bottom_hbox.addWidget(self.input_line, 4)
send_btn = PushButton("发送") send_btn = PushButton("发送")
send_btn.clicked.connect(self.send_data) send_btn.clicked.connect(self.send_data)
input_hbox.addWidget(self.input_line) bottom_hbox.addWidget(send_btn, 1)
input_hbox.addWidget(send_btn) self.auto_enter_checkbox = CheckBox("自动回车")
layout.addLayout(input_hbox) self.auto_enter_checkbox.setChecked(True)
bottom_hbox.addWidget(self.auto_enter_checkbox)
bottom_hbox.addStretch()
main_layout.addLayout(bottom_hbox)
self.ser = None self.ser = None
self.read_thread = None self.read_thread = None
def send_preset_command(self, cmd): def send_preset_command(self, cmd):
self.input_line.setText(cmd) self.input_line.setText(cmd)
self.send_data() self.send_data()
@ -311,8 +315,10 @@ class SerialTerminalInterface(BaseInterface):
self.text_edit.append(f"发送失败: {e}") self.text_edit.append(f"发送失败: {e}")
self.input_line.clear() self.input_line.clear()
# ===================== 零件库页面 ===================== # ===================== 零件库页面 =====================
# ...existing code...
class DownloadThread(QThread): class DownloadThread(QThread):
progressChanged = pyqtSignal(int) progressChanged = pyqtSignal(int)
finished = pyqtSignal(list, list) # success, fail finished = pyqtSignal(list, list) # success, fail
@ -325,27 +331,35 @@ class DownloadThread(QThread):
self.local_dir = local_dir self.local_dir = local_dir
def run(self): def run(self):
import requests, shutil, os
success, fail = [], [] success, fail = [], []
total = len(self.files) total = len(self.files)
max_retry = 3 # 最大重试次数
for idx, rel_path in enumerate(self.files): for idx, rel_path in enumerate(self.files):
try: retry = 0
url = f"{self.server_url}/download/{rel_path}" while retry < max_retry:
params = {"key": self.secret_key} try:
resp = requests.get(url, params=params, stream=True, timeout=10) url = f"{self.server_url}/download/{rel_path}"
if resp.status_code == 200: params = {"key": self.secret_key}
local_path = os.path.join(self.local_dir, rel_path) resp = requests.get(url, params=params, stream=True, timeout=10)
os.makedirs(os.path.dirname(local_path), exist_ok=True) if resp.status_code == 200:
with open(local_path, "wb") as f: local_path = os.path.join(self.local_dir, rel_path)
shutil.copyfileobj(resp.raw, f) os.makedirs(os.path.dirname(local_path), exist_ok=True)
success.append(rel_path) with open(local_path, "wb") as f:
else: shutil.copyfileobj(resp.raw, f)
fail.append(rel_path) success.append(rel_path)
except Exception: break # 下载成功,跳出重试循环
else:
print(f"下载失败({resp.status_code}): {rel_path},第{retry+1}次尝试")
retry += 1
except Exception as e:
print(f"下载异常: {rel_path},第{retry+1}次尝试,错误: {e}")
retry += 1
else:
fail.append(rel_path) fail.append(rel_path)
self.progressChanged.emit(int((idx + 1) / total * 100)) self.progressChanged.emit(int((idx + 1) / total * 100))
self.finished.emit(success, fail) self.finished.emit(success, fail)
class PartLibraryInterface(BaseInterface): class PartLibraryInterface(BaseInterface):
SERVER_URL = "http://154.37.215.220:5000" SERVER_URL = "http://154.37.215.220:5000"
SECRET_KEY = "MRobot_Download" SECRET_KEY = "MRobot_Download"
@ -359,7 +373,7 @@ class PartLibraryInterface(BaseInterface):
layout.addWidget(SubtitleLabel("零件库在线bate版")) layout.addWidget(SubtitleLabel("零件库在线bate版"))
layout.addWidget(HorizontalSeparator()) layout.addWidget(HorizontalSeparator())
layout.addWidget(BodyLabel("可浏览服务器零件库,选择需要的文件下载到本地。")) layout.addWidget(BodyLabel("可浏览服务器零件库,选择需要的文件下载到本地。(如无法使用或者下载失败,请尝试重新下载或检查网络连接)"))
btn_layout = QHBoxLayout() btn_layout = QHBoxLayout()
refresh_btn = PushButton(FluentIcon.SYNC, "刷新列表") refresh_btn = PushButton(FluentIcon.SYNC, "刷新列表")