Files
QQclawdbot-know-how/main_window.py
xiaji 0ab3d4f9c1 Initial commit: 知识库管理器应用
- 实现基于 PySide6 的 GUI 界面
- 集成 FastAPI 知识库服务器 API
- 支持查看、编辑、提交 Markdown 文件
- 包含完整的 pytest-qt 测试套件
- 添加功能列表文档
2026-01-30 12:03:12 +08:00

203 lines
7.2 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 PySide6.QtWidgets import (
QApplication, QMainWindow, QWidget, QVBoxLayout, QHBoxLayout,
QLabel, QLineEdit, QPushButton, QListWidget, QTextEdit,
QMessageBox, QSplitter, QFileDialog
)
from PySide6.QtCore import Qt
from api_client import KnowledgeBaseAPI
class KnowledgeBaseApp(QMainWindow):
def __init__(self):
super().__init__()
self.api: Optional[KnowledgeBaseAPI] = None
self.current_filename: Optional[str] = None
self.init_ui()
def init_ui(self):
self.setWindowTitle('知识库管理器')
self.setGeometry(100, 100, 1200, 800)
central_widget = QWidget()
self.setCentralWidget(central_widget)
main_layout = QVBoxLayout(central_widget)
# 服务器地址配置区域
server_layout = QHBoxLayout()
server_label = QLabel('服务器地址:')
self.server_input = QLineEdit('http://43.134.1.17:8800/')
self.server_input.setMinimumWidth(300)
self.config_button = QPushButton('配置')
self.config_button.clicked.connect(self.configure_server)
self.refresh_button = QPushButton('刷新列表')
self.refresh_button.clicked.connect(self.refresh_file_list)
server_layout.addWidget(server_label)
server_layout.addWidget(self.server_input)
server_layout.addWidget(self.config_button)
server_layout.addWidget(self.refresh_button)
server_layout.addStretch()
main_layout.addLayout(server_layout)
# 主内容区域(使用分割器)
splitter = QSplitter(Qt.Horizontal)
# 左侧:文件列表
left_widget = QWidget()
left_layout = QVBoxLayout(left_widget)
list_label = QLabel('文件列表 (.md):')
self.file_list = QListWidget()
self.file_list.itemClicked.connect(self.load_file)
left_layout.addWidget(list_label)
left_layout.addWidget(self.file_list)
# 右侧:编辑区域
right_widget = QWidget()
right_layout = QVBoxLayout(right_widget)
filename_layout = QHBoxLayout()
filename_label = QLabel('文件名:')
self.filename_input = QLineEdit()
self.filename_input.setPlaceholderText('输入文件名例如example.md')
filename_layout.addWidget(filename_label)
filename_layout.addWidget(self.filename_input)
self.text_editor = QTextEdit()
self.text_editor.setPlaceholderText('在此编辑 Markdown 内容...')
button_layout = QHBoxLayout()
self.save_button = QPushButton('保存到服务器')
self.save_button.clicked.connect(self.save_file)
self.post_button = QPushButton('提交新文件')
self.post_button.clicked.connect(self.post_new_file)
button_layout.addWidget(self.save_button)
button_layout.addWidget(self.post_button)
right_layout.addLayout(filename_layout)
right_layout.addWidget(self.text_editor)
right_layout.addLayout(button_layout)
splitter.addWidget(left_widget)
splitter.addWidget(right_widget)
splitter.setSizes([300, 900])
main_layout.addWidget(splitter)
# 状态栏
self.status_label = QLabel('就绪')
self.statusBar().addWidget(self.status_label)
def configure_server(self):
server_url = self.server_input.text().strip()
if not server_url:
QMessageBox.warning(self, '警告', '请输入服务器地址')
return
self.api = KnowledgeBaseAPI(server_url)
if self.api.test_connection():
self.status_label.setText(f'已连接到服务器: {server_url}')
QMessageBox.information(self, '成功', '服务器配置成功!')
self.refresh_file_list()
else:
QMessageBox.critical(self, '错误', '无法连接到服务器,请检查地址是否正确')
self.status_label.setText('连接失败')
def refresh_file_list(self):
if not self.api:
QMessageBox.warning(self, '警告', '请先配置服务器')
return
try:
files = self.api.get_file_list()
self.file_list.clear()
# 只显示 .md 文件
md_files = [f for f in files if f.endswith('.md')]
self.file_list.addItems(md_files)
self.status_label.setText(f'已加载 {len(md_files)} 个文件')
except Exception as e:
QMessageBox.critical(self, '错误', str(e))
self.status_label.setText('加载文件列表失败')
def load_file(self, item):
filename = item.text()
self.current_filename = filename
self.filename_input.setText(filename)
try:
content = self.api.get_file(filename)
self.text_editor.setPlainText(content)
self.status_label.setText(f'已加载文件: {filename}')
except Exception as e:
QMessageBox.critical(self, '错误', str(e))
self.status_label.setText('加载文件失败')
def save_file(self):
if not self.api:
QMessageBox.warning(self, '警告', '请先配置服务器')
return
if not self.current_filename:
QMessageBox.warning(self, '警告', '请先选择一个文件')
return
content = self.text_editor.toPlainText()
try:
self.api.post_file(self.current_filename, content)
QMessageBox.information(self, '成功', f'文件 {self.current_filename} 保存成功!')
self.status_label.setText(f'已保存文件: {self.current_filename}')
except Exception as e:
QMessageBox.critical(self, '错误', str(e))
self.status_label.setText('保存文件失败')
def post_new_file(self):
if not self.api:
QMessageBox.warning(self, '警告', '请先配置服务器')
return
filename = self.filename_input.text().strip()
if not filename:
QMessageBox.warning(self, '警告', '请输入文件名')
return
if not filename.endswith('.md'):
filename += '.md'
self.filename_input.setText(filename)
content = self.text_editor.toPlainText()
if not content:
QMessageBox.warning(self, '警告', '请输入文件内容')
return
try:
self.api.post_file(filename, content)
QMessageBox.information(self, '成功', f'文件 {filename} 提交成功!')
self.current_filename = filename
self.status_label.setText(f'已提交文件: {filename}')
self.refresh_file_list()
except Exception as e:
QMessageBox.critical(self, '错误', str(e))
self.status_label.setText('提交文件失败')
def main():
app = QApplication(sys.argv)
window = KnowledgeBaseApp()
window.show()
sys.exit(app.exec())
if __name__ == '__main__':
main()