feat: 知识管理平台精简版 - PyQt6桌面应用

主要功能:
- 账号管理:添加/编辑/删除账号,测试登录
- 浏览任务:批量浏览应读/选读内容并标记已读
- 截图管理:wkhtmltoimage截图,查看历史
- 金山文档:扫码登录/微信快捷登录,自动上传截图

技术栈:
- PyQt6 GUI框架
- Playwright 浏览器自动化
- SQLite 本地数据存储
- wkhtmltoimage 网页截图

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-01-18 22:16:36 +08:00
commit 83fef6dff2
24 changed files with 6133 additions and 0 deletions

195
ui/main_window.py Normal file
View 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()