1221212121212121213321213 #31

Merged
pshjeamgr merged 6 commits from main into llllllllllllllCC 4 months ago

@ -0,0 +1,201 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
MagicWord 安装和修复脚本
用于安装依赖并解决Qt平台插件问题
"""
import os
import sys
import subprocess
import platform
import importlib.util
def check_python_version():
"""检查Python版本"""
version = sys.version_info
print(f"当前Python版本: {version.major}.{version.minor}.{version.micro}")
if version.major < 3 or (version.major == 3 and version.minor < 6):
print("错误: 需要Python 3.6或更高版本")
return False
return True
def run_command(command, shell=False):
"""运行命令并返回结果"""
try:
result = subprocess.run(command, shell=shell, capture_output=True, text=True, encoding='utf-8')
return result.returncode, result.stdout, result.stderr
except Exception as e:
return -1, "", str(e)
def install_requirements():
"""安装requirements.txt中的依赖"""
requirements_file = "requirements.txt"
if not os.path.exists(requirements_file):
print(f"错误: 找不到 {requirements_file} 文件")
return False
print("安装项目依赖...")
try:
code, stdout, stderr = run_command([sys.executable, "-m", "pip", "install", "-r", requirements_file])
if code == 0:
print("所有依赖安装成功")
return True
else:
print(f"依赖安装失败: {stderr}")
return False
except Exception as e:
print(f"依赖安装异常: {e}")
return False
def check_pyqt5():
"""检查PyQt5安装"""
print("检查PyQt5安装...")
try:
import PyQt5
pyqt5_path = os.path.dirname(PyQt5.__file__)
print(f"PyQt5已安装路径: {pyqt5_path}")
return True
except ImportError:
print("PyQt5未安装")
return False
def reinstall_pyqt5():
"""重新安装PyQt5"""
print("重新安装PyQt5...")
try:
# 先卸载
print("卸载PyQt5...")
code, stdout, stderr = run_command([sys.executable, "-m", "pip", "uninstall", "PyQt5", "-y"])
# 重新安装
print("安装PyQt5...")
code, stdout, stderr = run_command([sys.executable, "-m", "pip", "install", "PyQt5"])
if code == 0:
print("PyQt5重新安装成功")
return True
else:
print(f"PyQt5重新安装失败: {stderr}")
return False
except Exception as e:
print(f"PyQt5重新安装异常: {e}")
return False
def create_qt_debug_script():
"""创建Qt调试运行脚本"""
system = platform.system()
if system == "Windows":
script_content = """@echo off
echo 设置Qt调试环境变量...
set QT_DEBUG_PLUGINS=1
echo Qt调试模式已启用
echo.
echo 运行MagicWord应用程序...
python src/main.py
pause
"""
script_name = "run_debug.bat"
else:
script_content = """#!/bin/bash
echo "设置Qt调试环境变量..."
export QT_DEBUG_PLUGINS=1
echo "Qt调试模式已启用"
echo ""
echo "运行MagicWord应用程序..."
python src/main.py
"""
script_name = "run_debug.sh"
try:
with open(script_name, "w", encoding="utf-8") as f:
f.write(script_content)
print(f"调试运行脚本创建完成: {script_name}")
return True
except Exception as e:
print(f"创建调试运行脚本失败: {e}")
return False
def main():
"""主函数"""
print("=" * 60)
print("MagicWord 项目安装和修复脚本")
print("=" * 60)
# 检查Python版本
if not check_python_version():
sys.exit(1)
# 升级pip
print("\n升级pip...")
code, stdout, stderr = run_command([sys.executable, "-m", "pip", "install", "--upgrade", "pip"])
if code != 0:
print(f"pip升级警告: {stderr}")
else:
print("pip升级完成")
# 安装依赖
print("\n安装项目依赖...")
if not install_requirements():
print("依赖安装失败")
sys.exit(1)
# 检查PyQt5
print("\n检查PyQt5...")
if not check_pyqt5():
print("PyQt5未安装开始安装...")
code, stdout, stderr = run_command([sys.executable, "-m", "pip", "install", "PyQt5"])
if code == 0:
print("PyQt5安装成功")
else:
print(f"PyQt5安装失败: {stderr}")
# 尝试重新安装
if not reinstall_pyqt5():
print("PyQt5重新安装也失败了")
# 再次检查PyQt5
if check_pyqt5():
# 检查PyQt5插件路径
try:
import PyQt5
pyqt5_path = os.path.dirname(PyQt5.__file__)
plugin_paths = [
os.path.join(pyqt5_path, "Qt5", "plugins"),
os.path.join(pyqt5_path, "plugins"),
]
plugin_path = None
for path in plugin_paths:
if os.path.exists(path):
plugin_path = path
break
if plugin_path:
print(f"PyQt5插件路径: {plugin_path}")
platforms_path = os.path.join(plugin_path, "platforms")
if os.path.exists(platforms_path):
print(f"Platform插件路径: {platforms_path}")
else:
print("未找到platforms目录")
else:
print("未找到PyQt5插件目录")
except Exception as e:
print(f"检查PyQt5插件时出错: {e}")
# 创建调试脚本
print("\n创建调试运行脚本...")
create_qt_debug_script()
print("\n" + "=" * 60)
print("安装和修复完成!")
print("如果问题仍然存在,请尝试以下方法:")
print("1. 运行创建的调试脚本查看详细错误信息")
print("2. 检查是否安装了Visual C++运行库")
print("3. 确保使用的是Python 3.6或更高版本")
print("=" * 60)
if __name__ == "__main__":
main()

@ -0,0 +1,8 @@
@echo off
echo 设置Qt调试环境变量...
set QT_DEBUG_PLUGINS=1
echo Qt调试模式已启用
echo.
echo 运行MagicWord应用程序...
python src/main.py
pause

@ -2,20 +2,68 @@
import sys
import traceback
import os
import platform
# 添加项目根目录到Python路径
project_root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.insert(0, project_root)
# 设置Qt平台插件路径 - 优先使用系统Qt插件
system_qt_plugins_path = '/usr/local/opt/qt5/plugins' # macOS Homebrew Qt5路径
venv_qt_plugins_path = os.path.join(project_root, '.venv', 'lib', 'python3.9', 'site-packages', 'PyQt5', 'Qt5', 'plugins')
# 设置Qt平台插件路径 - 根据操作系统设置正确的Qt插件路径
def set_qt_plugin_path():
system = platform.system()
if system == "Windows":
# Windows环境下查找Qt插件路径
# 首先检查虚拟环境中的Qt插件
venv_qt_plugins_path = os.path.join(project_root, '.venv', 'Lib', 'site-packages', 'PyQt5', 'Qt5', 'plugins')
if os.path.exists(venv_qt_plugins_path):
os.environ['QT_QPA_PLATFORM_PLUGIN_PATH'] = venv_qt_plugins_path
return
# 检查全局Python安装中的Qt插件
global_qt_plugins_path = os.path.join(sys.prefix, 'Lib', 'site-packages', 'PyQt5', 'Qt5', 'plugins')
if os.path.exists(global_qt_plugins_path):
os.environ['QT_QPA_PLATFORM_PLUGIN_PATH'] = global_qt_plugins_path
return
# 尝试在常见的Windows PyQt5安装路径中查找
common_paths = [
os.path.join(os.path.expanduser('~'), 'AppData', 'Local', 'Programs', 'Python', 'Python39', 'Lib', 'site-packages', 'PyQt5', 'Qt5', 'plugins'),
os.path.join(os.path.expanduser('~'), 'AppData', 'Roaming', 'Python', 'Python39', 'site-packages', 'PyQt5', 'Qt5', 'plugins'),
]
for path in common_paths:
if os.path.exists(path):
os.environ['QT_QPA_PLATFORM_PLUGIN_PATH'] = path
return
elif system == "Darwin": # macOS
# macOS环境下查找Qt插件路径
system_qt_plugins_path = '/usr/local/opt/qt5/plugins' # macOS Homebrew Qt5路径
venv_qt_plugins_path = os.path.join(project_root, '.venv', 'lib', 'python3.9', 'site-packages', 'PyQt5', 'Qt5', 'plugins')
# 优先检查系统Qt插件路径
if os.path.exists(system_qt_plugins_path):
os.environ['QT_QPA_PLATFORM_PLUGIN_PATH'] = system_qt_plugins_path
return
elif os.path.exists(venv_qt_plugins_path):
os.environ['QT_QPA_PLATFORM_PLUGIN_PATH'] = venv_qt_plugins_path
return
elif system == "Linux":
# Linux环境下查找Qt插件路径
venv_qt_plugins_path = os.path.join(project_root, '.venv', 'lib', 'python3.9', 'site-packages', 'PyQt5', 'Qt5', 'plugins')
global_qt_plugins_path = os.path.join(sys.prefix, 'lib', 'python3.9', 'site-packages', 'PyQt5', 'Qt5', 'plugins')
if os.path.exists(venv_qt_plugins_path):
os.environ['QT_QPA_PLATFORM_PLUGIN_PATH'] = venv_qt_plugins_path
return
elif os.path.exists(global_qt_plugins_path):
os.environ['QT_QPA_PLATFORM_PLUGIN_PATH'] = global_qt_plugins_path
return
# 优先检查系统Qt插件路径
if os.path.exists(system_qt_plugins_path):
os.environ['QT_QPA_PLATFORM_PLUGIN_PATH'] = system_qt_plugins_path
elif os.path.exists(venv_qt_plugins_path):
os.environ['QT_QPA_PLATFORM_PLUGIN_PATH'] = venv_qt_plugins_path
# 设置Qt平台插件路径
set_qt_plugin_path()
from PyQt5.QtWidgets import QApplication
from PyQt5.QtCore import Qt

@ -2,7 +2,8 @@
from PyQt5.QtWidgets import (QWidget, QVBoxLayout, QHBoxLayout, QLabel,
QPushButton, QTabWidget, QFrame, QTextEdit,
QToolButton, QMenuBar, QStatusBar, QGroupBox,
QComboBox, QSpinBox, QFontComboBox, QToolBar)
QComboBox, QSpinBox, QFontComboBox, QToolBar,
QSizePolicy)
from PyQt5.QtCore import Qt, QSize
from PyQt5.QtGui import QFont, QIcon, QPalette, QColor
@ -31,49 +32,6 @@ class WordRibbon(QFrame):
main_layout.setContentsMargins(0, 0, 0, 0)
main_layout.setSpacing(0)
# 标签栏
self.tab_bar = QWidget()
self.tab_bar.setFixedHeight(25)
self.tab_bar.setStyleSheet("""
QWidget {
background-color: #f3f2f1;
border-bottom: 1px solid #e1e1e1;
}
""")
tab_layout = QHBoxLayout()
tab_layout.setContentsMargins(10, 0, 0, 0)
tab_layout.setSpacing(0)
# 创建标签按钮
self.tabs = {}
tab_names = ['文件', '开始', '插入', '设计', '布局', '引用', '邮件', '审阅', '视图', '帮助']
for name in tab_names:
tab_btn = QPushButton(name)
tab_btn.setFlat(True)
tab_btn.setFixedHeight(25)
tab_btn.setStyleSheet("""
QPushButton {
background-color: transparent;
border: none;
padding: 5px 15px;
font-size: 12px;
color: #333333;
}
QPushButton:hover {
background-color: #e1e1e1;
}
QPushButton:checked {
background-color: #ffffff;
border: 1px solid #d0d0d0;
border-bottom: 1px solid #ffffff;
}
""")
self.tabs[name] = tab_btn
tab_layout.addWidget(tab_btn)
self.tab_bar.setLayout(tab_layout)
# 功能区
self.ribbon_area = QFrame()
self.ribbon_area.setStyleSheet("""
@ -93,33 +51,12 @@ class WordRibbon(QFrame):
self.ribbon_area.setLayout(ribbon_layout)
main_layout.addWidget(self.tab_bar)
main_layout.addWidget(self.ribbon_area)
self.setLayout(main_layout)
# 设置默认选中的标签
self.tabs['开始'].setChecked(True)
def setup_home_tab(self, layout):
"""设置开始标签的功能区内容"""
# 剪贴板组
clipboard_group = self.create_ribbon_group("剪贴板")
paste_btn = self.create_ribbon_button("粘贴", "Ctrl+V", "paste")
cut_btn = self.create_ribbon_button("剪切", "Ctrl+X", "cut")
copy_btn = self.create_ribbon_button("复制", "Ctrl+C", "copy")
clipboard_layout = QVBoxLayout()
clipboard_layout.addWidget(paste_btn)
small_btn_layout = QHBoxLayout()
small_btn_layout.addWidget(cut_btn)
small_btn_layout.addWidget(copy_btn)
clipboard_layout.addLayout(small_btn_layout)
clipboard_group.setLayout(clipboard_layout)
layout.addWidget(clipboard_group)
# 字体组
font_group = self.create_ribbon_group("字体")
@ -127,10 +64,12 @@ class WordRibbon(QFrame):
font_layout = QHBoxLayout()
self.font_combo = QFontComboBox()
self.font_combo.setFixedWidth(120)
self.font_combo.currentFontChanged.connect(self.on_font_changed)
self.font_size_combo = QComboBox()
self.font_size_combo.addItems(['8', '9', '10', '11', '12', '14', '16', '18', '20', '22', '24', '26', '28', '36', '48', '72'])
self.font_size_combo.setFixedWidth(50)
self.font_size_combo.setCurrentText('12')
self.font_size_combo.currentTextChanged.connect(self.on_font_size_changed)
font_layout.addWidget(self.font_combo)
font_layout.addWidget(self.font_size_combo)
@ -138,8 +77,11 @@ class WordRibbon(QFrame):
# 字体样式按钮
font_style_layout = QHBoxLayout()
self.bold_btn = self.create_toggle_button("B", "bold")
self.bold_btn.clicked.connect(self.on_bold_clicked)
self.italic_btn = self.create_toggle_button("I", "italic")
self.italic_btn.clicked.connect(self.on_italic_clicked)
self.underline_btn = self.create_toggle_button("U", "underline")
self.underline_btn.clicked.connect(self.on_underline_clicked)
font_style_layout.addWidget(self.bold_btn)
font_style_layout.addWidget(self.italic_btn)
@ -182,17 +124,37 @@ class WordRibbon(QFrame):
# 编辑组
editing_group = self.create_ribbon_group("编辑")
find_btn = self.create_ribbon_button("查找", "Ctrl+F", "find")
replace_btn = self.create_ribbon_button("替换", "Ctrl+H", "replace")
self.find_btn = self.create_ribbon_button("查找", "Ctrl+F", "find")
self.replace_btn = self.create_ribbon_button("替换", "Ctrl+H", "replace")
editing_layout = QVBoxLayout()
editing_layout.addWidget(find_btn)
editing_layout.addWidget(replace_btn)
editing_layout.addWidget(self.find_btn)
editing_layout.addWidget(self.replace_btn)
editing_group.setLayout(editing_layout)
layout.addWidget(editing_group)
layout.addStretch()
def on_font_changed(self, font):
"""字体变化处理"""
pass
def on_font_size_changed(self, size):
"""字体大小变化处理"""
pass
def on_bold_clicked(self):
"""粗体按钮点击处理"""
pass
def on_italic_clicked(self):
"""斜体按钮点击处理"""
pass
def on_underline_clicked(self):
"""下划线按钮点击处理"""
pass
def create_ribbon_group(self, title):
"""创建功能区组"""
group = QGroupBox(title)
@ -350,6 +312,21 @@ class WordStyleToolBar(QToolBar):
self.addWidget(undo_btn)
self.addWidget(redo_btn)
self.addSeparator()
# 添加弹性空间,将后面的按钮推到最右侧
# 创建一个具有扩展策略的QWidget来实现spacer效果
spacer = QWidget()
spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
self.addWidget(spacer)
# 添加批注、编辑、共享按钮到最右侧
comment_btn = self.create_quick_button("批注", "")
edit_btn = self.create_quick_button("编辑", "")
share_btn = self.create_quick_button("共享", "")
self.addWidget(comment_btn)
self.addWidget(edit_btn)
self.addWidget(share_btn)
def create_quick_button(self, text, shortcut):
"""创建快速访问按钮"""

