feat: 知识管理平台精简版 - PyQt6桌面应用
主要功能: - 账号管理:添加/编辑/删除账号,测试登录 - 浏览任务:批量浏览应读/选读内容并标记已读 - 截图管理:wkhtmltoimage截图,查看历史 - 金山文档:扫码登录/微信快捷登录,自动上传截图 技术栈: - PyQt6 GUI框架 - Playwright 浏览器自动化 - SQLite 本地数据存储 - wkhtmltoimage 网页截图 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
195
ui/main_window.py
Normal file
195
ui/main_window.py
Normal file
@@ -0,0 +1,195 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
主窗口
|
||||
侧边栏导航 + 主内容区 + 日志输出区
|
||||
"""
|
||||
|
||||
from PyQt6.QtWidgets import (
|
||||
QMainWindow, QWidget, QVBoxLayout, QHBoxLayout,
|
||||
QPushButton, QStackedWidget, QFrame, QLabel, QSplitter
|
||||
)
|
||||
from PyQt6.QtCore import Qt
|
||||
|
||||
from .styles import get_stylesheet, LIGHT_THEME, DARK_THEME
|
||||
from .log_widget import LogWidget
|
||||
from .account_widget import AccountWidget
|
||||
from .browse_widget import BrowseWidget
|
||||
from .screenshot_widget import ScreenshotWidget
|
||||
from .kdocs_widget import KDocsWidget
|
||||
from .settings_widget import SettingsWidget
|
||||
|
||||
|
||||
class MainWindow(QMainWindow):
|
||||
"""主窗口"""
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.setWindowTitle("知识管理平台助手 - 精简版")
|
||||
self.setMinimumSize(1000, 700)
|
||||
self.resize(1200, 800)
|
||||
|
||||
self._current_theme = "light"
|
||||
self._setup_ui()
|
||||
self._apply_theme("light")
|
||||
|
||||
def _setup_ui(self):
|
||||
"""设置UI布局"""
|
||||
central_widget = QWidget()
|
||||
self.setCentralWidget(central_widget)
|
||||
|
||||
main_layout = QHBoxLayout(central_widget)
|
||||
main_layout.setContentsMargins(0, 0, 0, 0)
|
||||
main_layout.setSpacing(0)
|
||||
|
||||
# 侧边栏
|
||||
sidebar = self._create_sidebar()
|
||||
main_layout.addWidget(sidebar)
|
||||
|
||||
# 右侧区域(内容 + 日志)
|
||||
right_widget = QWidget()
|
||||
right_layout = QVBoxLayout(right_widget)
|
||||
right_layout.setContentsMargins(0, 0, 0, 0)
|
||||
right_layout.setSpacing(0)
|
||||
|
||||
# 使用分割器可以调整日志区域大小
|
||||
splitter = QSplitter(Qt.Orientation.Vertical)
|
||||
|
||||
# 主内容区
|
||||
self.content_stack = QStackedWidget()
|
||||
self._create_pages()
|
||||
splitter.addWidget(self.content_stack)
|
||||
|
||||
# 日志区域
|
||||
self.log_widget = LogWidget()
|
||||
splitter.addWidget(self.log_widget)
|
||||
|
||||
# 设置初始比例
|
||||
splitter.setSizes([600, 150])
|
||||
|
||||
right_layout.addWidget(splitter)
|
||||
main_layout.addWidget(right_widget, 1)
|
||||
|
||||
# 连接日志信号
|
||||
self._connect_log_signals()
|
||||
|
||||
def _create_sidebar(self) -> QWidget:
|
||||
"""创建侧边栏"""
|
||||
sidebar = QFrame()
|
||||
sidebar.setObjectName("sidebar")
|
||||
sidebar.setFixedWidth(180)
|
||||
|
||||
layout = QVBoxLayout(sidebar)
|
||||
layout.setContentsMargins(0, 0, 0, 0)
|
||||
layout.setSpacing(0)
|
||||
|
||||
# 标题
|
||||
title = QLabel("📋 知识管理助手")
|
||||
title.setObjectName("sidebar_title")
|
||||
title.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
||||
layout.addWidget(title)
|
||||
|
||||
# 分隔线
|
||||
line = QFrame()
|
||||
line.setFrameShape(QFrame.Shape.HLine)
|
||||
line.setStyleSheet("background-color: rgba(255,255,255,0.1);")
|
||||
layout.addWidget(line)
|
||||
|
||||
# 导航按钮
|
||||
self._nav_buttons = []
|
||||
|
||||
nav_items = [
|
||||
("📝 账号管理", 0),
|
||||
("🔄 浏览任务", 1),
|
||||
("📸 截图管理", 2),
|
||||
("📤 金山文档", 3),
|
||||
("⚙️ 系统设置", 4),
|
||||
]
|
||||
|
||||
for text, index in nav_items:
|
||||
btn = QPushButton(text)
|
||||
btn.setCheckable(True)
|
||||
btn.clicked.connect(lambda checked, idx=index: self._switch_page(idx))
|
||||
layout.addWidget(btn)
|
||||
self._nav_buttons.append(btn)
|
||||
|
||||
layout.addStretch()
|
||||
|
||||
# 版本信息
|
||||
version_label = QLabel("v1.0.0")
|
||||
version_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
||||
version_label.setStyleSheet("color: rgba(255,255,255,0.5); font-size: 11px; padding: 8px;")
|
||||
layout.addWidget(version_label)
|
||||
|
||||
# 默认选中第一个
|
||||
self._nav_buttons[0].setChecked(True)
|
||||
|
||||
return sidebar
|
||||
|
||||
def _create_pages(self):
|
||||
"""创建各个页面"""
|
||||
# 账号管理
|
||||
self.account_widget = AccountWidget()
|
||||
self.content_stack.addWidget(self.account_widget)
|
||||
|
||||
# 浏览任务
|
||||
self.browse_widget = BrowseWidget()
|
||||
self.content_stack.addWidget(self.browse_widget)
|
||||
|
||||
# 截图管理
|
||||
self.screenshot_widget = ScreenshotWidget()
|
||||
self.content_stack.addWidget(self.screenshot_widget)
|
||||
|
||||
# 金山文档
|
||||
self.kdocs_widget = KDocsWidget()
|
||||
self.content_stack.addWidget(self.kdocs_widget)
|
||||
|
||||
# 系统设置
|
||||
self.settings_widget = SettingsWidget()
|
||||
self.settings_widget.theme_changed.connect(self._apply_theme)
|
||||
self.content_stack.addWidget(self.settings_widget)
|
||||
|
||||
def _connect_log_signals(self):
|
||||
"""连接各模块的日志信号到日志面板"""
|
||||
self.account_widget.log_signal.connect(self.log_widget.append_log)
|
||||
self.browse_widget.log_signal.connect(self.log_widget.append_log)
|
||||
self.screenshot_widget.log_signal.connect(self.log_widget.append_log)
|
||||
self.kdocs_widget.log_signal.connect(self.log_widget.append_log)
|
||||
self.settings_widget.log_signal.connect(self.log_widget.append_log)
|
||||
|
||||
def _switch_page(self, index: int):
|
||||
"""切换页面"""
|
||||
# 更新导航按钮状态
|
||||
for i, btn in enumerate(self._nav_buttons):
|
||||
btn.setChecked(i == index)
|
||||
|
||||
# 切换页面
|
||||
self.content_stack.setCurrentIndex(index)
|
||||
|
||||
def _apply_theme(self, theme_name: str):
|
||||
"""应用主题"""
|
||||
self._current_theme = theme_name
|
||||
theme = LIGHT_THEME if theme_name == "light" else DARK_THEME
|
||||
self.setStyleSheet(get_stylesheet(theme))
|
||||
|
||||
def log(self, message: str):
|
||||
"""记录日志"""
|
||||
self.log_widget.append_log(message)
|
||||
|
||||
def closeEvent(self, event):
|
||||
"""窗口关闭事件"""
|
||||
# 保存配置
|
||||
from config import get_config, save_config
|
||||
config = get_config()
|
||||
config.theme = self._current_theme
|
||||
save_config(config)
|
||||
|
||||
# 清理金山文档上传器
|
||||
try:
|
||||
from core.kdocs_uploader import get_kdocs_uploader
|
||||
uploader = get_kdocs_uploader()
|
||||
uploader.close()
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
event.accept()
|
||||
Reference in New Issue
Block a user