MRobot/fluentui.py
2025-06-13 01:38:37 +08:00

232 lines
9.8 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import sys
import webbrowser
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QWidget, QVBoxLayout, QApplication, QLabel, QGroupBox, QGridLayout, QFrame, QHBoxLayout
from PyQt5.QtGui import QPixmap, QFont
from qfluentwidgets import (
NavigationInterface, NavigationItemPosition, MessageBox,
setTheme, Theme, FluentWindow, NavigationAvatarWidget,
SubtitleLabel, setFont, InfoBar, InfoBarPosition, PushButton
)
from qfluentwidgets import FluentIcon as FIF
# ===================== 页面基类 =====================
class BaseInterface(QWidget):
"""所有页面的基类,便于统一扩展"""
def __init__(self, title: str = "", parent=None):
super().__init__(parent=parent)
self.setObjectName(f'{self.__class__.__name__}')
self._mainLayout = QVBoxLayout(self)
if title:
self.titleLabel = SubtitleLabel(title, self)
setFont(self.titleLabel, 24)
self._mainLayout.addWidget(self.titleLabel, 0, Qt.AlignmentFlag.AlignCenter)
self._mainLayout.addStretch(1)
self.setLayout(self._mainLayout)
# ===================== 首页界面 =====================
class HomeInterface(BaseInterface):
def __init__(self, parent=None):
super().__init__(parent=parent)
# 欢迎图标
iconLabel = QLabel(self)
iconPixmap = QPixmap('img/MRobot.png').scaled(
300, 300, Qt.AspectRatioMode.KeepAspectRatio, Qt.TransformationMode.SmoothTransformation
)
iconLabel.setPixmap(iconPixmap)
iconLabel.setAlignment(Qt.AlignmentFlag.AlignCenter)
# 欢迎语
welcomeLabel = SubtitleLabel("高效、智能的R代码助手", self)
setFont(welcomeLabel, 18)
welcomeLabel.setAlignment(Qt.AlignmentFlag.AlignCenter)
# 操作按钮
btnGen = PushButton('生成代码', self, FIF.LIBRARY)
btnGen.setFixedWidth(160)
btnGen.clicked.connect(self.showInfoBar)
btnHelp = PushButton('帮助文档', self, FIF.HELP)
btnHelp.setFixedWidth(160)
btnHelp.clicked.connect(self.showHelp)
btnAbout = PushButton('关于我们', self, FIF.INFO)
btnAbout.setFixedWidth(160)
btnAbout.clicked.connect(self.showAbout)
# 按钮布局
btnLayout = QVBoxLayout()
btnLayout.setSpacing(16)
btnLayout.addWidget(btnGen)
btnLayout.addWidget(btnHelp)
btnLayout.addWidget(btnAbout)
btnWidget = QWidget(self)
btnWidget.setLayout(btnLayout)
# 主布局
self._mainLayout.insertWidget(0, iconLabel, 0, Qt.AlignmentFlag.AlignCenter)
self._mainLayout.insertWidget(1, welcomeLabel, 0, Qt.AlignmentFlag.AlignCenter)
self._mainLayout.insertWidget(2, btnWidget, 0, Qt.AlignmentFlag.AlignCenter)
def showInfoBar(self):
InfoBar.success(
title="提示",
content="代码生成功能即将上线,敬请期待!",
parent=self,
position=InfoBarPosition.TOP,
duration=2000
)
def showHelp(self):
webbrowser.open("https://github.com/lvzucheng/MRobot") # 示例
def showAbout(self):
MessageBox("关于我们", "MRobot 由 lvzucheng 开发致力于高效智能的R代码辅助。", self).exec()
# ===================== 代码生成页面 =====================
class DataInterface(BaseInterface):
def __init__(self, parent=None):
super().__init__('代码生成', parent)
# ===================== 实用工具页面 =====================
# ...existing code...
class DownloadTool(BaseInterface):
def __init__(self, parent=None):
super().__init__('实用工具', parent)
# 主体水平布局
main_layout = QHBoxLayout()
main_layout.setSpacing(32)
main_layout.setContentsMargins(32, 0, 32, 0) # 顶部和底部间距减小
# 区域1常用小工具
tools = [
("Geek Uninstaller", "https://geekuninstaller.com/download", FIF.DELETE),
("Neat Download Manager", "https://www.neatdownloadmanager.com/index.php/en/", FIF.DOWNLOAD),
("Everything", "https://www.voidtools.com/zh-cn/downloads/", FIF.SEARCH),
("Bandizip", "https://www.bandisoft.com/bandizip/", FIF.ZIP_FOLDER),
("PotPlayer", "https://potplayer.daum.net/", FIF.VIDEO),
("Typora", "https://typora.io/", FIF.EDIT),
("Git", "https://git-scm.com/download/win", FIF.CODE),
("Python", "https://www.python.org/downloads/", FIF.CODE),
]
tools_card = QGroupBox("常用小工具", self)
tools_card.setFont(QFont("微软雅黑", 15, QFont.Bold))
tools_card.setStyleSheet("""
QGroupBox { border: 1.5px solid #d6eaf8; border-radius: 12px; background: #f8fbfd; margin-top: 0px; }
QGroupBox:title { color: #222; left: 18px; top: -10px; background: transparent; padding: 0 8px; }
""")
tools_grid = QGridLayout()
tools_grid.setSpacing(18)
tools_grid.setContentsMargins(18, 18, 18, 18)
for idx, (name, url, icon) in enumerate(tools):
btn = PushButton(name, self, icon)
btn.setFont(QFont("微软雅黑", 14))
btn.setMinimumHeight(44)
btn.clicked.connect(self._make_open_url(url))
row, col = divmod(idx, 2)
tools_grid.addWidget(btn, row, col)
tools_card.setLayout(tools_grid)
main_layout.addWidget(tools_card, 1)
# 区域2开发/设计软件
dev_tools = [
("STM32CubeMX", "https://www.st.com/zh/development-tools/stm32cubemx.html", FIF.SETTING),
("Keil MDK", "https://www.keil.com/download/product/", FIF.CODE),
("Visual Studio Code", "https://code.visualstudio.com/", FIF.CODE),
("CLion", "https://www.jetbrains.com/clion/download/", FIF.CODE),
("MATLAB", "https://www.mathworks.com/downloads/", FIF.CODE),
("SolidWorks", "https://www.solidworks.com/sw/support/downloads.htm", FIF.LAYOUT),
("Altium Designer", "https://www.altium.com/zh/altium-designer/downloads", FIF.LAYOUT),
("原神", "https://download-porter.hoyoverse.com/download-porter/2025/03/27/GenshinImpact_install_202503072011.exe?trace_key=GenshinImpact_install_ua_679d0b4e9b10", FIF.GAME),
]
dev_card = QGroupBox("开发/设计软件", self)
dev_card.setFont(QFont("微软雅黑", 15, QFont.Bold))
dev_card.setStyleSheet("""
QGroupBox { border: 1.5px solid #d6eaf8; border-radius: 12px; background: #f8fbfd; margin-top: 0px; }
QGroupBox:title { color: #222; left: 18px; top: -10px; background: transparent; padding: 0 8px; }
""")
dev_grid = QGridLayout()
dev_grid.setSpacing(18)
dev_grid.setContentsMargins(18, 18, 18, 18)
for idx, (name, url, icon) in enumerate(dev_tools):
btn = PushButton(name, self, icon)
btn.setFont(QFont("微软雅黑", 14))
btn.setMinimumHeight(44)
btn.clicked.connect(self._make_open_url(url))
row, col = divmod(idx, 2)
dev_grid.addWidget(btn, row, col)
dev_card.setLayout(dev_grid)
main_layout.addWidget(dev_card, 1)
# 添加到主布局,靠上显示
self._mainLayout.insertLayout(1, main_layout)
def _make_open_url(self, url):
# 返回一个只带url参数的槽避免lambda闭包问题
return lambda checked=False, link=url: webbrowser.open(link)
# ...existing code...
# ===================== 其它页面 =====================
class SettingInterface(BaseInterface):
def __init__(self, parent=None):
super().__init__('设置页面', parent)
class HelpInterface(BaseInterface):
def __init__(self, parent=None):
super().__init__('帮助页面', parent)
class AboutInterface(BaseInterface):
def __init__(self, parent=None):
super().__init__('关于页面', parent)
# ===================== 主窗口与导航 =====================
class MainWindow(FluentWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("MR_ToolBox")
self.resize(1000, 700)
self.setMinimumSize(800, 600)
setTheme(Theme.LIGHT)
self.page_registry = [
(HomeInterface(self), FIF.HOME, "首页", NavigationItemPosition.TOP),
(DataInterface(self), FIF.LIBRARY, "MRobot代码生成", NavigationItemPosition.SCROLL),
(DownloadTool(self), FIF.DOWNLOAD, "实用工具", NavigationItemPosition.SCROLL),
(SettingInterface(self), FIF.SETTING, "设置", NavigationItemPosition.BOTTOM),
(HelpInterface(self), FIF.HELP, "帮助", NavigationItemPosition.BOTTOM),
(AboutInterface(self), FIF.INFO, "关于", NavigationItemPosition.BOTTOM),
]
self.initNavigation()
def initNavigation(self):
for page, icon, name, position in self.page_registry:
self.addSubInterface(page, icon, name, position)
self.navigationInterface.addSeparator()
avatar = NavigationAvatarWidget('用户', ':/qfluentwidgets/images/avatar.png')
self.navigationInterface.addWidget(
routeKey='avatar',
widget=avatar,
onClick=self.showUserInfo,
position=NavigationItemPosition.BOTTOM
)
def showUserInfo(self):
content = "当前登录用户: 管理员\n邮箱: admin@example.com"
MessageBox("用户信息", content, self).exec()
# ===================== 程序入口 =====================
def main():
QApplication.setHighDpiScaleFactorRoundingPolicy(
Qt.HighDpiScaleFactorRoundingPolicy.PassThrough)
QApplication.setAttribute(Qt.ApplicationAttribute.AA_EnableHighDpiScaling)
QApplication.setAttribute(Qt.ApplicationAttribute.AA_UseHighDpiPixmaps)
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()