新增視窗定位設置功能,允許用戶選擇總是在主螢幕中心顯示視窗,並更新相關界面及翻譯支持。

This commit is contained in:
Minidoracat 2025-06-03 12:39:03 +08:00
parent c3efd9662c
commit 50cfd67086
7 changed files with 139 additions and 4 deletions

View File

@ -9,7 +9,8 @@
from PySide6.QtWidgets import (
QWidget, QVBoxLayout, QHBoxLayout, QLabel,
QGroupBox, QComboBox, QRadioButton, QButtonGroup, QMessageBox
QGroupBox, QComboBox, QRadioButton, QButtonGroup, QMessageBox,
QCheckBox
)
from PySide6.QtCore import Signal
@ -21,9 +22,10 @@ class SettingsTab(QWidget):
language_changed = Signal()
layout_mode_change_requested = Signal(bool) # 佈局模式變更請求信號
def __init__(self, combined_mode: bool, parent=None):
def __init__(self, combined_mode: bool, config_manager, parent=None):
super().__init__(parent)
self.combined_mode = combined_mode
self.config_manager = config_manager
self.i18n = get_i18n_manager()
self._setup_ui()
@ -136,6 +138,27 @@ class SettingsTab(QWidget):
self.layout_button_group.buttonToggled.connect(self._on_layout_mode_changed)
layout.addWidget(self.layout_group)
# === 視窗定位設置區域 ===
self.window_group = QGroupBox(t('settings.window.title'))
self.window_group.setObjectName('window_group')
window_layout = QVBoxLayout(self.window_group)
window_layout.setSpacing(12)
window_layout.setContentsMargins(16, 16, 16, 16)
# 總是在主螢幕中心顯示視窗選項
self.always_center_checkbox = QCheckBox(t('settings.window.alwaysCenter'))
self.always_center_checkbox.setChecked(self.config_manager.get_always_center_window())
self.always_center_checkbox.setStyleSheet("font-size: 14px; font-weight: bold; color: #e0e0e0;")
self.always_center_checkbox.stateChanged.connect(self._on_always_center_changed)
window_layout.addWidget(self.always_center_checkbox)
self.center_desc_label = QLabel(t('settings.window.alwaysCenterDescription'))
self.center_desc_label.setStyleSheet("color: #9e9e9e; font-size: 12px; margin-left: 20px; margin-bottom: 8px;")
self.center_desc_label.setWordWrap(True)
window_layout.addWidget(self.center_desc_label)
layout.addWidget(self.window_group)
layout.addStretch()
def _populate_language_selector(self) -> None:
@ -200,11 +223,17 @@ class SettingsTab(QWidget):
else:
self.separate_mode_radio.setChecked(True)
def _on_always_center_changed(self, state: int) -> None:
"""處理視窗定位設置變更"""
always_center = state == 2 # Qt.Checked = 2
self.config_manager.set_always_center_window(always_center)
def update_texts(self) -> None:
"""更新界面文字(用於語言切換)"""
# 更新GroupBox標題
self.language_group.setTitle(t('settings.language.title'))
self.layout_group.setTitle(t('settings.layout.title'))
self.window_group.setTitle(t('settings.window.title'))
# 更新標籤文字
self.language_label.setText(t('settings.language.selector'))
@ -218,9 +247,16 @@ class SettingsTab(QWidget):
self.separate_desc_label.setText(t('settings.layout.separateModeDescription'))
self.combined_desc_label.setText(t('settings.layout.combinedModeDescription'))
# 更新視窗設置文字
self.always_center_checkbox.setText(t('settings.window.alwaysCenter'))
self.center_desc_label.setText(t('settings.window.alwaysCenterDescription'))
# 重新填充語言選擇器
self._populate_language_selector()
# 重新設置勾選狀態,確保設置被正確保持
self.always_center_checkbox.setChecked(self.config_manager.get_always_center_window())
def set_layout_mode(self, combined_mode: bool) -> None:
"""設置佈局模式"""
self.combined_mode = combined_mode

View File

@ -101,3 +101,12 @@ class ConfigManager:
"""設置窗口幾何信息"""
self.set('window_geometry', geometry)
debug_log(f"保存窗口幾何信息: {geometry}")
def get_always_center_window(self) -> bool:
"""獲取總是在主螢幕中心顯示視窗的設置"""
return self.get('always_center_window', False)
def set_always_center_window(self, always_center: bool) -> None:
"""設置總是在主螢幕中心顯示視窗"""
self.set('always_center_window', always_center)
debug_log(f"視窗定位設置: {'總是中心顯示' if always_center else '智能定位'}")

View File

