MRobot/fluentui.py
2025-06-13 01:40:35 +08:00

263 lines
11 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)
# 顶部Logo
iconLabel = QLabel(self)
iconPixmap = QPixmap('img/MRobot.png').scaled(
180, 180, Qt.AspectRatioMode.KeepAspectRatio, Qt.TransformationMode.SmoothTransformation
)
iconLabel.setPixmap(iconPixmap)
iconLabel.setAlignment(Qt.AlignmentFlag.AlignCenter)
# 标题
titleLabel = QLabel("MRobot 智能R助手", self)
titleLabel.setFont(QFont("微软雅黑", 28, QFont.Bold))
titleLabel.setAlignment(Qt.AlignmentFlag.AlignCenter)
titleLabel.setStyleSheet("color: #1976d2; margin-top: 12px;")
# 副标题
subtitle = QLabel("高效 · 智能 · 便捷\n让R语言开发更简单", self)
subtitle.setFont(QFont("微软雅黑", 16))
subtitle.setAlignment(Qt.AlignmentFlag.AlignCenter)
subtitle.setStyleSheet("color: #555; margin-bottom: 18px;")
# 三个主按钮
btnGen = PushButton('代码生成', self, FIF.LIBRARY)
btnGen.setFixedSize(180, 48)
btnGen.setFont(QFont("微软雅黑", 15))
btnGen.clicked.connect(self.showInfoBar)
btnHelp = PushButton('帮助文档', self, FIF.HELP)
btnHelp.setFixedSize(180, 48)
btnHelp.setFont(QFont("微软雅黑", 15))
btnHelp.clicked.connect(self.showHelp)
btnAbout = PushButton('关于我们', self, FIF.INFO)
btnAbout.setFixedSize(180, 48)
btnAbout.setFont(QFont("微软雅黑", 15))
btnAbout.clicked.connect(self.showAbout)
btnLayout = QHBoxLayout()
btnLayout.setSpacing(36)
btnLayout.addStretch(1)
btnLayout.addWidget(btnGen)
btnLayout.addWidget(btnHelp)
btnLayout.addWidget(btnAbout)
btnLayout.addStretch(1)
# 卡片式欢迎信息
card = QFrame(self)
card.setStyleSheet("""
QFrame {
background: #f8fbfd;
border-radius: 18px;
border: 1.5px solid #d6eaf8;
padding: 24px 32px 18px 32px;
}
""")
cardLayout = QVBoxLayout(card)
cardLayout.setSpacing(10)
cardLayout.addWidget(titleLabel)
cardLayout.addWidget(subtitle)
cardLayout.addLayout(btnLayout)
# 主布局
layout = QVBoxLayout()
layout.setSpacing(24)
layout.setContentsMargins(0, 32, 0, 0)
layout.addWidget(iconLabel, 0, Qt.AlignmentFlag.AlignHCenter)
layout.addWidget(card, 0, Qt.AlignmentFlag.AlignHCenter)
layout.addStretch(1)
# 清空原有内容并设置新布局
QWidget().setLayout(self._mainLayout)
self.setLayout(layout)
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()