huangjiunyuna
黄俊源 5 months ago
parent 239ff80ae3
commit c76674752d

@ -1,22 +1,46 @@
# main.py
import sys
import traceback
from PyQt5.QtWidgets import QApplication
from PyQt5.QtCore import Qt
from src.main_window import MainWindow
def main():
"""
应用程序主入口点
- 创建QApplication实例
- 设置应用程序属性
- 创建MainWindow实例
- 显示窗口
- 启动事件循环
- 返回退出码
"""
# TODO: 实现主函数逻辑
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())
try:
# 创建QApplication实例
app = QApplication(sys.argv)
# 设置应用程序属性
app.setApplicationName("隐私学习软件")
app.setApplicationVersion("1.0")
app.setOrganizationName("个人开发者")
# 设置高DPI支持
app.setAttribute(Qt.AA_EnableHighDpiScaling, True)
app.setAttribute(Qt.AA_UseHighDpiPixmaps, True)
# 创建主窗口
window = MainWindow()
window.show()
# 启动事件循环并返回退出码
exit_code = app.exec_()
sys.exit(exit_code)
except Exception as e:
# 打印详细的错误信息
print(f"应用程序发生未捕获的异常: {e}")
traceback.print_exc()
sys.exit(1)
if __name__ == "__main__":
main()

