You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

409 lines
16 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

from PySide6.QtWidgets import (
QDialog, QVBoxLayout, QHBoxLayout, QTabWidget,
QPushButton, QLabel, QComboBox, QCheckBox,
QGroupBox, QSpinBox, QRadioButton, QMessageBox,
QWidget
)
from PySide6.QtCore import Qt
from src.core.config import Config
from src.core.ocr_engine import OCREngine
class SettingsDialog(QDialog):
"""
设置对话框
提供应用程序各项设置的配置界面包括常规设置、OCR设置和界面设置。
使用选项卡组织不同类别的设置,提供直观的设置界面。
设置更改后保存到配置文件中,供应用程序其他部分使用。
"""
def __init__(self, parent=None):
"""
初始化设置对话框
创建配置实例设置窗口基本属性初始化UI组件。
Args:
parent: 父窗口默认为None
"""
super().__init__(parent)
self.setWindowTitle("设置")
self.resize(500, 400)
self.config = Config()
self.init_ui()
def init_ui(self):
"""
初始化用户界面
创建选项卡式布局包含常规、OCR和界面三个选项卡
以及确定和取消按钮。
"""
# 主布局
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):
"""
设置常规选项卡
创建并布局常规设置选项,包括启动选项和文件历史设置。
Args:
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选项卡
创建并布局OCR设置选项包括默认语言设置、处理选项和输出类型设置。
Args:
tab: 要设置的选项卡控件
"""
layout = QVBoxLayout(tab)
# 默认语言
language_group = QGroupBox("默认OCR语言")
language_layout = QVBoxLayout(language_group)
self.language_combo = QComboBox()
self.language_combo.setToolTip("选择默认的OCR识别语言")
# 添加可用的语言
ocr_engine = OCREngine()
# 常用语言列表
common_langs = ['eng', 'chi_sim', 'chi_tra', 'jpn', 'kor']
# 首先添加常用语言
if ocr_engine.available_languages:
# 添加常用语言组
common_available = [lang for lang in common_langs if lang in ocr_engine.available_languages]
if common_available:
self.language_combo.addItem("--- 常用语言 ---", None)
for lang_code in common_available:
lang_name = ocr_engine.get_language_name(lang_code)
self.language_combo.addItem(lang_name, lang_code)
# 添加其他语言组
other_available = [lang for lang in ocr_engine.available_languages
if lang not in common_langs]
if other_available:
self.language_combo.addItem("--- 其他语言 ---", None)
# 按名称排序
other_langs_sorted = sorted(
other_available,
key=lambda x: ocr_engine.get_language_name(x)
)
for lang_code in other_langs_sorted:
lang_name = ocr_engine.get_language_name(lang_code)
self.language_combo.addItem(lang_name, lang_code)
else:
# 如果没有常用语言,直接添加所有语言
for lang_code in ocr_engine.available_languages:
lang_name = ocr_engine.get_language_name(lang_code)
self.language_combo.addItem(lang_name, lang_code)
# 设置当前默认语言
default_lang = self.config.get('default_options.language', 'eng')
index = self.language_combo.findData(default_lang)
if index >= 0:
self.language_combo.setCurrentIndex(index)
# 添加刷新语言列表按钮
lang_buttons_layout = QHBoxLayout()
self.refresh_langs_btn = QPushButton("刷新语言列表")
self.refresh_langs_btn.clicked.connect(self.refresh_languages)
lang_buttons_layout.addWidget(self.refresh_langs_btn)
language_layout.addWidget(self.language_combo)
language_layout.addLayout(lang_buttons_layout)
# 默认选项
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(language_group)
layout.addWidget(options_group)
layout.addWidget(output_group)
layout.addStretch()
def setup_ui_tab(self, tab):
"""
设置界面选项卡
创建并布局界面设置选项,包括主题和语言设置。
Args:
tab: 要设置的选项卡控件
"""
layout = QVBoxLayout(tab)
# 主题设置
theme_group = QGroupBox("主题")
theme_layout = QVBoxLayout(theme_group)
self.theme_system_rb = QRadioButton("跟随系统")
self.theme_light_rb = QRadioButton("浅色主题")
self.theme_dark_rb = QRadioButton("深色主题")
current_theme = self.config.get('ui.theme', 'system')
if current_theme == 'light':
self.theme_light_rb.setChecked(True)
elif current_theme == 'dark':
self.theme_dark_rb.setChecked(True)
else:
self.theme_system_rb.setChecked(True)
theme_layout.addWidget(self.theme_system_rb)
theme_layout.addWidget(self.theme_light_rb)
theme_layout.addWidget(self.theme_dark_rb)
# 语言设置
language_group = QGroupBox("界面语言")
language_layout = QVBoxLayout(language_group)
self.ui_language_combo = QComboBox()
self.ui_language_combo.addItem("简体中文", "zh_CN")
self.ui_language_combo.addItem("English", "en_US")
current_lang = self.config.get('ui.language', 'zh_CN')
index = self.ui_language_combo.findData(current_lang)
if index >= 0:
self.ui_language_combo.setCurrentIndex(index)
language_note = QLabel("注:更改语言设置需要重启应用程序才能生效")
language_note.setStyleSheet("color: gray;")
language_layout.addWidget(self.ui_language_combo)
language_layout.addWidget(language_note)
layout.addWidget(theme_group)
layout.addWidget(language_group)
layout.addStretch()
def clear_history(self):
"""
清除历史记录
清空最近使用的文件和输出目录列表,并弹出确认提示。
"""
self.config.set('recent_files', [])
self.config.set('recent_output_dirs', [])
QMessageBox.information(self, "已清除", "已清除所有历史记录")
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设置
lang_index = self.language_combo.currentIndex()
lang_data = self.language_combo.itemData(lang_index)
# 如果选择了分隔符,尝试找到下一个有效选项
if lang_data is None:
for i in range(lang_index + 1, self.language_combo.count()):
next_data = self.language_combo.itemData(i)
if next_data:
lang_data = next_data
break
# 如果没有找到,使用默认语言
if lang_data is None:
lang_data = 'eng'
self.config.set('default_options.language', lang_data)
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())
# 保存界面设置
if self.theme_light_rb.isChecked():
theme = 'light'
elif self.theme_dark_rb.isChecked():
theme = 'dark'
else:
theme = 'system'
self.config.set('ui.theme', theme)
self.config.set('ui.language', self.ui_language_combo.currentData())
super().accept()
def refresh_languages(self):
"""
刷新语言列表
重新获取系统中已安装的Tesseract语言包并更新语言下拉列表。
保存当前选择的语言,并在刷新后尝试恢复选择。
"""
# 保存当前选择的语言
current_lang = self.language_combo.currentData()
# 清空语言下拉列表
self.language_combo.clear()
# 重新获取语言列表
ocr_engine = OCREngine()
# 这会重新检测可用的语言
ocr_engine = OCREngine()
# 重新填充语言下拉列表
common_langs = ['eng', 'chi_sim', 'chi_tra', 'jpn', 'kor']
if ocr_engine.available_languages:
# 添加常用语言组
common_available = [lang for lang in common_langs if lang in ocr_engine.available_languages]
if common_available:
self.language_combo.addItem("--- 常用语言 ---", None)
for lang_code in common_available:
lang_name = ocr_engine.get_language_name(lang_code)
self.language_combo.addItem(lang_name, lang_code)
# 添加其他语言组
other_available = [lang for lang in ocr_engine.available_languages
if lang not in common_langs]
if other_available:
self.language_combo.addItem("--- 其他语言 ---", None)
# 按名称排序
other_langs_sorted = sorted(
other_available,
key=lambda x: ocr_engine.get_language_name(x)
)
for lang_code in other_langs_sorted:
lang_name = ocr_engine.get_language_name(lang_code)
self.language_combo.addItem(lang_name, lang_code)
else:
# 如果没有常用语言,直接添加所有语言
for lang_code in ocr_engine.available_languages:
lang_name = ocr_engine.get_language_name(lang_code)
self.language_combo.addItem(lang_name, lang_code)
# 恢复之前选择的语言
if current_lang:
index = self.language_combo.findData(current_lang)
if index >= 0:
self.language_combo.setCurrentIndex(index)
# 显示刷新结果
QMessageBox.information(
self,
"刷新完成",
f"已刷新语言列表,找到 {len(ocr_engine.available_languages)} 种语言"
)
def download_language_pack(self):
"""下载Tesseract语言包 - 已移除"""
pass