@ -3,9 +3,10 @@ import sys
import os
from PyQt5.QtWidgets import (QMainWindow, QWidget, QVBoxLayout, QHBoxLayout,
QTextEdit, QLabel, QSplitter, QFrame, QMenuBar,
QAction, QFileDialog, QMessageBox, QApplication)
QAction, QFileDialog, QMessageBox, QApplication,
QDialog, QLineEdit, QCheckBox, QPushButton)
from PyQt5.QtCore import Qt, QThread, pyqtSignal, QTimer, QRect
from PyQt5.QtGui import QFont, QPalette, QColor, QIcon, QPixmap, QTextCharFormat
from PyQt5.QtGui import QFont, QPalette, QColor, QIcon, QPixmap, QTextCharFormat, QTextCursor, QTextDocument
from ui.word_style_ui import (WordRibbon, WordStatusBar, WordTextEdit,
WordStyleToolBar)
@ -231,10 +232,106 @@ class WordStyleMainWindow(QMainWindow):
# 打印布局
print_layout_action = QAction('打印布局', self)
print_layout_action.setCheckable(True)
print_layout_action.setChecked(True)
print_layout_action.triggered.connect(self.toggle_print_layout)
view_menu.addAction(print_layout_action)
view_menu.addSeparator()
# 页面布局子菜单
layout_menu = view_menu.addMenu('页面布局')
# 页面颜色
page_color_menu = layout_menu.addMenu('页面颜色')
white_action = QAction('白色', self)
white_action.triggered.connect(lambda: self.set_page_color('white'))
page_color_menu.addAction(white_action)
light_blue_action = QAction('浅蓝色', self)
light_blue_action.triggered.connect(lambda: self.set_page_color('light_blue'))
page_color_menu.addAction(light_blue_action)
light_yellow_action = QAction('浅黄色', self)
light_yellow_action.triggered.connect(lambda: self.set_page_color('light_yellow'))
page_color_menu.addAction(light_yellow_action)
light_green_action = QAction('浅绿色', self)
light_green_action.triggered.connect(lambda: self.set_page_color('light_green'))
page_color_menu.addAction(light_green_action)
# 页面边距
margin_menu = layout_menu.addMenu('页面边距')
normal_margin_action = QAction('普通', self)
normal_margin_action.triggered.connect(lambda: self.set_page_margins('normal'))
margin_menu.addAction(normal_margin_action)
narrow_margin_action = QAction('', self)
narrow_margin_action.triggered.connect(lambda: self.set_page_margins('narrow'))
margin_menu.addAction(narrow_margin_action)
wide_margin_action = QAction('', self)
wide_margin_action.triggered.connect(lambda: self.set_page_margins('wide'))
margin_menu.addAction(wide_margin_action)
# 缩放子菜单
zoom_menu = view_menu.addMenu('缩放')
zoom_in_action = QAction('放大', self)
zoom_in_action.setShortcut('Ctrl++')
zoom_in_action.triggered.connect(self.zoom_in)
zoom_menu.addAction(zoom_in_action)
zoom_out_action = QAction('缩小', self)
zoom_out_action.setShortcut('Ctrl+-')
zoom_out_action.triggered.connect(self.zoom_out)
zoom_menu.addAction(zoom_out_action)
zoom_100_action = QAction('实际大小', self)
zoom_100_action.setShortcut('Ctrl+0')
zoom_100_action.triggered.connect(self.zoom_100)
zoom_menu.addAction(zoom_100_action)
zoom_menu.addSeparator()
# 预设缩放选项
zoom_50_action = QAction('50%', self)
zoom_50_action.triggered.connect(lambda: self.set_zoom_level(50))
zoom_menu.addAction(zoom_50_action)
zoom_75_action = QAction('75%', self)
zoom_75_action.triggered.connect(lambda: self.set_zoom_level(75))
zoom_menu.addAction(zoom_75_action)
zoom_100_action2 = QAction('100%', self)
zoom_100_action2.triggered.connect(lambda: self.set_zoom_level(100))
zoom_menu.addAction(zoom_100_action2)
zoom_125_action = QAction('125%', self)
zoom_125_action.triggered.connect(lambda: self.set_zoom_level(125))
zoom_menu.addAction(zoom_125_action)
zoom_150_action = QAction('150%', self)
zoom_150_action.triggered.connect(lambda: self.set_zoom_level(150))
zoom_menu.addAction(zoom_150_action)
zoom_200_action = QAction('200%', self)
zoom_200_action.triggered.connect(lambda: self.set_zoom_level(200))
zoom_menu.addAction(zoom_200_action)
view_menu.addSeparator()
# 显示选项
grid_lines_action = QAction('网格线', self)
grid_lines_action.setCheckable(True)
grid_lines_action.triggered.connect(self.toggle_grid_lines)
view_menu.addAction(grid_lines_action)
ruler_action = QAction('标尺', self)
ruler_action.setCheckable(True)
ruler_action.triggered.connect(self.toggle_ruler)
view_menu.addAction(ruler_action)
# 帮助菜单
help_menu = menubar.addMenu('帮助(H)')
@ -318,9 +415,23 @@ class WordStyleMainWindow(QMainWindow):
self.text_edit.textChanged.connect(self.on_text_changed)
# Ribbon按钮信号
if hasattr(self.ribbon, 'tabs'):
for tab_name, tab_btn in self.ribbon.tabs.items():
tab_btn.clicked.connect(lambda checked, name=tab_name: self.on_tab_changed(name))
# 标签栏已删除,相关代码已移除
# 字体设置信号
if hasattr(self.ribbon, 'font_combo'):
self.ribbon.font_combo.currentFontChanged.connect(self.on_font_changed)
self.ribbon.font_size_combo.currentTextChanged.connect(self.on_font_size_changed)
self.ribbon.bold_btn.clicked.connect(self.on_bold_clicked)
self.ribbon.italic_btn.clicked.connect(self.on_italic_clicked)
self.ribbon.underline_btn.clicked.connect(self.on_underline_clicked)
# 查找和替换按钮信号
if hasattr(self.ribbon, 'find_btn'):
self.ribbon.find_btn.clicked.connect(self.show_find_dialog)
if hasattr(self.ribbon, 'replace_btn'):
self.ribbon.replace_btn.clicked.connect(self.show_replace_dialog)
# 页面布局信号已在菜单中直接连接,无需在此重复连接
def on_text_changed(self):
"""文本变化处理 - 逐步显示模式"""
@ -389,14 +500,71 @@ class WordStyleMainWindow(QMainWindow):
self.is_modified = True
self.update_window_title()
def on_tab_changed(self, tab_name):
"""标签切换处理"""
# 更新标签状态
for name, btn in self.ribbon.tabs.items():
btn.setChecked(name == tab_name)
# 这里可以根据不同标签切换不同的功能区内容
print(f"切换到标签: {tab_name}")
def on_font_changed(self, font):
"""字体更改处理"""
cursor = self.text_edit.textCursor()
if cursor.hasSelection():
# 如果有选中文本,只更改选中文本的字体
fmt = cursor.charFormat()
fmt.setFontFamily(font.family())
cursor.setCharFormat(fmt)
else:
# 如果没有选中文本,更改整个文档的默认字体
self.text_edit.setFontFamily(font.family())
def on_font_size_changed(self, size):
"""字体大小更改处理"""
try:
font_size = int(size)
cursor = self.text_edit.textCursor()
if cursor.hasSelection():
# 如果有选中文本,只更改选中文本的字体大小
fmt = cursor.charFormat()
fmt.setFontPointSize(font_size)
cursor.setCharFormat(fmt)
else:
# 如果没有选中文本,更改整个文档的默认字体大小
self.text_edit.setFontPointSize(font_size)
except ValueError:
pass # 忽略无效的字体大小
def on_bold_clicked(self, checked):
"""粗体按钮点击处理"""
cursor = self.text_edit.textCursor()
if cursor.hasSelection():
# 如果有选中文本,只更改选中文本的粗体样式
fmt = cursor.charFormat()
fmt.setFontWeight(QFont.Bold if checked else QFont.Normal)
cursor.setCharFormat(fmt)
else:
# 如果没有选中文本,更改整个文档的默认粗体样式
self.text_edit.setFontWeight(QFont.Bold if checked else QFont.Normal)
def on_italic_clicked(self, checked):
"""斜体按钮点击处理"""
cursor = self.text_edit.textCursor()
if cursor.hasSelection():
# 如果有选中文本,只更改选中文本的斜体样式
fmt = cursor.charFormat()
fmt.setFontItalic(checked)
cursor.setCharFormat(fmt)
else:
# 如果没有选中文本,更改整个文档的默认斜体样式
self.text_edit.setFontItalic(checked)
def on_underline_clicked(self, checked):
"""下划线按钮点击处理"""
cursor = self.text_edit.textCursor()
if cursor.hasSelection():
# 如果有选中文本,只更改选中文本的下划线样式
fmt = cursor.charFormat()
fmt.setFontUnderline(checked)
cursor.setCharFormat(fmt)
else:
# 如果没有选中文本,更改整个文档的默认下划线样式
self.text_edit.setFontUnderline(checked)
def update_weather_display(self, weather_data):
"""更新天气显示"""
@ -600,6 +768,319 @@ class WordStyleMainWindow(QMainWindow):
# 这里可以实现打印布局的逻辑
self.status_bar.showMessage("打印布局功能开发中...", 3000)
def set_page_color(self, color):
"""设置页面颜色"""
color_map = {
'white': '#ffffff',
'light_blue': '#e6f3ff',
'light_yellow': '#fffde6',
'light_green': '#e6ffe6'
}
if color in color_map:
bg_color = color_map[color]
# 更新文本编辑区域的背景色
current_style = self.text_edit.styleSheet()
# 移除旧的背景色设置
import re
current_style = re.sub(r'background-color:\s*#[a-fA-F0-9]+;', '', current_style)
# 添加新的背景色设置
new_style = current_style + f"\nbackground-color: {bg_color};"
self.text_edit.setStyleSheet(new_style)
self.status_bar.showMessage(f"页面颜色已设置为{color}", 2000)
def set_page_margins(self, margin_type):
"""设置页面边距"""
margin_map = {
'normal': (50, 50, 50, 50),
'narrow': (20, 20, 20, 20),
'wide': (80, 80, 80, 80)
}
if margin_type in margin_map:
margins = margin_map[margin_type]
# 更新文档容器的边距
# text_edit的父级是document_layout父级的父级是document_container
container = self.text_edit.parent().parent() # 获取文档容器
if container and hasattr(container, 'layout'):
layout = container.layout()
if layout:
layout.setContentsMargins(margins[0], margins[1], margins[2], margins[3])
self.status_bar.showMessage(f"页面边距已设置为{margin_type}", 2000)
def zoom_in(self):
"""放大"""
self.adjust_zoom_level(10)
def zoom_out(self):
"""缩小"""
self.adjust_zoom_level(-10)
def zoom_100(self):
"""实际大小"""
self.set_zoom_level(100)
def set_zoom_level(self, level):
"""设置缩放级别"""
if 10 <= level <= 500: # 限制缩放范围在10%到500%之间
# 获取当前字体大小并调整
current_font = self.text_edit.currentFont()
base_size = 12 # 基准字体大小
new_size = base_size * (level / 100)
# 应用新的字体大小
current_font.setPointSizeF(new_size)
self.text_edit.setFont(current_font)
self.status_bar.showMessage(f"缩放级别: {level}%", 2000)
def adjust_zoom_level(self, delta):
"""调整缩放级别"""
# 获取当前字体大小
current_font = self.text_edit.currentFont()
current_size = current_font.pointSizeF()
base_size = 12 # 基准字体大小
# 计算当前缩放百分比
current_zoom = (current_size / base_size) * 100
new_zoom = current_zoom + delta
# 限制缩放范围
if 10 <= new_zoom <= 500:
self.set_zoom_level(int(new_zoom))
def toggle_grid_lines(self):
"""切换网格线显示"""
self.status_bar.showMessage("网格线功能开发中...", 3000)
def toggle_ruler(self):
"""切换标尺显示"""
self.status_bar.showMessage("标尺功能开发中...", 3000)
def show_find_dialog(self):
"""显示查找对话框"""
# 创建查找对话框
dialog = QDialog(self)
dialog.setWindowTitle("查找")
dialog.setFixedSize(400, 150)
layout = QVBoxLayout()
# 查找内容输入
find_layout = QHBoxLayout()
find_label = QLabel("查找内容:")
self.find_edit = QLineEdit()
find_layout.addWidget(find_label)
find_layout.addWidget(self.find_edit)
layout.addLayout(find_layout)
# 选项
options_layout = QHBoxLayout()
self.case_sensitive_checkbox = QCheckBox("区分大小写")
self.whole_words_checkbox = QCheckBox("全字匹配")
options_layout.addWidget(self.case_sensitive_checkbox)
options_layout.addWidget(self.whole_words_checkbox)
options_layout.addStretch()
layout.addLayout(options_layout)
# 按钮
buttons_layout = QHBoxLayout()
find_next_btn = QPushButton("查找下一个")
find_next_btn.clicked.connect(lambda: self.find_text(dialog))
cancel_btn = QPushButton("取消")
cancel_btn.clicked.connect(dialog.close)
buttons_layout.addWidget(find_next_btn)
buttons_layout.addWidget(cancel_btn)
layout.addLayout(buttons_layout)
dialog.setLayout(layout)
dialog.exec_()
def find_text(self, dialog):
"""执行查找操作"""
search_text = self.find_edit.text()
if not search_text:
QMessageBox.warning(self, "查找", "请输入查找内容")
return
# 获取当前光标位置
cursor = self.text_edit.textCursor()
start_pos = cursor.position()
# 设置查找选项
flags = QTextDocument.FindFlags()
if self.case_sensitive_checkbox.isChecked():
flags |= QTextDocument.FindCaseSensitively
if self.whole_words_checkbox.isChecked():
flags |= QTextDocument.FindWholeWords
# 执行查找
found_cursor = self.text_edit.document().find(search_text, start_pos, flags)
if found_cursor.isNull():
# 如果没找到,从文档开始处重新查找
found_cursor = self.text_edit.document().find(search_text, 0, flags)
if not found_cursor.isNull():
# 选中找到的文本
self.text_edit.setTextCursor(found_cursor)
self.text_edit.ensureCursorVisible()
else:
QMessageBox.information(self, "查找", f"找不到 '{search_text}'")
def show_replace_dialog(self):
"""显示替换对话框"""
# 创建替换对话框
dialog = QDialog(self)
dialog.setWindowTitle("替换")
dialog.setFixedSize(400, 200)
layout = QVBoxLayout()
# 查找内容输入
find_layout = QHBoxLayout()
find_label = QLabel("查找内容:")
self.replace_find_edit = QLineEdit()
find_layout.addWidget(find_label)
find_layout.addWidget(self.replace_find_edit)
layout.addLayout(find_layout)
# 替换为输入
replace_layout = QHBoxLayout()
replace_label = QLabel("替换为:")
self.replace_edit = QLineEdit()
replace_layout.addWidget(replace_label)
replace_layout.addWidget(self.replace_edit)
layout.addLayout(replace_layout)
# 选项
options_layout = QHBoxLayout()
self.replace_case_sensitive_checkbox = QCheckBox("区分大小写")
self.replace_whole_words_checkbox = QCheckBox("全字匹配")
options_layout.addWidget(self.replace_case_sensitive_checkbox)
options_layout.addWidget(self.replace_whole_words_checkbox)
options_layout.addStretch()
layout.addLayout(options_layout)
# 按钮
buttons_layout = QHBoxLayout()
find_next_btn = QPushButton("查找下一个")
replace_btn = QPushButton("替换")
replace_all_btn = QPushButton("全部替换")
cancel_btn = QPushButton("取消")
find_next_btn.clicked.connect(lambda: self.find_text_for_replace(dialog))
replace_btn.clicked.connect(lambda: self.replace_text(dialog))
replace_all_btn.clicked.connect(lambda: self.replace_all_text(dialog))
cancel_btn.clicked.connect(dialog.close)
buttons_layout.addWidget(find_next_btn)
buttons_layout.addWidget(replace_btn)
buttons_layout.addWidget(replace_all_btn)
buttons_layout.addWidget(cancel_btn)
layout.addLayout(buttons_layout)
dialog.setLayout(layout)
dialog.exec_()
def find_text_for_replace(self, dialog):
"""在替换对话框中执行查找操作"""
search_text = self.replace_find_edit.text()
if not search_text:
QMessageBox.warning(self, "查找", "请输入查找内容")
return
# 获取当前光标位置
cursor = self.text_edit.textCursor()
start_pos = cursor.position()
# 设置查找选项
flags = QTextDocument.FindFlags()
if self.replace_case_sensitive_checkbox.isChecked():
flags |= QTextDocument.FindCaseSensitively
if self.replace_whole_words_checkbox.isChecked():
flags |= QTextDocument.FindWholeWords
# 执行查找
found_cursor = self.text_edit.document().find(search_text, start_pos, flags)
if found_cursor.isNull():
# 如果没找到,从文档开始处重新查找
found_cursor = self.text_edit.document().find(search_text, 0, flags)
if not found_cursor.isNull():
# 选中找到的文本
self.text_edit.setTextCursor(found_cursor)
self.text_edit.ensureCursorVisible()
else:
QMessageBox.information(self, "查找", f"找不到 '{search_text}'")
def replace_text(self, dialog):
"""替换当前选中的文本"""
search_text = self.replace_find_edit.text()
replace_text = self.replace_edit.text()
# 检查是否有选中的文本且与查找内容匹配
cursor = self.text_edit.textCursor()
selected_text = cursor.selectedText()
# 检查是否匹配(考虑大小写敏感选项)
match = False
if self.replace_case_sensitive_checkbox.isChecked():
match = selected_text == search_text
else:
match = selected_text.lower() == search_text.lower()
if match:
# 替换选中的文本
cursor.insertText(replace_text)
# 继续查找下一个
self.find_text_for_replace(dialog)
else:
# 如果没有匹配的选中文本,执行查找
self.find_text_for_replace(dialog)
def replace_all_text(self, dialog):
"""替换所有匹配的文本"""
search_text = self.replace_find_edit.text()
replace_text = self.replace_edit.text()
if not search_text:
QMessageBox.warning(self, "替换", "请输入查找内容")
return
# 设置查找选项
flags = QTextDocument.FindFlags()
if self.replace_case_sensitive_checkbox.isChecked():
flags |= QTextDocument.FindCaseSensitively
if self.replace_whole_words_checkbox.isChecked():
flags |= QTextDocument.FindWholeWords
# 保存当前光标位置
original_cursor = self.text_edit.textCursor()
# 从文档开始处查找并替换所有匹配项
count = 0
cursor = self.text_edit.textCursor()
cursor.movePosition(QTextCursor.Start)
self.text_edit.setTextCursor(cursor)
while True:
found_cursor = self.text_edit.document().find(search_text, cursor, flags)
if found_cursor.isNull():
break
# 替换文本
found_cursor.insertText(replace_text)
count += 1
cursor = found_cursor
# 恢复原始光标位置
self.text_edit.setTextCursor(original_cursor)
# 显示替换结果
QMessageBox.information(self, "替换", f"已完成 {count} 处替换。")
def show_about(self):
"""显示关于对话框"""
QMessageBox.about(

Loading…
Cancel
Save