@ -1,8 +1,10 @@
import sys
from PyQt5.QtWidgets import (QApplication, QMainWindow, QTextEdit, QAction,
QFileDialog, QVBoxLayout, QWidget, QLabel, QStatusBar)
from PyQt5.QtGui import QFont, QTextCharFormat, QColor
QFileDialog, QVBoxLayout, QWidget, QLabel, QStatusBar, QMessageBox)
from PyQt5.QtGui import QFont, QTextCharFormat, QColor, QTextCursor
from PyQt5.QtCore import Qt
from src.file_parser import FileParser
from src.typing_logic import TypingLogic
class MainWindow(QMainWindow):
def __init__(self):
@ -14,8 +16,13 @@ class MainWindow(QMainWindow):
- 初始化当前输入位置
- 调用initUI()方法
"""
# TODO: 实现构造函数逻辑
pass
super().__init__()
self.learning_content = ""
self.current_position = 0
self.typing_logic = None
self.text_edit = None
self.status_bar = None
self.initUI()
def initUI(self):
"""
@ -25,8 +32,24 @@ class MainWindow(QMainWindow):
- 创建状态栏并显示"就绪"
- 连接文本变化信号到onTextChanged
"""
# TODO: 实现UI初始化逻辑
pass
# 设置窗口属性
self.setWindowTitle("隐私学习软件 - 仿Word")
self.setGeometry(100, 100, 800, 600)
# 创建中央文本编辑区域
self.text_edit = QTextEdit()
self.text_edit.setFont(QFont("Arial", 12))
self.setCentralWidget(self.text_edit)
# 创建菜单栏
self.createMenuBar()
# 创建状态栏
self.status_bar = self.statusBar()
self.status_bar.showMessage("就绪")
# 连接文本变化信号
self.text_edit.textChanged.connect(self.onTextChanged)
def createMenuBar(self):
"""
@ -35,8 +58,39 @@ class MainWindow(QMainWindow):
- 帮助菜单关于
- 为每个菜单项连接对应的槽函数
"""
# TODO: 实现菜单栏创建逻辑
pass
menu_bar = self.menuBar()
# 文件菜单
file_menu = menu_bar.addMenu('文件')
# 打开动作
open_action = QAction('打开', self)
open_action.setShortcut('Ctrl+O')
open_action.triggered.connect(self.openFile)
file_menu.addAction(open_action)
# 保存动作
save_action = QAction('保存', self)
save_action.setShortcut('Ctrl+S')
save_action.triggered.connect(self.saveFile)
file_menu.addAction(save_action)
# 分隔线
file_menu.addSeparator()
# 退出动作
exit_action = QAction('退出', self)
exit_action.setShortcut('Ctrl+Q')
exit_action.triggered.connect(self.close)
file_menu.addAction(exit_action)
# 帮助菜单
help_menu = menu_bar.addMenu('帮助')
# 关于动作
about_action = QAction('关于', self)
about_action.triggered.connect(self.showAbout)
help_menu.addAction(about_action)
def openFile(self):
"""
@ -46,8 +100,33 @@ class MainWindow(QMainWindow):
- 成功时将内容显示在文本区域重置打字状态
- 失败时显示错误消息框
"""
# TODO: 实现打开文件逻辑
pass
options = QFileDialog.Options()
file_path, _ = QFileDialog.getOpenFileName(
self,
"打开文件",
"",
"文本文件 (*.txt);;Word文档 (*.docx);;所有文件 (*)",
options=options
)
if file_path:
try:
# 解析文件内容
content = FileParser.parse_file(file_path)
self.learning_content = content
# 显示内容到文本编辑区域
self.text_edit.setPlainText(content)
# 重置打字状态
self.typing_logic = TypingLogic(content)
self.current_position = 0
# 更新状态栏
self.status_bar.showMessage(f"已打开文件: {file_path}")
except Exception as e:
# 显示错误消息框
QMessageBox.critical(self, "错误", f"无法打开文件:\n{str(e)}")
def saveFile(self):
"""
@ -56,16 +135,49 @@ class MainWindow(QMainWindow):
- 将文本区域内容写入选定文件
- 返回操作结果
"""
# TODO: 实现保存文件逻辑
pass
options = QFileDialog.Options()
file_path, _ = QFileDialog.getSaveFileName(
self,
"保存文件",
"",
"文本文件 (*.txt);;所有文件 (*)",
options=options
)
if file_path:
try:
# 获取文本编辑区域的内容
content = self.text_edit.toPlainText()
# 写入文件
with open(file_path, 'w', encoding='utf-8') as f:
f.write(content)
# 更新状态栏
self.status_bar.showMessage(f"文件已保存: {file_path}")
return True
except Exception as e:
# 显示错误消息框
QMessageBox.critical(self, "错误", f"无法保存文件:\n{str(e)}")
return False
return False
def showAbout(self):
"""
显示关于对话框
- 显示消息框包含软件名称版本描述
"""
# TODO: 实现关于对话框逻辑
pass
QMessageBox.about(
self,
"关于",
"隐私学习软件 - 仿Word\n\n"
"版本: 1.0\n\n"
"这是一个用于隐私学习的打字练习软件,\n"
"可以加载文档并进行打字练习,\n"
"帮助提高打字速度和准确性。"
)
def onTextChanged(self):
"""
@ -74,8 +186,30 @@ class MainWindow(QMainWindow):
- 调用打字逻辑检查输入正确性
- 更新高亮显示和状态栏
"""
# TODO: 实现文本变化处理逻辑
pass
if self.typing_logic is None:
return
# 获取当前文本内容
current_text = self.text_edit.toPlainText()
# 调用打字逻辑检查输入正确性
result = self.typing_logic.check_input(current_text)
# 更新高亮显示
if result['correct']:
self.highlightText(len(current_text), QColor('lightgreen'))
else:
# 高亮显示错误部分
self.highlightText(len(current_text), QColor('lightcoral'))
# 更新状态栏
progress = self.typing_logic.get_progress()
accuracy = result.get('accuracy', 0) * 100
self.status_bar.showMessage(
f"进度: {progress['percentage']:.1f}% | "
f"准确率: {accuracy:.1f}% | "
f"位置: {result['position']}/{progress['total']}"
)
def highlightText(self, position, color):
"""
@ -84,5 +218,24 @@ class MainWindow(QMainWindow):
- 应用背景颜色格式
- 恢复光标位置
"""
# TODO: 实现文本高亮逻辑
pass
# 创建文本格式
format = QTextCharFormat()
format.setBackground(color)
# 获取文本游标
cursor = self.text_edit.textCursor()
# 保存当前光标位置
current_pos = cursor.position()
# 选择从开始到指定位置的文本
cursor.select(QTextCursor.Document)
cursor.setPosition(0, QTextCursor.MoveAnchor)
cursor.setPosition(position, QTextCursor.KeepAnchor)
# 应用格式
cursor.mergeCharFormat(format)
# 恢复光标位置
cursor.setPosition(current_pos)
self.text_edit.setTextCursor(cursor)

@ -6,8 +6,11 @@ class TypingLogic:
- 初始化当前索引为0
- 初始化错误计数为0
"""
# TODO: 实现构造函数逻辑
pass
self.learning_content = learning_content
self.current_index = 0
self.error_count = 0
self.total_chars = len(learning_content)
self.typed_chars = 0
def check_input(self, user_text: str) -> dict:
"""
@ -22,17 +25,54 @@ class TypingLogic:
* completed: 布尔值是否完成
* accuracy: 浮点数准确率
"""
# TODO: 实现输入检查逻辑
pass
# 更新已输入字符数
self.typed_chars = len(user_text)
# 如果用户输入的字符数超过了学习材料的长度,截取到相同长度
if len(user_text) > self.total_chars:
user_text = user_text[:self.total_chars]
# 检查当前输入是否正确
correct = True
expected_char = ''
if self.current_index < self.total_chars:
expected_char = self.learning_content[self.current_index]
if len(user_text) > self.current_index and user_text[self.current_index] != expected_char:
correct = False
self.error_count += 1
else:
# 已经完成所有输入
return {
"correct": True,
"expected": "",
"position": self.current_index,
"completed": True,
"accuracy": self._calculate_accuracy()
}
# 更新当前索引
self.current_index = len(user_text)
# 检查是否完成
completed = self.current_index >= self.total_chars
return {
"correct": correct,
"expected": expected_char,
"position": self.current_index,
"completed": completed,
"accuracy": self._calculate_accuracy()
}
def get_expected_text(self) -> str:
def get_expected_text(self, length: int = 10) -> str:
"""
获取用户接下来应该输入的内容
- 返回从当前位置开始的一定长度文本如10个字符
- 处理文本结束情况
"""
# TODO: 实现期望文本获取逻辑
pass
start_pos = self.current_index
end_pos = min(start_pos + length, self.total_chars)
return self.learning_content[start_pos:end_pos]
def get_progress(self) -> dict:
"""
@ -42,8 +82,17 @@ class TypingLogic:
- percentage: 浮点数完成百分比
- remaining: 整数剩余字符数
"""
# TODO: 实现进度获取逻辑
pass
current = self.current_index
total = self.total_chars
percentage = (current / total * 100) if total > 0 else 0
remaining = max(0, total - current)
return {
"current": current,
"total": total,
"percentage": percentage,
"remaining": remaining
}
def reset(self, new_content: str = None):
"""
@ -52,8 +101,12 @@ class TypingLogic:
- 重置错误计数
- 如果提供了新内容更新学习材料
"""
# TODO: 实现重置逻辑
pass
if new_content is not None:
self.learning_content = new_content
self.total_chars = len(new_content)
self.current_index = 0
self.error_count = 0
self.typed_chars = 0
def get_statistics(self) -> dict:
"""
@ -63,5 +116,19 @@ class TypingLogic:
- error_count: 整数错误次数
- accuracy_rate: 浮点数准确率
"""
# TODO: 实现统计信息获取逻辑
pass
return {
"total_chars": self.total_chars,
"typed_chars": self.typed_chars,
"error_count": self.error_count,
"accuracy_rate": self._calculate_accuracy()
}
def _calculate_accuracy(self) -> float:
"""
计算准确率
"""
if self.typed_chars == 0:
return 0.0
# 准确率 = (已输入字符数 - 错误次数) / 已输入字符数
accuracy = (self.typed_chars - self.error_count) / self.typed_chars
return max(0.0, accuracy) # 确保准确率不为负数
Loading…
Cancel
Save