commit
83bbd75cb4
@ -0,0 +1,8 @@
|
||||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
# Editor-based HTTP Client requests
|
||||
/httpRequests/
|
||||
# Datasource local storage ignored files
|
||||
/dataSources/
|
||||
/dataSources.local.xml
|
@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="PYTHON_MODULE" version="4">
|
||||
<component name="NewModuleRootManager">
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<excludeFolder url="file://$MODULE_DIR$/.venv" />
|
||||
</content>
|
||||
<orderEntry type="jdk" jdkName="Python 3.9 (OCRmyPDF-GUI)" jdkType="Python SDK" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
<component name="PyDocumentationSettings">
|
||||
<option name="format" value="PLAIN" />
|
||||
<option name="myDocStringFormat" value="Plain" />
|
||||
</component>
|
||||
</module>
|
@ -0,0 +1,6 @@
|
||||
<component name="InspectionProjectProfileManager">
|
||||
<settings>
|
||||
<option name="USE_PROJECT_PROFILE" value="false" />
|
||||
<version value="1.0" />
|
||||
</settings>
|
||||
</component>
|
@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.9 (OCRmyPDF-GUI)" project-jdk-type="Python SDK" />
|
||||
</project>
|
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/OCRmyPDF-GUI.iml" filepath="$PROJECT_DIR$/.idea/OCRmyPDF-GUI.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
Binary file not shown.
@ -0,0 +1,2 @@
|
||||
PySide6>=6.5.0
|
||||
pytest>=7.0.0
|
@ -0,0 +1,18 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
OCRmyPDF GUI 启动脚本
|
||||
"""
|
||||
|
||||
import sys
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
# 添加项目根目录到Python路径
|
||||
project_root = Path(__file__).resolve().parent
|
||||
sys.path.insert(0, str(project_root))
|
||||
|
||||
# 导入主模块
|
||||
from src.main import main
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
@ -0,0 +1 @@
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1 @@
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1 @@
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,363 @@
|
||||
from PySide6.QtWidgets import (
|
||||
QDialog, QVBoxLayout, QHBoxLayout, QGroupBox,
|
||||
QPushButton, QLabel, QFileDialog, QProgressBar,
|
||||
QComboBox, QCheckBox, QListWidget, QMessageBox,
|
||||
QRadioButton
|
||||
)
|
||||
from PySide6.QtCore import Qt, Signal, Slot, QThread
|
||||
from pathlib import Path
|
||||
import os
|
||||
|
||||
from src.core.ocr_engine import OCREngine
|
||||
from src.core.config import Config
|
||||
from src.utils.file_utils import FileUtils
|
||||
|
||||
class BatchOCRWorker(QThread):
|
||||
"""批量OCR处理线程"""
|
||||
progress_updated = Signal(int, int, str, bool)
|
||||
file_progress_updated = Signal(int, int) # 当前文件的进度
|
||||
finished = Signal(dict)
|
||||
|
||||
def __init__(self, engine, files, output_dir, options):
|
||||
super().__init__()
|
||||
self.engine = engine
|
||||
self.files = files
|
||||
self.output_dir = output_dir
|
||||
self.options = options
|
||||
|
||||
def run(self):
|
||||
results = self.engine.process_batch(
|
||||
self.files,
|
||||
self.output_dir,
|
||||
self.options,
|
||||
lambda current, total, file, success: self.progress_updated.emit(current, total, file, success)
|
||||
)
|
||||
self.finished.emit(results)
|
||||
|
||||
class BatchDialog(QDialog):
|
||||
"""批量处理对话框"""
|
||||
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent)
|
||||
self.setWindowTitle("批量OCR处理")
|
||||
self.resize(700, 500)
|
||||
|
||||
self.config = Config()
|
||||
self.ocr_engine = OCREngine()
|
||||
self.selected_files = []
|
||||
|
||||
self.init_ui()
|
||||
|
||||
def init_ui(self):
|
||||
"""初始化UI"""
|
||||
# 主布局
|
||||
main_layout = QVBoxLayout(self)
|
||||
|
||||
# 文件选择区域
|
||||
file_group = QGroupBox("文件选择")
|
||||
file_layout = QVBoxLayout(file_group)
|
||||
|
||||
file_buttons_layout = QHBoxLayout()
|
||||
self.add_files_btn = QPushButton("添加文件")
|
||||
self.add_files_btn.clicked.connect(self.add_files)
|
||||
self.add_folder_btn = QPushButton("添加文件夹")
|
||||
self.add_folder_btn.clicked.connect(self.add_folder)
|
||||
self.clear_files_btn = QPushButton("清除")
|
||||
self.clear_files_btn.clicked.connect(self.clear_files)
|
||||
self.select_all_btn = QPushButton("全选")
|
||||
self.select_all_btn.clicked.connect(self.select_all_files)
|
||||
|
||||
file_buttons_layout.addWidget(self.add_files_btn)
|
||||
file_buttons_layout.addWidget(self.add_folder_btn)
|
||||
file_buttons_layout.addWidget(self.clear_files_btn)
|
||||
file_buttons_layout.addWidget(self.select_all_btn)
|
||||
file_buttons_layout.addStretch()
|
||||
|
||||
self.file_list = QListWidget()
|
||||
self.file_list.setSelectionMode(QListWidget.SelectionMode.ExtendedSelection)
|
||||
|
||||
file_layout.addLayout(file_buttons_layout)
|
||||
file_layout.addWidget(self.file_list)
|
||||
|
||||
# 输出选项
|
||||
output_group = QGroupBox("输出选项")
|
||||
output_layout = QVBoxLayout(output_group)
|
||||
|
||||
# 输出目录
|
||||
output_dir_layout = QHBoxLayout()
|
||||
output_dir_layout.addWidget(QLabel("输出目录:"))
|
||||
self.output_dir_edit = QComboBox()
|
||||
self.output_dir_edit.setEditable(True)
|
||||
self.output_dir_edit.addItems(self.config.get('recent_output_dirs', []))
|
||||
self.output_dir_btn = QPushButton("浏览...")
|
||||
self.output_dir_btn.clicked.connect(self.select_output_dir)
|
||||
output_dir_layout.addWidget(self.output_dir_edit, 1)
|
||||
output_dir_layout.addWidget(self.output_dir_btn)
|
||||
|
||||
# 输出文件命名
|
||||
naming_layout = QHBoxLayout()
|
||||
naming_layout.addWidget(QLabel("输出文件命名:"))
|
||||
self.naming_combo = QComboBox()
|
||||
self.naming_combo.addItems(["原文件名_ocr", "原文件名", "自定义前缀_原文件名"])
|
||||
naming_layout.addWidget(self.naming_combo, 1)
|
||||
|
||||
output_layout.addLayout(output_dir_layout)
|
||||
output_layout.addLayout(naming_layout)
|
||||
|
||||
# OCR选项
|
||||
ocr_group = QGroupBox("OCR选项")
|
||||
ocr_layout = QVBoxLayout(ocr_group)
|
||||
|
||||
# 使用配置文件
|
||||
config_layout = QHBoxLayout()
|
||||
config_layout.addWidget(QLabel("使用配置文件:"))
|
||||
self.config_combo = QComboBox()
|
||||
self.config_combo.addItems(["默认配置"])
|
||||
self.save_config_btn = QPushButton("保存当前配置")
|
||||
self.save_config_btn.clicked.connect(self.save_current_config)
|
||||
config_layout.addWidget(self.config_combo, 1)
|
||||
config_layout.addWidget(self.save_config_btn)
|
||||
|
||||
# 处理选项
|
||||
self.deskew_cb = QCheckBox("自动校正倾斜页面")
|
||||
self.deskew_cb.setChecked(self.config.get('default_options.deskew', True))
|
||||
|
||||
self.rotate_cb = QCheckBox("自动旋转页面")
|
||||
self.rotate_cb.setChecked(self.config.get('default_options.rotate_pages', True))
|
||||
|
||||
self.clean_cb = QCheckBox("清理图像")
|
||||
self.clean_cb.setChecked(self.config.get('default_options.clean', False))
|
||||
|
||||
self.optimize_cb = QCheckBox("优化输出文件大小")
|
||||
self.optimize_cb.setChecked(self.config.get('default_options.optimize', True))
|
||||
|
||||
# 添加到布局
|
||||
ocr_layout.addLayout(config_layout)
|
||||
ocr_layout.addWidget(self.deskew_cb)
|
||||
ocr_layout.addWidget(self.rotate_cb)
|
||||
ocr_layout.addWidget(self.clean_cb)
|
||||
ocr_layout.addWidget(self.optimize_cb)
|
||||
|
||||
# 进度条
|
||||
progress_group = QGroupBox("处理进度")
|
||||
progress_layout = QVBoxLayout(progress_group)
|
||||
|
||||
# 总进度
|
||||
total_progress_layout = QHBoxLayout()
|
||||
total_progress_layout.addWidget(QLabel("总进度:"))
|
||||
self.total_progress_bar = QProgressBar()
|
||||
total_progress_layout.addWidget(self.total_progress_bar)
|
||||
|
||||
# 当前文件进度
|
||||
file_progress_layout = QHBoxLayout()
|
||||
file_progress_layout.addWidget(QLabel("当前文件:"))
|
||||
self.file_progress_bar = QProgressBar()
|
||||
file_progress_layout.addWidget(self.file_progress_bar)
|
||||
|
||||
self.status_label = QLabel("准备就绪")
|
||||
|
||||
progress_layout.addLayout(total_progress_layout)
|
||||
progress_layout.addLayout(file_progress_layout)
|
||||
progress_layout.addWidget(self.status_label)
|
||||
|
||||
# 操作按钮
|
||||
buttons_layout = QHBoxLayout()
|
||||
self.start_btn = QPushButton("开始批量处理")
|
||||
self.start_btn.clicked.connect(self.start_batch_ocr)
|
||||
self.cancel_btn = QPushButton("取消")
|
||||
self.cancel_btn.clicked.connect(self.cancel_batch_ocr)
|
||||
self.cancel_btn.setEnabled(False)
|
||||
self.close_btn = QPushButton("关闭")
|
||||
self.close_btn.clicked.connect(self.reject)
|
||||
|
||||
buttons_layout.addStretch()
|
||||
buttons_layout.addWidget(self.start_btn)
|
||||
buttons_layout.addWidget(self.cancel_btn)
|
||||
buttons_layout.addWidget(self.close_btn)
|
||||
|
||||
# 添加所有元素到主布局
|
||||
main_layout.addWidget(file_group)
|
||||
main_layout.addWidget(output_group)
|
||||
main_layout.addWidget(ocr_group)
|
||||
main_layout.addWidget(progress_group)
|
||||
main_layout.addLayout(buttons_layout)
|
||||
|
||||
def add_files(self):
|
||||
"""添加文件"""
|
||||
files, _ = QFileDialog.getOpenFileNames(
|
||||
self,
|
||||
"选择PDF文件",
|
||||
"",
|
||||
"PDF文件 (*.pdf);;所有文件 (*.*)"
|
||||
)
|
||||
|
||||
if files:
|
||||
self.add_files_to_list(files)
|
||||
|
||||
def add_folder(self):
|
||||
"""添加文件夹"""
|
||||
folder = QFileDialog.getExistingDirectory(
|
||||
self,
|
||||
"选择包含PDF文件的文件夹"
|
||||
)
|
||||
|
||||
if folder:
|
||||
pdf_files = FileUtils.get_pdf_files_in_dir(folder, recursive=True)
|
||||
if pdf_files:
|
||||
self.add_files_to_list(pdf_files)
|
||||
else:
|
||||
QMessageBox.information(self, "提示", "所选文件夹中未找到PDF文件")
|
||||
|
||||
def add_files_to_list(self, files):
|
||||
"""添加文件到列表"""
|
||||
# 过滤已存在的文件
|
||||
new_files = [f for f in files if f not in self.selected_files]
|
||||
if not new_files:
|
||||
return
|
||||
|
||||
self.selected_files.extend(new_files)
|
||||
|
||||
# 更新列表显示
|
||||
self.file_list.clear()
|
||||
for file in self.selected_files:
|
||||
self.file_list.addItem(Path(file).name)
|
||||
|
||||
# 更新状态
|
||||
self.status_label.setText(f"已添加 {len(self.selected_files)} 个文件")
|
||||
|
||||
# 保存最近使用的文件
|
||||
for file in new_files:
|
||||
self.config.add_recent_file(file)
|
||||
|
||||
def clear_files(self):
|
||||
"""清除文件列表"""
|
||||
self.selected_files = []
|
||||
self.file_list.clear()
|
||||
self.status_label.setText("文件列表已清空")
|
||||
|
||||
def select_all_files(self):
|
||||
"""全选文件"""
|
||||
self.file_list.selectAll()
|
||||
|
||||
def select_output_dir(self):
|
||||
"""选择输出目录"""
|
||||
dir_path = QFileDialog.getExistingDirectory(
|
||||
self,
|
||||
"选择输出目录",
|
||||
""
|
||||
)
|
||||
|
||||
if dir_path:
|
||||
self.output_dir_edit.setCurrentText(dir_path)
|
||||
self.config.add_recent_output_dir(dir_path)
|
||||
|
||||
def save_current_config(self):
|
||||
"""保存当前配置"""
|
||||
# 这里可以实现保存当前配置的功能
|
||||
QMessageBox.information(self, "提示", "配置保存功能尚未实现")
|
||||
|
||||
def start_batch_ocr(self):
|
||||
"""开始批量OCR处理"""
|
||||
if not self.selected_files:
|
||||
QMessageBox.warning(self, "警告", "未选择文件")
|
||||
return
|
||||
|
||||
output_dir = self.output_dir_edit.currentText()
|
||||
if not output_dir:
|
||||
QMessageBox.warning(self, "警告", "未选择输出目录")
|
||||
return
|
||||
|
||||
# 确保输出目录存在
|
||||
if not FileUtils.ensure_dir(output_dir):
|
||||
QMessageBox.critical(self, "错误", f"无法创建输出目录: {output_dir}")
|
||||
return
|
||||
|
||||
# 收集OCR选项
|
||||
options = {
|
||||
"deskew": self.deskew_cb.isChecked(),
|
||||
"rotate_pages": self.rotate_cb.isChecked(),
|
||||
"clean": self.clean_cb.isChecked(),
|
||||
"optimize": self.optimize_cb.isChecked()
|
||||
}
|
||||
|
||||
# 禁用UI元素
|
||||
self.start_btn.setEnabled(False)
|
||||
self.cancel_btn.setEnabled(True)
|
||||
self.add_files_btn.setEnabled(False)
|
||||
self.add_folder_btn.setEnabled(False)
|
||||
self.clear_files_btn.setEnabled(False)
|
||||
self.select_all_btn.setEnabled(False)
|
||||
self.output_dir_btn.setEnabled(False)
|
||||
self.output_dir_edit.setEnabled(False)
|
||||
|
||||
# 重置进度条
|
||||
self.total_progress_bar.setValue(0)
|
||||
self.file_progress_bar.setValue(0)
|
||||
self.status_label.setText("处理中...")
|
||||
|
||||
# 创建并启动工作线程
|
||||
self.worker = BatchOCRWorker(
|
||||
self.ocr_engine,
|
||||
self.selected_files,
|
||||
output_dir,
|
||||
options
|
||||
)
|
||||
self.worker.progress_updated.connect(self.update_progress)
|
||||
self.worker.file_progress_updated.connect(self.update_file_progress)
|
||||
self.worker.finished.connect(self.ocr_finished)
|
||||
self.worker.start()
|
||||
|
||||
def cancel_batch_ocr(self):
|
||||
"""取消批量OCR处理"""
|
||||
if hasattr(self, 'worker') and self.worker.isRunning():
|
||||
self.worker.terminate()
|
||||
self.worker.wait()
|
||||
self.status_label.setText("处理已取消")
|
||||
|
||||
# 启用UI元素
|
||||
self.enable_ui()
|
||||
|
||||
def enable_ui(self):
|
||||
"""启用UI元素"""
|
||||
self.start_btn.setEnabled(True)
|
||||
self.cancel_btn.setEnabled(False)
|
||||
self.add_files_btn.setEnabled(True)
|
||||
self.add_folder_btn.setEnabled(True)
|
||||
self.clear_files_btn.setEnabled(True)
|
||||
self.select_all_btn.setEnabled(True)
|
||||
self.output_dir_btn.setEnabled(True)
|
||||
self.output_dir_edit.setEnabled(True)
|
||||
|
||||
@Slot(int, int, str, bool)
|
||||
def update_progress(self, current, total, file, success):
|
||||
"""更新总进度"""
|
||||
percent = int(current * 100 / total)
|
||||
self.total_progress_bar.setValue(percent)
|
||||
|
||||
file_name = Path(file).name
|
||||
status = "成功" if success else "失败"
|
||||
self.status_label.setText(f"处理 {file_name}: {status} ({current}/{total})")
|
||||
|
||||
@Slot(int, int)
|
||||
def update_file_progress(self, current, total):
|
||||
"""更新当前文件进度"""
|
||||
percent = int(current * 100 / total) if total > 0 else 0
|
||||
self.file_progress_bar.setValue(percent)
|
||||
|
||||
@Slot(dict)
|
||||
def ocr_finished(self, results):
|
||||
"""OCR处理完成"""
|
||||
success_count = sum(1 for success in results.values() if success)
|
||||
total_count = len(results)
|
||||
|
||||
self.status_label.setText(f"处理完成: {success_count}/{total_count} 文件成功")
|
||||
|
||||
# 启用UI元素
|
||||
self.enable_ui()
|
||||
|
||||
# 显示完成消息
|
||||
QMessageBox.information(
|
||||
self,
|
||||
"处理完成",
|
||||
f"批量OCR处理已完成\n成功: {success_count} 文件\n失败: {total_count - success_count} 文件"
|
||||
)
|
@ -0,0 +1,211 @@
|
||||
from PySide6.QtWidgets import (
|
||||
QDialog, QVBoxLayout, QHBoxLayout, QTabWidget,
|
||||
QPushButton, QLabel, QComboBox, QCheckBox,
|
||||
QGroupBox, QSpinBox, QRadioButton
|
||||
)
|
||||
from PySide6.QtCore import Qt
|
||||
|
||||
from src.core.config import Config
|
||||
|
||||
class SettingsDialog(QDialog):
|
||||
"""设置对话框"""
|
||||
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent)
|
||||
self.setWindowTitle("设置")
|
||||
self.resize(500, 400)
|
||||
|
||||
self.config = Config()
|
||||
self.init_ui()
|
||||
|
||||
def init_ui(self):
|
||||
"""初始化UI"""
|
||||
# 主布局
|
||||
main_layout = QVBoxLayout(self)
|
||||
|
||||
# 创建选项卡
|
||||
tab_widget = QTabWidget()
|
||||
main_layout.addWidget(tab_widget)
|
||||
|
||||
# 常规选项卡
|
||||
general_tab = QWidget()
|
||||
tab_widget.addTab(general_tab, "常规")
|
||||
self.setup_general_tab(general_tab)
|
||||
|
||||
# OCR选项卡
|
||||
ocr_tab = QWidget()
|
||||
tab_widget.addTab(ocr_tab, "OCR")
|
||||
self.setup_ocr_tab(ocr_tab)
|
||||
|
||||
# 界面选项卡
|
||||
ui_tab = QWidget()
|
||||
tab_widget.addTab(ui_tab, "界面")
|
||||
self.setup_ui_tab(ui_tab)
|
||||
|
||||
# 按钮区域
|
||||
button_layout = QHBoxLayout()
|
||||
button_layout.addStretch()
|
||||
|
||||
self.ok_btn = QPushButton("确定")
|
||||
self.ok_btn.clicked.connect(self.accept)
|
||||
self.cancel_btn = QPushButton("取消")
|
||||
self.cancel_btn.clicked.connect(self.reject)
|
||||
|
||||
button_layout.addWidget(self.ok_btn)
|
||||
button_layout.addWidget(self.cancel_btn)
|
||||
|
||||
main_layout.addLayout(button_layout)
|
||||
|
||||
def setup_general_tab(self, tab):
|
||||
"""设置常规选项卡"""
|
||||
layout = QVBoxLayout(tab)
|
||||
|
||||
# 启动选项
|
||||
startup_group = QGroupBox("启动选项")
|
||||
startup_layout = QVBoxLayout(startup_group)
|
||||
|
||||
self.check_update_cb = QCheckBox("启动时检查更新")
|
||||
self.check_update_cb.setChecked(self.config.get('general.check_update_on_startup', False))
|
||||
|
||||
self.show_welcome_cb = QCheckBox("显示欢迎页面")
|
||||
self.show_welcome_cb.setChecked(self.config.get('general.show_welcome', True))
|
||||
|
||||
self.remember_window_cb = QCheckBox("记住窗口大小和位置")
|
||||
self.remember_window_cb.setChecked(self.config.get('general.remember_window_geometry', True))
|
||||
|
||||
startup_layout.addWidget(self.check_update_cb)
|
||||
startup_layout.addWidget(self.show_welcome_cb)
|
||||
startup_layout.addWidget(self.remember_window_cb)
|
||||
|
||||
# 文件历史
|
||||
history_group = QGroupBox("文件历史")
|
||||
history_layout = QVBoxLayout(history_group)
|
||||
|
||||
recent_files_layout = QHBoxLayout()
|
||||
recent_files_layout.addWidget(QLabel("最近文件数量:"))
|
||||
self.recent_files_spin = QSpinBox()
|
||||
self.recent_files_spin.setRange(0, 30)
|
||||
self.recent_files_spin.setValue(self.config.get('general.max_recent_files', 10))
|
||||
recent_files_layout.addWidget(self.recent_files_spin)
|
||||
recent_files_layout.addStretch()
|
||||
|
||||
self.clear_history_btn = QPushButton("清除历史记录")
|
||||
self.clear_history_btn.clicked.connect(self.clear_history)
|
||||
|
||||
history_layout.addLayout(recent_files_layout)
|
||||
history_layout.addWidget(self.clear_history_btn)
|
||||
|
||||
layout.addWidget(startup_group)
|
||||
layout.addWidget(history_group)
|
||||
layout.addStretch()
|
||||
|
||||
def setup_ocr_tab(self, tab):
|
||||
"""设置OCR选项卡"""
|
||||
layout = QVBoxLayout(tab)
|
||||
|
||||
# 默认选项
|
||||
options_group = QGroupBox("默认处理选项")
|
||||
options_layout = QVBoxLayout(options_group)
|
||||
|
||||
self.deskew_cb = QCheckBox("自动校正倾斜页面")
|
||||
self.deskew_cb.setChecked(self.config.get('default_options.deskew', True))
|
||||
|
||||
self.rotate_cb = QCheckBox("自动旋转页面")
|
||||
self.rotate_cb.setChecked(self.config.get('default_options.rotate_pages', True))
|
||||
|
||||
self.clean_cb = QCheckBox("清理图像")
|
||||
self.clean_cb.setChecked(self.config.get('default_options.clean', False))
|
||||
|
||||
self.optimize_cb = QCheckBox("优化输出文件大小")
|
||||
self.optimize_cb.setChecked(self.config.get('default_options.optimize', True))
|
||||
|
||||
options_layout.addWidget(self.deskew_cb)
|
||||
options_layout.addWidget(self.rotate_cb)
|
||||
options_layout.addWidget(self.clean_cb)
|
||||
options_layout.addWidget(self.optimize_cb)
|
||||
|
||||
# 输出类型
|
||||
output_group = QGroupBox("默认输出类型")
|
||||
output_layout = QVBoxLayout(output_group)
|
||||
|
||||
self.output_type_combo = QComboBox()
|
||||
self.output_type_combo.addItems(["pdf", "pdfa", "pdfa-1", "pdfa-2", "pdfa-3"])
|
||||
self.output_type_combo.setCurrentText(self.config.get('default_options.output_type', 'pdfa'))
|
||||
|
||||
output_layout.addWidget(self.output_type_combo)
|
||||
|
||||
layout.addWidget(options_group)
|
||||
layout.addWidget(output_group)
|
||||
layout.addStretch()
|
||||
|
||||
def setup_ui_tab(self, tab):
|
||||
"""设置界面选项卡"""
|
||||
layout = QVBoxLayout(tab)
|
||||
|
||||
# 语言
|
||||
language_group = QGroupBox("界面语言")
|
||||
language_layout = QVBoxLayout(language_group)
|
||||
|
||||
self.ui_language_combo = QComboBox()
|
||||
self.ui_language_combo.addItems(["简体中文", "English"])
|
||||
current_lang = "简体中文" if self.config.get('ui.language') == 'zh_CN' else "English"
|
||||
self.ui_language_combo.setCurrentText(current_lang)
|
||||
|
||||
language_layout.addWidget(self.ui_language_combo)
|
||||
|
||||
# 主题
|
||||
theme_group = QGroupBox("主题")
|
||||
theme_layout = QVBoxLayout(theme_group)
|
||||
|
||||
self.light_theme_rb = QRadioButton("浅色")
|
||||
self.dark_theme_rb = QRadioButton("深色")
|
||||
self.system_theme_rb = QRadioButton("跟随系统")
|
||||
|
||||
current_theme = self.config.get('ui.theme', 'system')
|
||||
if current_theme == 'light':
|
||||
self.light_theme_rb.setChecked(True)
|
||||
elif current_theme == 'dark':
|
||||
self.dark_theme_rb.setChecked(True)
|
||||
else:
|
||||
self.system_theme_rb.setChecked(True)
|
||||
|
||||
theme_layout.addWidget(self.light_theme_rb)
|
||||
theme_layout.addWidget(self.dark_theme_rb)
|
||||
theme_layout.addWidget(self.system_theme_rb)
|
||||
|
||||
layout.addWidget(language_group)
|
||||
layout.addWidget(theme_group)
|
||||
layout.addStretch()
|
||||
|
||||
def clear_history(self):
|
||||
"""清除历史记录"""
|
||||
self.config.set('recent_files', [])
|
||||
self.config.set('recent_output_dirs', [])
|
||||
|
||||
def accept(self):
|
||||
"""确定按钮点击事件"""
|
||||
# 保存常规设置
|
||||
self.config.set('general.check_update_on_startup', self.check_update_cb.isChecked())
|
||||
self.config.set('general.show_welcome', self.show_welcome_cb.isChecked())
|
||||
self.config.set('general.remember_window_geometry', self.remember_window_cb.isChecked())
|
||||
self.config.set('general.max_recent_files', self.recent_files_spin.value())
|
||||
|
||||
# 保存OCR设置
|
||||
self.config.set('default_options.deskew', self.deskew_cb.isChecked())
|
||||
self.config.set('default_options.rotate_pages', self.rotate_cb.isChecked())
|
||||
self.config.set('default_options.clean', self.clean_cb.isChecked())
|
||||
self.config.set('default_options.optimize', self.optimize_cb.isChecked())
|
||||
self.config.set('default_options.output_type', self.output_type_combo.currentText())
|
||||
|
||||
# 保存界面设置
|
||||
ui_lang = 'zh_CN' if self.ui_language_combo.currentText() == '简体中文' else 'en_US'
|
||||
self.config.set('ui.language', ui_lang)
|
||||
|
||||
if self.light_theme_rb.isChecked():
|
||||
self.config.set('ui.theme', 'light')
|
||||
elif self.dark_theme_rb.isChecked():
|
||||
self.config.set('ui.theme', 'dark')
|
||||
else:
|
||||
self.config.set('ui.theme', 'system')
|
||||
|
||||
super().accept()
|
@ -0,0 +1 @@
|
||||
|
@ -0,0 +1,48 @@
|
||||
import sys
|
||||
import logging
|
||||
from pathlib import Path
|
||||
from PySide6.QtWidgets import QApplication
|
||||
from PySide6.QtCore import QTranslator, QLocale
|
||||
|
||||
from src.gui.main_window import MainWindow
|
||||
from src.core.config import Config
|
||||
|
||||
def setup_logging():
|
||||
"""设置日志系统"""
|
||||
log_dir = Path.home() / ".ocrmypdf-gui"
|
||||
log_dir.mkdir(exist_ok=True, parents=True)
|
||||
log_file = log_dir / "ocrmypdf-gui.log"
|
||||
|
||||
logging.basicConfig(
|
||||
level=logging.INFO,
|
||||
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
|
||||
handlers=[
|
||||
logging.StreamHandler(),
|
||||
logging.FileHandler(log_file)
|
||||
]
|
||||
)
|
||||
|
||||
def main():
|
||||
"""程序入口"""
|
||||
# 设置日志
|
||||
setup_logging()
|
||||
logger = logging.getLogger(__name__)
|
||||
logger.info("启动 OCRmyPDF GUI")
|
||||
|
||||
# 创建应用
|
||||
app = QApplication(sys.argv)
|
||||
app.setApplicationName("OCRmyPDF GUI")
|
||||
app.setOrganizationName("OCRmyPDF")
|
||||
|
||||
# 加载配置
|
||||
config = Config()
|
||||
|
||||
# 创建并显示主窗口
|
||||
window = MainWindow()
|
||||
window.show()
|
||||
|
||||
# 运行应用
|
||||
sys.exit(app.exec())
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
@ -0,0 +1 @@
|
||||
|
Binary file not shown.
Binary file not shown.
Loading…
Reference in new issue