Files
nl-utils/v1/main.py
2025-06-07 23:43:57 +08:00

480 lines
12 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
from PyQt5.QtWidgets import QApplication, QMainWindow, QStackedWidget, QHBoxLayout, QWidget, QMessageBox
from PyQt5.QtCore import Qt
from views.login import LoginPage
from views.nav import NavBar
from views.home import Home
from views.word_to_pdf import WordToPDFPage
from views.app_center import AppCenter
from views.history import HistoryPage
from PyQt5.QtGui import QPalette, QColor
# 优化的暗色主题样式表
STYLES_TXT = """
/* ===== 全局样式 ===== */
QWidget {
font-family: 'Segoe UI', 'Microsoft YaHei', sans-serif;
font-size: 14px;
color: #e2e8f0;
border: none;
}
/* 输入框 */
QLineEdit {
background-color: #2d3748;
border: 1px solid #4a5568;
border-radius: 6px;
padding: 10px;
color: #e2e8f0;
min-height: 40px;
}
QLineEdit:focus {
border-color: #818cf8;
outline: none;
}
/* ===== 按钮全局样式 ===== */
QPushButton {
background-color: #4f46e5;
color: white;
border-radius: 8px; /* 增加圆角程度 */
padding: 10px 16px;
min-height: 40px; /* 增加高度 */
font-weight: 500;
transition: all 0.2s ease;
border: none;
outline: none; /* 防止点击时出现虚线边框 */
}
QPushButton:hover {
background-color: #4338ca;
transform: translateY(-2px);
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}
QPushButton:pressed {
background-color: #3730a3;
transform: translateY(0);
box-shadow: none;
}
QPushButton:disabled {
background-color: #4a5568;
color: #a0aec0;
}
/* 特殊按钮样式 */
QPushButton#navBtn {
text-align: left;
padding: 12px 25px;
color: #a0aec0;
border-radius: 8px;
margin: 5px 15px;
font-size: 14px;
background-color: transparent;
border: none;
min-height: auto; /* 覆盖全局最小高度 */
}
QPushButton#navBtn:hover {
background-color: rgba(79, 70, 229, 0.1);
color: #cbd5e0;
}
QPushButton#navBtn.active {
background-color: rgba(79, 70, 229, 0.15);
color: #818cf8;
font-weight: 500;
}
QPushButton#logoutBtn {
text-align: left;
padding: 12px 25px;
border-radius: 8px;
margin: 5px 15px;
font-size: 14px;
color: #feb2b2;
background-color: transparent;
border: none;
min-height: auto; /* 覆盖全局最小高度 */
}
QPushButton#logoutBtn:hover {
color: #f56565;
}
/* 操作按钮样式 */
QPushButton#actionBtn {
background-color: rgba(129, 140, 248, 0.1);
color: #818cf8;
border: 1px solid rgba(129, 140, 248, 0.2);
min-height: auto; /* 覆盖全局最小高度 */
}
QPushButton#actionBtn:hover {
background-color: rgba(129, 140, 248, 0.2);
}
QPushButton#retryBtn {
background-color: rgba(251, 113, 133, 0.1);
color: #fb7185;
border: 1px solid rgba(251, 113, 133, 0.2);
min-height: auto; /* 覆盖全局最小高度 */
}
QPushButton#retryBtn:hover {
background-color: rgba(251, 113, 133, 0.2);
}
QPushButton#deleteBtn {
background-color: rgba(120, 113, 108, 0.1);
color: #a8a29e;
border: 1px solid rgba(120, 113, 108, 0.2);
min-height: auto; /* 覆盖全局最小高度 */
}
QPushButton#deleteBtn:hover {
background-color: rgba(120, 113, 108, 0.2);
}
/* 卡片按钮样式 */
QPushButton#appCardBtn {
min-height: auto; /* 覆盖全局最小高度 */
min-width: 120px;
}
/* 登录页面按钮 */
QPushButton#loginBtn {
min-height: auto; /* 覆盖全局最小高度 */
min-width: 240px;
padding: 14px 30px;
font-size: 16px;
}
/* 列表控件 */
QListWidget {
background-color: #2d3748;
border: 1px solid #4a5568;
border-radius: 8px;
padding: 4px;
color: #e2e8f0;
outline: none;
}
QListWidget::item {
padding: 8px 12px;
border-bottom: 1px solid #4a5568;
}
QListWidget::item:selected {
background-color: rgba(129, 140, 248, 0.15);
color: #e2e8f0;
border-radius: 4px;
}
/* 滚动条 */
QScrollBar:vertical {
background: #2d3748;
width: 10px;
border: none;
}
QScrollBar::handle:vertical {
background: #4a5568;
min-height: 20px;
border-radius: 4px;
}
QScrollBar::handle:vertical:hover {
background: #718096;
}
QScrollBar::add-line:vertical,
QScrollBar::sub-line:vertical {
height: 0;
}
QScrollBar::add-page:vertical,
QScrollBar::sub-page:vertical {
background: none;
}
/* 标签 */
QLabel {
color: #e2e8f0;
background-color: transparent;
}
/* 菜单栏 */
/* 导航栏 */
#navBar {
background-color: #1a202c;
border-right: 1px solid #2d3748;
}
/* 用户卡片 */
#userCard {
background-color: #2d3748;
border-radius: 8px;
margin: 15px;
padding: 15px;
}
/* 导航按钮 */
#navBtn {
text-align: left;
padding: 12px 25px;
color: #a0aec0;
border-radius: 8px;
margin: 5px 15px;
font-size: 14px;
background-color: transparent;
border: none;
}
#navBtn:hover {
background-color: rgba(79, 70, 229, 0.1);
color: #cbd5e0;
}
#navBtn.active {
background-color: rgba(79, 70, 229, 0.15);
color: #818cf8;
font-weight: 500;
}
/* 退出按钮 */
#logoutBtn {
text-align: left;
padding: 12px 25px;
border-radius: 8px;
margin: 5px 15px;
font-size: 14px;
color: #feb2b2;
background-color: transparent;
border: none;
}
#logoutBtn:hover {
color: #f56565;
}
/* 分割线 */
QFrame[frameShape="4"] { /* HLine */
background-color: #2d3748;
margin: 10px 15px;
max-height: 1px;
}
/* 进度条 */
QProgressBar {
border-radius: 4px;
height: 8px;
background-color: #2d3748;
border: 1px solid #4a5568;
text-align: center;
}
QProgressBar::chunk {
background-color: #4f46e5;
border-radius: 4px;
}
/* 复选框 */
QCheckBox {
color: #e2e8f0;
spacing: 8px;
}
QCheckBox::indicator {
width: 16px;
height: 16px;
border: 1px solid #4a5568;
border-radius: 3px;
background-color: #2d3748;
}
QCheckBox::indicator:checked {
background-color: #4f46e5;
border: 1px solid #4f46e5;
}
/* 分组框 */
QGroupBox {
font-weight: bold;
background-color: #2d3748;
border: 1px solid #4a5568;
border-radius: 8px;
margin-top: 1.5ex;
padding-top: 10px;
}
QGroupBox::title {
subcontrol-origin: margin;
subcontrol-position: top left;
background-color: transparent;
padding: 0 3px;
left: 9px;
}
"""
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.username = None
self.init_ui()
def init_ui(self):
self.setWindowTitle("文档处理工具")
self.setGeometry(100, 100, 1200, 800)
self.setStyleSheet(STYLES_TXT)
# 设置暗色主题调色板
palette = QPalette()
palette.setColor(QPalette.Window, QColor(26, 32, 44)) # #1a202c
palette.setColor(QPalette.WindowText, QColor(226, 232, 240)) # #e2e8f0
palette.setColor(QPalette.Base, QColor(45, 55, 72)) # #2d3748
palette.setColor(QPalette.AlternateBase, QColor(42, 50, 65)) # #2a3241
palette.setColor(QPalette.ToolTipBase, QColor(26, 32, 44)) # #1a202c
palette.setColor(QPalette.ToolTipText, QColor(226, 232, 240)) # #e2e8f0
palette.setColor(QPalette.Text, QColor(226, 232, 240)) # #e2e8f0
palette.setColor(QPalette.Button, QColor(79, 70, 229)) # #4f46e5
palette.setColor(QPalette.ButtonText, QColor(226, 232, 240)) # #e2e8f0
palette.setColor(QPalette.BrightText, Qt.white)
palette.setColor(QPalette.Link, QColor(129, 140, 248)) # #818cf8
palette.setColor(QPalette.Highlight, QColor(129, 140, 248)) # #818cf8
palette.setColor(QPalette.HighlightedText, Qt.white)
palette.setColor(QPalette.Disabled, QPalette.Text, QColor(160, 174, 192)) # #a0aec0
self.setPalette(palette)
# 主窗口部件
self.main_widget = QWidget()
self.main_layout = QHBoxLayout(self.main_widget)
self.main_layout.setContentsMargins(0, 0, 0, 0)
self.main_layout.setSpacing(0)
# 导航栏 (初始隐藏)
self.nav_bar = NavBar("")
self.nav_bar.setObjectName("navBar")
self.nav_bar.hide()
self.nav_bar.nav_item_clicked.connect(self.handle_nav_click)
self.nav_bar.logout_clicked.connect(self.handle_logout)
# 页面堆栈
self.stacked_pages = QStackedWidget()
self.stacked_pages.setObjectName("stackedPages")
# 登录页
self.login_page = LoginPage()
self.login_page.login_success.connect(self.handle_login_success)
# 首页
self.home = Home()
self.home.app_selected.connect(self.handle_app_selected)
# 应用中心页
self.app_center = AppCenter()
self.app_center.app_selected.connect(self.handle_app_selected)
# Word转PDF页
self.word_to_pdf = WordToPDFPage()
# 使用记录页
self.history_page = HistoryPage()
# 设置页(待实现)
self.settings_page = QWidget()
self.settings_page.setObjectName("settingsPage")
# 添加页面
self.stacked_pages.addWidget(self.login_page)
self.stacked_pages.addWidget(self.app_center)
self.stacked_pages.addWidget(self.home)
self.stacked_pages.addWidget(self.word_to_pdf)
self.stacked_pages.addWidget(self.history_page)
self.stacked_pages.addWidget(self.settings_page)
# 主布局
self.main_layout.addWidget(self.nav_bar)
self.main_layout.addWidget(self.stacked_pages, 1) # 设置弹性因子为1
self.setCentralWidget(self.main_widget)
def handle_login_success(self, username):
self.username = username
# 更新导航栏用户信息
self.nav_bar.username = username
self.nav_bar.show()
# 设置默认激活页
self.nav_bar.set_active_nav("home")
self.stacked_pages.setCurrentWidget(self.home)
def handle_logout(self):
self.username = None
self.nav_bar.hide()
self.stacked_pages.setCurrentWidget(self.login_page)
def handle_nav_click(self, nav_id):
# 确保导航栏状态更新
self.nav_bar.set_active_nav(nav_id)
# 根据导航ID切换页面
if nav_id == "home":
self.stacked_pages.setCurrentWidget(self.home)
if nav_id == "app_center":
self.stacked_pages.setCurrentWidget(self.app_center)
elif nav_id == "history":
self.stacked_pages.setCurrentWidget(self.history_page)
elif nav_id == "settings":
self.stacked_pages.setCurrentWidget(self.settings_page)
def handle_app_selected(self, app_id):
try:
if app_id == "word_to_pdf":
self.stacked_pages.setCurrentWidget(self.word_to_pdf)
elif app_id == "history":
# 注意这里假设历史记录页面尚未开发暂时显示word_to_pdf页面
# 实际开发中应替换为正确的历史记录页面
self.stacked_pages.setCurrentWidget(self.word_to_pdf)
else:
# 未开发的应用:弹出提示弹窗
self.show_development_popup(app_id)
except Exception as e:
# 捕获并打印异常信息,避免程序闪退
print(f"处理应用选择时发生错误: {e}")
# 可以选择显示错误弹窗
QMessageBox.critical(self, "错误", f"发生错误: {str(e)}", QMessageBox.Button.Ok)
def show_development_popup(self, app_id):
"""显示开发中弹窗"""
try:
msg_box = QMessageBox(self)
msg_box.setWindowTitle("功能开发中")
msg_box.setText(f"应用 '{app_id}' 正在开发中")
msg_box.setInformativeText("我们正在努力开发此功能,敬请期待!")
msg_box.setIcon(QMessageBox.Icon.Information)
msg_box.setStandardButtons(QMessageBox.Button.Ok)
msg_box.button(QMessageBox.Button.Ok).setText("知道了")
msg_box.exec()
except Exception as e:
print(f"显示弹窗时发生错误: {e}")
def main():
app = QApplication(sys.argv)
app.setStyle('Fusion')
# 设置高DPI支持
app.setAttribute(Qt.AA_EnableHighDpiScaling)
app.setAttribute(Qt.AA_UseHighDpiPixmaps)
window = MainWindow()
window.show()
sys.exit(app.exec_())
if __name__ == "__main__":
main()