@ -49,6 +49,9 @@ class FeedbackWindow(QMainWindow):
self.setMinimumSize(1000, 800)
self.resize(1200, 900)
# 智能視窗定位
self._apply_window_positioning()
# 中央元件
central_widget = QWidget()
self.setCentralWidget(central_widget)
@ -359,8 +362,80 @@ class FeedbackWindow(QMainWindow):
# 更新分頁文字
self.tab_manager.update_tab_texts()
def _apply_window_positioning(self) -> None:
"""根據用戶設置應用視窗定位策略"""
always_center = self.config_manager.get_always_center_window()
if always_center:
# 強制在主螢幕中心顯示
self._move_to_primary_screen_center()
else:
# 先嘗試恢復上次位置
if self._restore_last_position():
# 檢查恢復的位置是否可見
if not self._is_window_visible():
self._move_to_primary_screen_center()
else:
# 沒有保存的位置,移到中心
self._move_to_primary_screen_center()
def _is_window_visible(self) -> bool:
"""檢查視窗是否在任何螢幕的可見範圍內"""
from PySide6.QtWidgets import QApplication
window_rect = self.frameGeometry()
for screen in QApplication.screens():
if screen.availableGeometry().intersects(window_rect):
return True
return False
def _move_to_primary_screen_center(self) -> None:
"""將視窗移到主螢幕中心"""
from PySide6.QtWidgets import QApplication
screen = QApplication.primaryScreen()
if screen:
screen_geometry = screen.availableGeometry()
window_geometry = self.frameGeometry()
center_point = screen_geometry.center()
window_geometry.moveCenter(center_point)
self.move(window_geometry.topLeft())
debug_log("視窗已移到主螢幕中心")
def _restore_last_position(self) -> bool:
"""嘗試恢復上次保存的視窗位置"""
try:
geometry = self.config_manager.get_window_geometry()
if geometry and 'x' in geometry and 'y' in geometry and 'width' in geometry and 'height' in geometry:
self.move(geometry['x'], geometry['y'])
self.resize(geometry['width'], geometry['height'])
debug_log(f"已恢復視窗位置: ({geometry['x']}, {geometry['y']}) 大小: {geometry['width']}x{geometry['height']}")
return True
except Exception as e:
debug_log(f"恢復視窗位置失敗: {e}")
return False
def _save_window_position(self) -> None:
"""保存當前視窗位置"""
try:
geometry = {
'x': self.x(),
'y': self.y(),
'width': self.width(),
'height': self.height()
}
self.config_manager.set_window_geometry(geometry)
debug_log(f"已保存視窗位置: ({geometry['x']}, {geometry['y']}) 大小: {geometry['width']}x{geometry['height']}")
except Exception as e:
debug_log(f"保存視窗位置失敗: {e}")
def closeEvent(self, event) -> None:
"""窗口關閉事件"""
# 保存視窗位置(除非設置為總是中心顯示)
if not self.config_manager.get_always_center_window():
self._save_window_position()
# 清理分頁管理器
self.tab_manager.cleanup()
event.accept()

View File

@ -60,7 +60,7 @@ class TabManager:
self.tab_widget.addTab(self.command_tab, t('tabs.command'))
# 設置分頁
self.settings_tab = SettingsTab(self.combined_mode)
self.settings_tab = SettingsTab(self.combined_mode, self.config_manager)
self.tab_widget.addTab(self.settings_tab, t('tabs.language'))
# 關於分頁

View File

@ -91,6 +91,11 @@
"combinedModeDescription": "Display AI summary and feedback on the same page for easy comparison",
"separateMode": "Separate Mode",
"separateModeDescription": "AI summary and feedback are in separate tabs"
},
"window": {
"title": "Window Positioning",
"alwaysCenter": "Always show window at primary screen center",
"alwaysCenterDescription": "Recommended for multi-monitor setups or when experiencing window positioning issues"
}
},
"buttons": {

View File

@ -71,6 +71,11 @@
"combinedModeDescription": "将 AI 摘要和反馈放在同一页面,便于对照阅读",
"separateMode": "分离模式",
"separateModeDescription": "AI 摘要和反馈分别在不同页签"
},
"window": {
"title": "窗口定位",
"alwaysCenter": "总是在主屏幕中心显示窗口",
"alwaysCenterDescription": "建议在多屏幕环境或遇到窗口定位问题时开启此选项"
}
},
"buttons": {

View File

@ -92,6 +92,11 @@
"combinedModeDescription": "將 AI 摘要和回饋放在同一頁面,便於對照閱讀",
"separateMode": "分離模式",
"separateModeDescription": "AI 摘要和回饋分別在不同頁籤"
},
"window": {
"title": "視窗定位",
"alwaysCenter": "總是在主螢幕中心顯示視窗",
"alwaysCenterDescription": "建議在多螢幕環境或遇到視窗定位問題時開啟此選項"
}
},
"buttons": {