mirror of
https://github.com/goldenfishs/MRobot.git
synced 2025-07-03 22:24:17 +08:00
完善MRUI架构
This commit is contained in:
parent
86b0062881
commit
b893c30eb3
180
MRobot.py
180
MRobot.py
@ -7,12 +7,22 @@ from PyQt5.QtGui import QTextCursor
|
||||
from PyQt5.QtCore import QThread, pyqtSignal
|
||||
from PyQt5.QtWidgets import QHBoxLayout, QComboBox, QPushButton, QTextEdit, QLineEdit, QLabel
|
||||
from PyQt5.QtWidgets import QGroupBox, QGridLayout, QSizePolicy
|
||||
|
||||
from qfluentwidgets import Theme, setTheme
|
||||
from qfluentwidgets import (
|
||||
NavigationItemPosition, Theme, FluentWindow, NavigationAvatarWidget,
|
||||
PushButton, FluentIcon
|
||||
)
|
||||
from qfluentwidgets import FluentIcon as FIF
|
||||
from qfluentwidgets import Theme, setTheme, FluentIcon, SwitchButton
|
||||
from qfluentwidgets import BodyLabel
|
||||
from qfluentwidgets import BodyLabel, TextEdit, LineEdit, ComboBox, PushButton, SwitchButton
|
||||
from qfluentwidgets import BodyLabel, SubtitleLabel, StrongBodyLabel, HorizontalSeparator, InfoBar
|
||||
from qfluentwidgets import MessageDialog
|
||||
from qfluentwidgets import Dialog, StrongBodyLabel, BodyLabel, SubtitleLabel, AvatarWidget
|
||||
from PyQt5.QtWidgets import QVBoxLayout, QHBoxLayout, QWidget
|
||||
from qfluentwidgets import Dialog
|
||||
from qfluentwidgets import StrongBodyLabel, SubtitleLabel, BodyLabel, PushButton, AvatarWidget, HorizontalSeparator
|
||||
from qfluentwidgets import ImageLabel
|
||||
|
||||
# ===================== 页面基类 =====================
|
||||
class BaseInterface(QWidget):
|
||||
@ -20,13 +30,67 @@ class BaseInterface(QWidget):
|
||||
super().__init__(parent=parent)
|
||||
|
||||
# ===================== 首页界面 =====================
|
||||
# ...existing code...
|
||||
|
||||
# ...existing code...
|
||||
|
||||
class HomeInterface(BaseInterface):
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent=parent)
|
||||
self.setObjectName("homeInterface")
|
||||
layout = QVBoxLayout()
|
||||
layout.setContentsMargins(60, 60, 60, 60)
|
||||
layout.setSpacing(32)
|
||||
self.setLayout(layout)
|
||||
|
||||
# 顶部logo和欢迎区
|
||||
top_layout = QHBoxLayout()
|
||||
logo = ImageLabel('img/MRobot.png')
|
||||
logo.setFixedSize(260, 80)
|
||||
top_layout.addWidget(logo, alignment=Qt.AlignmentFlag.AlignTop)
|
||||
title_layout = QVBoxLayout()
|
||||
title_layout.addWidget(StrongBodyLabel("欢迎使用 MRobot Toolbox"))
|
||||
title_layout.addWidget(SubtitleLabel("让你的机器人开发更高效、更智能"))
|
||||
top_layout.addLayout(title_layout)
|
||||
top_layout.addStretch()
|
||||
layout.addLayout(top_layout)
|
||||
|
||||
layout.addWidget(HorizontalSeparator())
|
||||
|
||||
# 项目简介
|
||||
layout.addWidget(BodyLabel(
|
||||
"MRobot Toolbox 是一款集成化的机器人开发辅助工具,"
|
||||
"支持代码生成、串口终端、主题切换等多种实用功能。\n"
|
||||
"点击左侧导航栏可快速切换各功能页面。"
|
||||
))
|
||||
|
||||
# 开发者与项目目标
|
||||
layout.addWidget(HorizontalSeparator())
|
||||
layout.addWidget(SubtitleLabel("开发者与项目目标"))
|
||||
layout.addWidget(BodyLabel("开发团队:QUT 青岛理工大学 MOVE 战队"))
|
||||
layout.addWidget(BodyLabel("项目目标:为所有 rmer 和 rcer 提供现代化、简单、高效的机器人开发方式,"
|
||||
"让机器人开发变得更轻松、更智能。"))
|
||||
layout.addWidget(BodyLabel("适用于 RM、RC、各类嵌入式机器人项目。"))
|
||||
|
||||
# # 开源与版本信息
|
||||
# layout.addWidget(HorizontalSeparator())
|
||||
# layout.addWidget(SubtitleLabel("项目信息"))
|
||||
# layout.addWidget(BodyLabel("开源地址: https://github.com/QUT-MOVE/MRobot-Toolbox"))
|
||||
# layout.addWidget(BodyLabel("当前版本: v1.0.0"))
|
||||
# layout.addWidget(BodyLabel("反馈邮箱: move@qut.edu.cn"))
|
||||
|
||||
# # 致谢
|
||||
# layout.addWidget(HorizontalSeparator())
|
||||
# layout.addWidget(SubtitleLabel("致谢"))
|
||||
# layout.addWidget(BodyLabel("感谢所有开源社区贡献者,特别感谢 RM/RC 机器人开发者的持续支持。"))
|
||||
|
||||
layout.addStretch()
|
||||
|
||||
# ...existing code...
|
||||
|
||||
# ...existing code...
|
||||
|
||||
|
||||
# ===================== 代码生成页面 =====================
|
||||
class DataInterface(BaseInterface):
|
||||
def __init__(self, parent=None):
|
||||
@ -65,15 +129,15 @@ class SerialTerminalInterface(BaseInterface):
|
||||
|
||||
# 串口选择和连接
|
||||
hbox = QHBoxLayout()
|
||||
self.port_combo = QComboBox()
|
||||
self.port_combo = ComboBox() # 替换QComboBox为ComboBox
|
||||
self.refresh_ports()
|
||||
self.baud_combo = QComboBox()
|
||||
self.baud_combo = ComboBox() # 替换QComboBox为ComboBox
|
||||
self.baud_combo.addItems(['9600', '115200', '57600', '38400', '19200', '4800'])
|
||||
self.connect_btn = QPushButton("连接")
|
||||
self.connect_btn = PushButton("连接") # 替换QPushButton为PushButton
|
||||
self.connect_btn.clicked.connect(self.toggle_connection)
|
||||
hbox.addWidget(QLabel("串口:"))
|
||||
hbox.addWidget(BodyLabel("串口:"))
|
||||
hbox.addWidget(self.port_combo)
|
||||
hbox.addWidget(QLabel("波特率:"))
|
||||
hbox.addWidget(BodyLabel("波特率:"))
|
||||
hbox.addWidget(self.baud_combo)
|
||||
hbox.addWidget(self.connect_btn)
|
||||
layout.addLayout(hbox)
|
||||
@ -82,15 +146,15 @@ class SerialTerminalInterface(BaseInterface):
|
||||
preset_group = QGroupBox("预设命令")
|
||||
preset_layout = QGridLayout()
|
||||
self.preset_commands = [
|
||||
("复位", "RESET"),
|
||||
("获取版本", "GET_VERSION"),
|
||||
("启动", "START"),
|
||||
("停止", "STOP"),
|
||||
("自检", "SELF_TEST"),
|
||||
("查询状态", "STATUS?"),
|
||||
("线程监视器", "RESET"),
|
||||
("陀螺仪校准", "GET_VERSION"),
|
||||
("性能监视", "START"),
|
||||
("重启", "STOP"),
|
||||
("显示所有device", "SELF_TEST"),
|
||||
("查询id", "STATUS"),
|
||||
]
|
||||
for i, (label, cmd) in enumerate(self.preset_commands):
|
||||
btn = QPushButton(label)
|
||||
btn = PushButton(label) # 替换QPushButton为PushButton
|
||||
btn.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred)
|
||||
btn.clicked.connect(lambda _, c=cmd: self.send_preset_command(c))
|
||||
preset_layout.addWidget(btn, i // 3, i % 3)
|
||||
@ -98,19 +162,16 @@ class SerialTerminalInterface(BaseInterface):
|
||||
layout.addWidget(preset_group)
|
||||
|
||||
# 显示区
|
||||
self.text_edit = QTextEdit()
|
||||
self.text_edit = TextEdit() # 替换QTextEdit为TextEdit
|
||||
self.text_edit.setReadOnly(True)
|
||||
self.text_edit.setStyleSheet(
|
||||
"background-color: #1e1e1e; color: #d4d4d4; font-family: Consolas, 'Courier New', monospace; font-size: 14px;"
|
||||
)
|
||||
layout.addWidget(self.text_edit)
|
||||
|
||||
# 输入区
|
||||
input_hbox = QHBoxLayout()
|
||||
self.input_line = QLineEdit()
|
||||
self.input_line = LineEdit()
|
||||
self.input_line.setPlaceholderText("输入内容,回车发送")
|
||||
self.input_line.returnPressed.connect(self.send_data)
|
||||
send_btn = QPushButton("发送")
|
||||
send_btn = PushButton("发送")
|
||||
send_btn.clicked.connect(self.send_data)
|
||||
input_hbox.addWidget(self.input_line)
|
||||
input_hbox.addWidget(send_btn)
|
||||
@ -168,13 +229,10 @@ class SerialTerminalInterface(BaseInterface):
|
||||
text = self.input_line.text()
|
||||
try:
|
||||
if not text:
|
||||
# 内容为空,只发送换行
|
||||
self.ser.write('\n'.encode())
|
||||
else:
|
||||
# 逐字符发送
|
||||
for char in text:
|
||||
self.ser.write(char.encode())
|
||||
# 结尾加换行
|
||||
self.ser.write('\n'.encode())
|
||||
except Exception as e:
|
||||
self.text_edit.append(f"发送失败: {e}")
|
||||
@ -182,12 +240,58 @@ class SerialTerminalInterface(BaseInterface):
|
||||
|
||||
# ===================== 设置界面 =====================
|
||||
class SettingInterface(BaseInterface):
|
||||
themeSwitchRequested = pyqtSignal()
|
||||
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent=parent)
|
||||
self.setObjectName("settingInterface")
|
||||
layout = QVBoxLayout()
|
||||
self.setLayout(layout)
|
||||
|
||||
# 标题
|
||||
layout.addSpacing(10)
|
||||
layout.addWidget(SubtitleLabel("设置中心"))
|
||||
layout.addSpacing(10)
|
||||
layout.addWidget(HorizontalSeparator())
|
||||
|
||||
# 主题切换区域
|
||||
theme_title = StrongBodyLabel("外观设置")
|
||||
theme_desc = BodyLabel("切换夜间/白天模式,适应不同环境。")
|
||||
theme_desc.setWordWrap(True)
|
||||
layout.addSpacing(10)
|
||||
layout.addWidget(theme_title)
|
||||
layout.addWidget(theme_desc)
|
||||
|
||||
theme_box = QHBoxLayout()
|
||||
self.theme_label = BodyLabel("夜间模式")
|
||||
self.theme_switch = SwitchButton()
|
||||
self.theme_switch.setChecked(Theme.DARK == Theme.DARK)
|
||||
self.theme_switch.checkedChanged.connect(self.on_theme_switch)
|
||||
theme_box.addWidget(self.theme_label)
|
||||
theme_box.addWidget(self.theme_switch)
|
||||
theme_box.addStretch()
|
||||
layout.addLayout(theme_box)
|
||||
|
||||
layout.addSpacing(15)
|
||||
layout.addWidget(HorizontalSeparator())
|
||||
|
||||
# 其它设置区域(示例)
|
||||
other_title = StrongBodyLabel("其它设置")
|
||||
other_desc = BodyLabel("更多功能正在开发中,敬请期待。")
|
||||
other_desc.setWordWrap(True)
|
||||
layout.addSpacing(10)
|
||||
layout.addWidget(other_title)
|
||||
layout.addWidget(other_desc)
|
||||
|
||||
# 版权信息
|
||||
layout.addStretch()
|
||||
copyright_label = BodyLabel("© 2025 MRobot Toolbox")
|
||||
copyright_label.setAlignment(Qt.AlignmentFlag.AlignHCenter)
|
||||
layout.addWidget(copyright_label)
|
||||
layout.addSpacing(10)
|
||||
|
||||
def on_theme_switch(self, checked):
|
||||
self.themeSwitchRequested.emit()
|
||||
# ===================== 帮助与关于界面 =====================
|
||||
class HelpInterface(BaseInterface):
|
||||
def __init__(self, parent=None):
|
||||
@ -213,11 +317,18 @@ class MainWindow(FluentWindow):
|
||||
self.resize(1000, 700)
|
||||
self.setMinimumSize(800, 600)
|
||||
|
||||
# 记录当前主题
|
||||
self.current_theme = Theme.DARK
|
||||
|
||||
# 创建页面实例
|
||||
self.setting_page = SettingInterface(self)
|
||||
self.setting_page.themeSwitchRequested.connect(self.toggle_theme)
|
||||
|
||||
self.page_registry = [
|
||||
(HomeInterface(self), FIF.HOME, "首页", NavigationItemPosition.TOP),
|
||||
(DataInterface(self), FIF.LIBRARY, "MRobot代码生成", NavigationItemPosition.SCROLL),
|
||||
(SerialTerminalInterface(self), FIF.COMMAND_PROMPT, "串口终端", NavigationItemPosition.SCROLL),
|
||||
(SettingInterface(self), FIF.SETTING, "设置", NavigationItemPosition.BOTTOM),
|
||||
(SerialTerminalInterface(self), FIF.COMMAND_PROMPT, "Mini_Shell", NavigationItemPosition.SCROLL),
|
||||
(self.setting_page, FIF.SETTING, "设置", NavigationItemPosition.BOTTOM),
|
||||
(HelpInterface(self), FIF.HELP, "帮助", NavigationItemPosition.BOTTOM),
|
||||
(AboutInterface(self), FIF.INFO, "关于", NavigationItemPosition.BOTTOM),
|
||||
]
|
||||
@ -231,13 +342,32 @@ class MainWindow(FluentWindow):
|
||||
self.navigationInterface.addWidget(
|
||||
routeKey='avatar',
|
||||
widget=avatar,
|
||||
onClick=None,
|
||||
onClick=self.show_user_info, # 这里改为 self.show_user_info
|
||||
position=NavigationItemPosition.BOTTOM
|
||||
)
|
||||
|
||||
def toggle_theme(self):
|
||||
# 切换主题
|
||||
if self.current_theme == Theme.DARK:
|
||||
self.current_theme = Theme.LIGHT
|
||||
else:
|
||||
self.current_theme = Theme.DARK
|
||||
setTheme(self.current_theme)
|
||||
# 同步设置界面按钮状态
|
||||
self.setting_page.theme_switch.setChecked(self.current_theme == Theme.DARK)
|
||||
|
||||
def show_user_info(self):
|
||||
dialog = Dialog(
|
||||
title="用户信息",
|
||||
content="用户:MRobot至尊VIP用户",
|
||||
parent=self
|
||||
)
|
||||
dialog.exec()
|
||||
|
||||
# ===================== 程序入口 =====================
|
||||
def main():
|
||||
app = QApplication(sys.argv)
|
||||
setTheme(Theme.DARK)
|
||||
window = MainWindow()
|
||||
window.show()
|
||||
sys.exit(app.exec_())
|
||||
|
Loading…
Reference in New Issue
Block a user