|
|
|
|
@ -17,6 +17,9 @@ from ui.word_style_ui import WeatherAPI
|
|
|
|
|
from file_parser import FileParser
|
|
|
|
|
from input_handler.input_processor import InputProcessor
|
|
|
|
|
|
|
|
|
|
# 导入主题管理器
|
|
|
|
|
from ui.theme_manager import theme_manager
|
|
|
|
|
|
|
|
|
|
class WeatherFetchThread(QThread):
|
|
|
|
|
weather_fetched = pyqtSignal(dict)
|
|
|
|
|
|
|
|
|
|
@ -98,6 +101,9 @@ class WordStyleMainWindow(QMainWindow):
|
|
|
|
|
self.setWindowTitle("文档1 - MagicWord")
|
|
|
|
|
self.setGeometry(100, 100, 1200, 800)
|
|
|
|
|
|
|
|
|
|
# 初始化主题
|
|
|
|
|
self.init_theme()
|
|
|
|
|
|
|
|
|
|
# 设置应用程序图标
|
|
|
|
|
self.set_window_icon()
|
|
|
|
|
|
|
|
|
|
@ -120,6 +126,261 @@ class WordStyleMainWindow(QMainWindow):
|
|
|
|
|
# 初始化时刷新天气
|
|
|
|
|
self.refresh_weather()
|
|
|
|
|
|
|
|
|
|
def init_theme(self):
|
|
|
|
|
"""初始化主题"""
|
|
|
|
|
# 连接主题切换信号
|
|
|
|
|
theme_manager.theme_changed.connect(self.on_theme_changed)
|
|
|
|
|
|
|
|
|
|
# 设置默认为白色模式(禁用自动检测)
|
|
|
|
|
theme_manager.enable_auto_detection(False)
|
|
|
|
|
theme_manager.set_dark_theme(False)
|
|
|
|
|
|
|
|
|
|
# 应用当前主题
|
|
|
|
|
self.apply_theme()
|
|
|
|
|
|
|
|
|
|
def apply_theme(self):
|
|
|
|
|
"""应用主题样式"""
|
|
|
|
|
is_dark = theme_manager.is_dark_theme()
|
|
|
|
|
|
|
|
|
|
# 应用主题样式表
|
|
|
|
|
stylesheet = theme_manager.get_theme_stylesheet(is_dark)
|
|
|
|
|
if stylesheet.strip(): # 只在有样式内容时应用
|
|
|
|
|
self.setStyleSheet(stylesheet)
|
|
|
|
|
|
|
|
|
|
# 更新组件样式
|
|
|
|
|
self.update_component_styles(is_dark)
|
|
|
|
|
|
|
|
|
|
def update_component_styles(self, is_dark):
|
|
|
|
|
"""更新组件样式"""
|
|
|
|
|
colors = theme_manager.get_current_theme_colors()
|
|
|
|
|
|
|
|
|
|
# 更新菜单栏样式 - 使用微软蓝
|
|
|
|
|
if hasattr(self, 'menubar'):
|
|
|
|
|
self.menubar.setStyleSheet("""
|
|
|
|
|
QMenuBar {
|
|
|
|
|
background-color: #0078d7;
|
|
|
|
|
border: 1px solid #005a9e;
|
|
|
|
|
font-size: 12px;
|
|
|
|
|
color: #ffffff;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QMenuBar::item {
|
|
|
|
|
background-color: transparent;
|
|
|
|
|
padding: 4px 10px;
|
|
|
|
|
color: #ffffff;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QMenuBar::item:selected {
|
|
|
|
|
background-color: #106ebe;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QMenuBar::item:pressed {
|
|
|
|
|
background-color: #005a9e;
|
|
|
|
|
color: #ffffff;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#startMenu {
|
|
|
|
|
background-color: white;
|
|
|
|
|
color: #000000;
|
|
|
|
|
}
|
|
|
|
|
""")
|
|
|
|
|
|
|
|
|
|
# 更新文件菜单样式
|
|
|
|
|
if hasattr(self, 'file_menu') and self.file_menu is not None:
|
|
|
|
|
self.file_menu.setStyleSheet(f"""
|
|
|
|
|
QMenu {{
|
|
|
|
|
background-color: {colors['surface']};
|
|
|
|
|
border: 1px solid {colors['border']};
|
|
|
|
|
font-size: 12px;
|
|
|
|
|
color: {colors['text']};
|
|
|
|
|
}}
|
|
|
|
|
|
|
|
|
|
QMenu::item {{
|
|
|
|
|
padding: 4px 20px;
|
|
|
|
|
color: {colors['text']};
|
|
|
|
|
background-color: transparent;
|
|
|
|
|
}}
|
|
|
|
|
|
|
|
|
|
QMenu::item:selected {{
|
|
|
|
|
background-color: {colors['surface_hover']};
|
|
|
|
|
}}
|
|
|
|
|
|
|
|
|
|
QMenu::item:pressed {{
|
|
|
|
|
background-color: {colors['accent']};
|
|
|
|
|
color: {colors['surface']};
|
|
|
|
|
}}
|
|
|
|
|
""")
|
|
|
|
|
|
|
|
|
|
# 更新视图菜单样式
|
|
|
|
|
if hasattr(self, 'view_menu') and self.view_menu is not None:
|
|
|
|
|
self.view_menu.setStyleSheet(f"""
|
|
|
|
|
QMenu {{
|
|
|
|
|
background-color: {colors['surface']};
|
|
|
|
|
border: 1px solid {colors['border']};
|
|
|
|
|
font-size: 12px;
|
|
|
|
|
color: {colors['text']};
|
|
|
|
|
}}
|
|
|
|
|
|
|
|
|
|
QMenu::item {{
|
|
|
|
|
padding: 4px 20px;
|
|
|
|
|
color: {colors['text']};
|
|
|
|
|
background-color: transparent;
|
|
|
|
|
}}
|
|
|
|
|
|
|
|
|
|
QMenu::item:selected {{
|
|
|
|
|
background-color: {colors['surface_hover']};
|
|
|
|
|
}}
|
|
|
|
|
|
|
|
|
|
QMenu::item:pressed {{
|
|
|
|
|
background-color: {colors['accent']};
|
|
|
|
|
color: {colors['surface']};
|
|
|
|
|
}}
|
|
|
|
|
""")
|
|
|
|
|
|
|
|
|
|
# 更新开始菜单样式
|
|
|
|
|
if hasattr(self, 'start_menu') and self.start_menu is not None:
|
|
|
|
|
self.start_menu.setStyleSheet(f"""
|
|
|
|
|
QMenu {{
|
|
|
|
|
background-color: {colors['surface']};
|
|
|
|
|
border: 1px solid {colors['border']};
|
|
|
|
|
font-size: 12px;
|
|
|
|
|
color: {colors['text']};
|
|
|
|
|
}}
|
|
|
|
|
|
|
|
|
|
QMenu::item {{
|
|
|
|
|
padding: 4px 20px;
|
|
|
|
|
color: {colors['text']};
|
|
|
|
|
background-color: transparent;
|
|
|
|
|
}}
|
|
|
|
|
|
|
|
|
|
QMenu::item:selected {{
|
|
|
|
|
background-color: {colors['surface_hover']};
|
|
|
|
|
}}
|
|
|
|
|
|
|
|
|
|
QMenu::item:pressed {{
|
|
|
|
|
background-color: {colors['accent']};
|
|
|
|
|
color: {colors['surface']};
|
|
|
|
|
}}
|
|
|
|
|
""")
|
|
|
|
|
|
|
|
|
|
# 更新文本编辑器样式
|
|
|
|
|
if hasattr(self, 'text_edit'):
|
|
|
|
|
self.text_edit.setStyleSheet(f"""
|
|
|
|
|
QTextEdit {{
|
|
|
|
|
background-color: {colors['surface']};
|
|
|
|
|
border: 1px solid {colors['border']};
|
|
|
|
|
border-radius: 0px;
|
|
|
|
|
font-family: 'Calibri', 'Microsoft YaHei', '微软雅黑', sans-serif;
|
|
|
|
|
font-size: 12pt;
|
|
|
|
|
color: {colors['text']};
|
|
|
|
|
padding: 40px;
|
|
|
|
|
line-height: 1.5;
|
|
|
|
|
}}
|
|
|
|
|
""")
|
|
|
|
|
|
|
|
|
|
# 更新滚动区域样式
|
|
|
|
|
if hasattr(self, 'scroll_area'):
|
|
|
|
|
self.scroll_area.setStyleSheet(f"""
|
|
|
|
|
QScrollArea {{
|
|
|
|
|
background-color: {colors['background']};
|
|
|
|
|
border: none;
|
|
|
|
|
}}
|
|
|
|
|
QScrollArea QWidget {{
|
|
|
|
|
background-color: {colors['background']};
|
|
|
|
|
}}
|
|
|
|
|
""")
|
|
|
|
|
|
|
|
|
|
# 更新图片列表样式(如果已存在)
|
|
|
|
|
if hasattr(self, 'image_list_widget') and self.image_list_widget is not None:
|
|
|
|
|
self.image_list_widget.setStyleSheet(f"""
|
|
|
|
|
QListWidget {{
|
|
|
|
|
background-color: {colors['surface']};
|
|
|
|
|
border: 1px solid {colors['border']};
|
|
|
|
|
border-radius: 4px;
|
|
|
|
|
font-size: 11px;
|
|
|
|
|
color: {colors['text']};
|
|
|
|
|
}}
|
|
|
|
|
QListWidget::item {{
|
|
|
|
|
padding: 5px;
|
|
|
|
|
border-bottom: 1px solid {colors['border']};
|
|
|
|
|
color: {colors['text']};
|
|
|
|
|
}}
|
|
|
|
|
QListWidget::item:selected {{
|
|
|
|
|
background-color: {colors['accent']};
|
|
|
|
|
color: {colors['surface']};
|
|
|
|
|
}}
|
|
|
|
|
""")
|
|
|
|
|
|
|
|
|
|
# 更新功能区下拉框样式
|
|
|
|
|
if hasattr(self, 'ribbon'):
|
|
|
|
|
self.update_ribbon_styles(is_dark)
|
|
|
|
|
|
|
|
|
|
def update_ribbon_styles(self, is_dark):
|
|
|
|
|
"""更新功能区样式"""
|
|
|
|
|
colors = theme_manager.get_current_theme_colors()
|
|
|
|
|
|
|
|
|
|
# 更新字体下拉框样式
|
|
|
|
|
if hasattr(self.ribbon, 'font_combo'):
|
|
|
|
|
self.ribbon.font_combo.setStyleSheet(f"""
|
|
|
|
|
QComboBox {{
|
|
|
|
|
background-color: {colors['surface']};
|
|
|
|
|
border: 1px solid {colors['border']};
|
|
|
|
|
border-radius: 2px;
|
|
|
|
|
color: {colors['text']};
|
|
|
|
|
padding: 2px 5px;
|
|
|
|
|
}}
|
|
|
|
|
|
|
|
|
|
QComboBox:hover {{
|
|
|
|
|
background-color: {colors['surface_hover']};
|
|
|
|
|
border: 1px solid {colors['accent']};
|
|
|
|
|
}}
|
|
|
|
|
|
|
|
|
|
QComboBox::drop-down {{
|
|
|
|
|
border: none;
|
|
|
|
|
width: 15px;
|
|
|
|
|
}}
|
|
|
|
|
|
|
|
|
|
QComboBox::down-arrow {{
|
|
|
|
|
image: none;
|
|
|
|
|
border-left: 3px solid transparent;
|
|
|
|
|
border-right: 3px solid transparent;
|
|
|
|
|
border-top: 5px solid {colors['text']};
|
|
|
|
|
}}
|
|
|
|
|
""")
|
|
|
|
|
|
|
|
|
|
# 更新字体大小下拉框样式
|
|
|
|
|
if hasattr(self.ribbon, 'size_combo'):
|
|
|
|
|
self.ribbon.size_combo.setStyleSheet(f"""
|
|
|
|
|
QComboBox {{
|
|
|
|
|
background-color: {colors['surface']};
|
|
|
|
|
border: 1px solid {colors['border']};
|
|
|
|
|
border-radius: 2px;
|
|
|
|
|
color: {colors['text']};
|
|
|
|
|
padding: 2px 5px;
|
|
|
|
|
}}
|
|
|
|
|
|
|
|
|
|
QComboBox:hover {{
|
|
|
|
|
background-color: {colors['surface_hover']};
|
|
|
|
|
border: 1px solid {colors['accent']};
|
|
|
|
|
}}
|
|
|
|
|
|
|
|
|
|
QComboBox::drop-down {{
|
|
|
|
|
border: none;
|
|
|
|
|
width: 15px;
|
|
|
|
|
}}
|
|
|
|
|
|
|
|
|
|
QComboBox::down-arrow {{
|
|
|
|
|
image: none;
|
|
|
|
|
border-left: 3px solid transparent;
|
|
|
|
|
border-right: 3px solid transparent;
|
|
|
|
|
border-top: 5px solid {colors['text']};
|
|
|
|
|
}}
|
|
|
|
|
""")
|
|
|
|
|
|
|
|
|
|
def on_theme_changed(self, is_dark):
|
|
|
|
|
"""主题切换槽函数"""
|
|
|
|
|
self.apply_theme()
|
|
|
|
|
|
|
|
|
|
def set_window_icon(self):
|
|
|
|
|
"""设置窗口图标"""
|
|
|
|
|
# 使用我们创建的Word风格图标
|
|
|
|
|
@ -247,30 +508,12 @@ class WordStyleMainWindow(QMainWindow):
|
|
|
|
|
def create_menu_bar(self):
|
|
|
|
|
"""创建菜单栏"""
|
|
|
|
|
menubar = self.menuBar()
|
|
|
|
|
menubar.setStyleSheet("""
|
|
|
|
|
QMenuBar {
|
|
|
|
|
background-color: #f3f2f1;
|
|
|
|
|
border-bottom: 1px solid #d0d0d0;
|
|
|
|
|
font-size: 12px;
|
|
|
|
|
color: #333333;
|
|
|
|
|
}
|
|
|
|
|
QMenuBar::item:selected {
|
|
|
|
|
background-color: #e1e1e1;
|
|
|
|
|
}
|
|
|
|
|
""")
|
|
|
|
|
menubar.setNativeMenuBar(False)
|
|
|
|
|
self.menubar = menubar # 保存为实例变量以便后续样式更新
|
|
|
|
|
|
|
|
|
|
# 文件菜单
|
|
|
|
|
file_menu = menubar.addMenu('文件(F)')
|
|
|
|
|
file_menu.setStyleSheet("""
|
|
|
|
|
QMenu {
|
|
|
|
|
background-color: #ffffff;
|
|
|
|
|
border: 1px solid #d0d0d0;
|
|
|
|
|
font-size: 12px;
|
|
|
|
|
}
|
|
|
|
|
QMenu::item:selected {
|
|
|
|
|
background-color: #e1e1e1;
|
|
|
|
|
}
|
|
|
|
|
""")
|
|
|
|
|
self.file_menu = file_menu # 保存为实例变量
|
|
|
|
|
|
|
|
|
|
# 新建
|
|
|
|
|
new_action = QAction('新建(N)', self)
|
|
|
|
|
@ -304,6 +547,8 @@ class WordStyleMainWindow(QMainWindow):
|
|
|
|
|
|
|
|
|
|
# 开始菜单
|
|
|
|
|
start_menu = menubar.addMenu('开始(S)')
|
|
|
|
|
start_menu.setObjectName("startMenu")
|
|
|
|
|
self.start_menu = start_menu # 保存为实例变量
|
|
|
|
|
|
|
|
|
|
# 撤销
|
|
|
|
|
undo_action = QAction('撤销(U)', self)
|
|
|
|
|
@ -339,6 +584,7 @@ class WordStyleMainWindow(QMainWindow):
|
|
|
|
|
|
|
|
|
|
# 视图菜单
|
|
|
|
|
view_menu = menubar.addMenu('视图(V)')
|
|
|
|
|
self.view_menu = view_menu # 保存为实例变量
|
|
|
|
|
|
|
|
|
|
# 阅读视图
|
|
|
|
|
read_view_action = QAction('阅读视图', self)
|
|
|
|
|
@ -354,6 +600,25 @@ class WordStyleMainWindow(QMainWindow):
|
|
|
|
|
|
|
|
|
|
view_menu.addSeparator()
|
|
|
|
|
|
|
|
|
|
# 模式选择子菜单
|
|
|
|
|
theme_menu = view_menu.addMenu('模式')
|
|
|
|
|
|
|
|
|
|
# 白色模式
|
|
|
|
|
self.light_mode_action = QAction('白色模式', self)
|
|
|
|
|
self.light_mode_action.setCheckable(True)
|
|
|
|
|
self.light_mode_action.setChecked(not theme_manager.is_dark_theme()) # 根据当前主题设置
|
|
|
|
|
self.light_mode_action.triggered.connect(self.set_light_mode)
|
|
|
|
|
theme_menu.addAction(self.light_mode_action)
|
|
|
|
|
|
|
|
|
|
# 黑色模式
|
|
|
|
|
self.dark_mode_action = QAction('黑色模式', self)
|
|
|
|
|
self.dark_mode_action.setCheckable(True)
|
|
|
|
|
self.dark_mode_action.setChecked(theme_manager.is_dark_theme()) # 根据当前主题设置
|
|
|
|
|
self.dark_mode_action.triggered.connect(self.set_dark_mode)
|
|
|
|
|
theme_menu.addAction(self.dark_mode_action)
|
|
|
|
|
|
|
|
|
|
view_menu.addSeparator()
|
|
|
|
|
|
|
|
|
|
# 视图模式选择
|
|
|
|
|
view_mode_menu = view_menu.addMenu('视图模式')
|
|
|
|
|
|
|
|
|
|
@ -402,24 +667,30 @@ class WordStyleMainWindow(QMainWindow):
|
|
|
|
|
show_weather_action = QAction('显示详细天气', self)
|
|
|
|
|
show_weather_action.triggered.connect(self.show_detailed_weather)
|
|
|
|
|
weather_menu.addAction(show_weather_action)
|
|
|
|
|
#插入
|
|
|
|
|
# 插入菜单
|
|
|
|
|
insert_menu = menubar.addMenu('插入(I)')
|
|
|
|
|
#绘图
|
|
|
|
|
|
|
|
|
|
# 绘图菜单
|
|
|
|
|
paint_menu = menubar.addMenu('绘图(D)')
|
|
|
|
|
#设计
|
|
|
|
|
|
|
|
|
|
# 设计菜单
|
|
|
|
|
design_menu = menubar.addMenu('设计(G)')
|
|
|
|
|
#布局
|
|
|
|
|
|
|
|
|
|
# 布局菜单
|
|
|
|
|
layout_menu = menubar.addMenu('布局(L)')
|
|
|
|
|
#引用
|
|
|
|
|
|
|
|
|
|
# 引用菜单
|
|
|
|
|
reference_menu = menubar.addMenu('引用(R)')
|
|
|
|
|
#邮件
|
|
|
|
|
|
|
|
|
|
# 邮件菜单
|
|
|
|
|
mail_menu = menubar.addMenu('邮件(M)')
|
|
|
|
|
#审阅
|
|
|
|
|
|
|
|
|
|
# 审阅菜单
|
|
|
|
|
review_menu = menubar.addMenu('审阅(W)')
|
|
|
|
|
#视图
|
|
|
|
|
view_menu = menubar.addMenu('视图(V)')
|
|
|
|
|
#开发工具
|
|
|
|
|
|
|
|
|
|
# 开发工具菜单
|
|
|
|
|
developer_menu = menubar.addMenu('开发工具(Q)')
|
|
|
|
|
|
|
|
|
|
# 帮助菜单
|
|
|
|
|
help_menu = menubar.addMenu('帮助(H)')
|
|
|
|
|
|
|
|
|
|
@ -435,11 +706,11 @@ class WordStyleMainWindow(QMainWindow):
|
|
|
|
|
# 创建滚动区域
|
|
|
|
|
from PyQt5.QtWidgets import QScrollArea
|
|
|
|
|
|
|
|
|
|
scroll_area = QScrollArea()
|
|
|
|
|
scroll_area.setWidgetResizable(True)
|
|
|
|
|
scroll_area.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded)
|
|
|
|
|
scroll_area.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
|
|
|
|
|
scroll_area.setStyleSheet("""
|
|
|
|
|
self.scroll_area = QScrollArea() # 保存为实例变量
|
|
|
|
|
self.scroll_area.setWidgetResizable(True)
|
|
|
|
|
self.scroll_area.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded)
|
|
|
|
|
self.scroll_area.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
|
|
|
|
|
self.scroll_area.setStyleSheet("""
|
|
|
|
|
QScrollArea {
|
|
|
|
|
background-color: #e1e1e1;
|
|
|
|
|
border: none;
|
|
|
|
|
@ -507,8 +778,8 @@ class WordStyleMainWindow(QMainWindow):
|
|
|
|
|
document_layout.addWidget(self.image_list_widget)
|
|
|
|
|
document_container.setLayout(document_layout)
|
|
|
|
|
|
|
|
|
|
scroll_area.setWidget(document_container)
|
|
|
|
|
main_layout.addWidget(scroll_area)
|
|
|
|
|
self.scroll_area.setWidget(document_container)
|
|
|
|
|
main_layout.addWidget(self.scroll_area)
|
|
|
|
|
|
|
|
|
|
def init_network_services(self):
|
|
|
|
|
"""初始化网络服务"""
|
|
|
|
|
@ -1567,132 +1838,59 @@ class WordStyleMainWindow(QMainWindow):
|
|
|
|
|
self.status_bar.showMessage("打印布局功能开发中...", 3000)
|
|
|
|
|
|
|
|
|
|
def set_view_mode(self, mode):
|
|
|
|
|
"""设置视图模式 - 实现文档A和学习文档C的正确交互"""
|
|
|
|
|
"""设置视图模式 - 打开学习模式窗口或切换到打字模式"""
|
|
|
|
|
if mode not in ["typing", "learning"]:
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
# 保存当前模式的内容
|
|
|
|
|
current_content = self.text_edit.toPlainText()
|
|
|
|
|
|
|
|
|
|
# 根据当前模式保存特定信息
|
|
|
|
|
if self.view_mode == "typing":
|
|
|
|
|
# 打字模式:保存打字内容到文档A
|
|
|
|
|
self.typing_mode_content = current_content
|
|
|
|
|
print(f"保存打字模式内容到文档A,长度: {len(self.typing_mode_content)}")
|
|
|
|
|
elif self.view_mode == "learning":
|
|
|
|
|
# 学习模式:保存当前学习进度和内容
|
|
|
|
|
self.learning_text = current_content
|
|
|
|
|
if hasattr(self, 'displayed_chars') and self.imported_content:
|
|
|
|
|
self.learning_progress = self.displayed_chars
|
|
|
|
|
print(f"保存学习模式内容,学习进度: {self.learning_progress}/{len(self.imported_content) if self.imported_content else 0}")
|
|
|
|
|
|
|
|
|
|
# 更新模式
|
|
|
|
|
self.view_mode = mode
|
|
|
|
|
self.last_edit_mode = mode
|
|
|
|
|
|
|
|
|
|
# 更新菜单项状态
|
|
|
|
|
self.typing_mode_action.setChecked(mode == "typing")
|
|
|
|
|
self.learning_mode_action.setChecked(mode == "learning")
|
|
|
|
|
|
|
|
|
|
# 临时禁用文本变化信号,避免递归
|
|
|
|
|
self.text_edit.textChanged.disconnect(self.on_text_changed)
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
if mode == "typing":
|
|
|
|
|
# 打字模式:显示学习模式下已输入的内容(文档A)
|
|
|
|
|
self.status_bar.showMessage("切换到打字模式 - 显示已输入的内容", 3000)
|
|
|
|
|
|
|
|
|
|
# 设置文档A的内容(学习模式下已输入的内容)
|
|
|
|
|
self.text_edit.clear()
|
|
|
|
|
if hasattr(self, 'learning_progress') and self.learning_progress > 0:
|
|
|
|
|
# 显示学习模式下已输入的内容
|
|
|
|
|
display_text = self.imported_content[:self.learning_progress]
|
|
|
|
|
self.text_edit.setPlainText(display_text)
|
|
|
|
|
else:
|
|
|
|
|
# 如果没有学习进度,显示默认提示
|
|
|
|
|
self.text_edit.setPlainText("请先在学习模式下输入内容")
|
|
|
|
|
if mode == "learning":
|
|
|
|
|
# 学习模式:打开新的学习模式窗口
|
|
|
|
|
try:
|
|
|
|
|
from learning_mode_window import LearningModeWindow
|
|
|
|
|
|
|
|
|
|
# 设置光标位置到文档末尾
|
|
|
|
|
cursor = self.text_edit.textCursor()
|
|
|
|
|
cursor.movePosition(cursor.End)
|
|
|
|
|
self.text_edit.setTextCursor(cursor)
|
|
|
|
|
# 准备传递给学习窗口的参数
|
|
|
|
|
imported_content = ""
|
|
|
|
|
current_position = 0
|
|
|
|
|
|
|
|
|
|
# 重置打字逻辑,准备接受新的输入
|
|
|
|
|
if self.typing_logic:
|
|
|
|
|
# 如果有已导入的内容,传递给学习窗口
|
|
|
|
|
if hasattr(self, 'imported_content') and self.imported_content:
|
|
|
|
|
imported_content = self.imported_content
|
|
|
|
|
if hasattr(self, 'learning_progress') and self.learning_progress > 0:
|
|
|
|
|
# 使用已输入的内容作为打字逻辑的基础
|
|
|
|
|
self.typing_logic.reset(self.imported_content)
|
|
|
|
|
# 设置当前位置到已输入的末尾
|
|
|
|
|
self.typing_logic.current_index = self.learning_progress
|
|
|
|
|
self.typing_logic.typed_chars = self.learning_progress
|
|
|
|
|
else:
|
|
|
|
|
self.typing_logic.reset("")
|
|
|
|
|
current_position = self.learning_progress
|
|
|
|
|
|
|
|
|
|
# 重置显示字符计数
|
|
|
|
|
self.displayed_chars = 0
|
|
|
|
|
# 创建学习模式窗口,直接传递导入内容
|
|
|
|
|
self.learning_window = LearningModeWindow(self, imported_content, current_position)
|
|
|
|
|
|
|
|
|
|
# 重置图片插入记录
|
|
|
|
|
if hasattr(self, 'inserted_images'):
|
|
|
|
|
self.inserted_images.clear()
|
|
|
|
|
# 显示学习模式窗口
|
|
|
|
|
self.learning_window.show()
|
|
|
|
|
|
|
|
|
|
elif mode == "learning":
|
|
|
|
|
# 学习模式:从上次中断的地方继续显示学习文档C的内容
|
|
|
|
|
if not self.imported_content:
|
|
|
|
|
self.status_bar.showMessage("学习模式需要导入文件 - 请先打开一个文件", 3000)
|
|
|
|
|
# 清空文本编辑器,等待导入文件
|
|
|
|
|
self.text_edit.clear()
|
|
|
|
|
if self.typing_logic:
|
|
|
|
|
self.typing_logic.reset("在此输入您的内容...")
|
|
|
|
|
# 重置显示字符计数
|
|
|
|
|
self.displayed_chars = 0
|
|
|
|
|
# 重置图片插入记录
|
|
|
|
|
if hasattr(self, 'inserted_images'):
|
|
|
|
|
self.inserted_images.clear()
|
|
|
|
|
else:
|
|
|
|
|
# 检查是否有保存的学习进度
|
|
|
|
|
if hasattr(self, 'learning_progress') and self.learning_progress > 0:
|
|
|
|
|
self.status_bar.showMessage(f"切换到学习模式 - 从上次中断处继续 ({self.learning_progress}/{len(self.imported_content)})", 3000)
|
|
|
|
|
# 恢复学习进度
|
|
|
|
|
self.displayed_chars = self.learning_progress
|
|
|
|
|
|
|
|
|
|
# 重置打字逻辑,准备接受导入内容
|
|
|
|
|
if self.typing_logic:
|
|
|
|
|
self.typing_logic.reset(self.imported_content)
|
|
|
|
|
|
|
|
|
|
# 获取应该显示的学习文档C的内容部分
|
|
|
|
|
display_text = self.imported_content[:self.displayed_chars]
|
|
|
|
|
|
|
|
|
|
# 设置文本内容
|
|
|
|
|
self.text_edit.clear()
|
|
|
|
|
self.text_edit.setPlainText(display_text)
|
|
|
|
|
|
|
|
|
|
# 设置光标位置到文本末尾
|
|
|
|
|
cursor = self.text_edit.textCursor()
|
|
|
|
|
cursor.movePosition(cursor.End)
|
|
|
|
|
self.text_edit.setTextCursor(cursor)
|
|
|
|
|
|
|
|
|
|
# 重新插入图片
|
|
|
|
|
if hasattr(self, 'inserted_images'):
|
|
|
|
|
self.inserted_images.clear()
|
|
|
|
|
self.insert_images_in_text()
|
|
|
|
|
else:
|
|
|
|
|
self.status_bar.showMessage("切换到学习模式 - 准备显示学习文档C内容", 3000)
|
|
|
|
|
# 重置打字逻辑,准备接受导入内容
|
|
|
|
|
if self.typing_logic:
|
|
|
|
|
self.typing_logic.reset(self.imported_content)
|
|
|
|
|
|
|
|
|
|
# 重置显示字符计数
|
|
|
|
|
self.displayed_chars = 0
|
|
|
|
|
|
|
|
|
|
# 清空文本编辑器,等待用户开始打字
|
|
|
|
|
self.text_edit.clear()
|
|
|
|
|
|
|
|
|
|
# 重置图片插入记录
|
|
|
|
|
if hasattr(self, 'inserted_images'):
|
|
|
|
|
self.inserted_images.clear()
|
|
|
|
|
finally:
|
|
|
|
|
# 重新连接文本变化信号
|
|
|
|
|
self.text_edit.textChanged.connect(self.on_text_changed)
|
|
|
|
|
# 更新菜单状态
|
|
|
|
|
self.learning_mode_action.setChecked(True)
|
|
|
|
|
self.typing_mode_action.setChecked(False)
|
|
|
|
|
|
|
|
|
|
# 切换到打字模式(主窗口保持打字模式)
|
|
|
|
|
self.view_mode = "typing"
|
|
|
|
|
|
|
|
|
|
self.status_bar.showMessage("学习模式窗口已打开", 3000)
|
|
|
|
|
|
|
|
|
|
except ImportError as e:
|
|
|
|
|
QMessageBox.critical(self, "错误", f"无法加载学习模式窗口:\n{str(e)}")
|
|
|
|
|
except Exception as e:
|
|
|
|
|
QMessageBox.critical(self, "错误", f"打开学习模式窗口时出错:\n{str(e)}")
|
|
|
|
|
|
|
|
|
|
elif mode == "typing":
|
|
|
|
|
# 打字模式:保持当前窗口状态
|
|
|
|
|
self.view_mode = "typing"
|
|
|
|
|
self.typing_mode_action.setChecked(True)
|
|
|
|
|
self.learning_mode_action.setChecked(False)
|
|
|
|
|
self.status_bar.showMessage("当前为打字模式", 2000)
|
|
|
|
|
|
|
|
|
|
def on_learning_mode_closed(self):
|
|
|
|
|
"""学习模式窗口关闭时的回调"""
|
|
|
|
|
# 重置菜单状态
|
|
|
|
|
self.learning_mode_action.setChecked(False)
|
|
|
|
|
self.typing_mode_action.setChecked(True)
|
|
|
|
|
self.view_mode = "typing"
|
|
|
|
|
self.status_bar.showMessage("学习模式窗口已关闭", 2000)
|
|
|
|
|
|
|
|
|
|
def set_page_color(self, color):
|
|
|
|
|
"""设置页面颜色"""
|
|
|
|
|
@ -2009,10 +2207,59 @@ class WordStyleMainWindow(QMainWindow):
|
|
|
|
|
|
|
|
|
|
def show_about(self):
|
|
|
|
|
"""显示关于对话框"""
|
|
|
|
|
QMessageBox.about(
|
|
|
|
|
self, "关于 MagicWord",
|
|
|
|
|
"MagicWord - 隐私学习软件\n\n"
|
|
|
|
|
"版本: 2.0\n"
|
|
|
|
|
# 创建自定义对话框
|
|
|
|
|
dialog = QDialog(self)
|
|
|
|
|
dialog.setWindowTitle("关于 MagicWord")
|
|
|
|
|
dialog.setModal(True)
|
|
|
|
|
dialog.setFixedSize(500, 400)
|
|
|
|
|
|
|
|
|
|
# 创建布局
|
|
|
|
|
layout = QVBoxLayout()
|
|
|
|
|
|
|
|
|
|
# 添加图标和标题布局
|
|
|
|
|
header_layout = QHBoxLayout()
|
|
|
|
|
|
|
|
|
|
# 添加应用程序图标
|
|
|
|
|
try:
|
|
|
|
|
icon_path = os.path.join(os.path.dirname(os.path.dirname(__file__)), "resources", "icons", "app_icon_128X128.png")
|
|
|
|
|
if os.path.exists(icon_path):
|
|
|
|
|
icon_label = QLabel()
|
|
|
|
|
icon_label.setAlignment(Qt.AlignCenter)
|
|
|
|
|
pixmap = QPixmap(icon_path)
|
|
|
|
|
if not pixmap.isNull():
|
|
|
|
|
# 缩放图标到合适大小
|
|
|
|
|
scaled_pixmap = pixmap.scaled(80, 80, Qt.KeepAspectRatio, Qt.SmoothTransformation)
|
|
|
|
|
icon_label.setPixmap(scaled_pixmap)
|
|
|
|
|
header_layout.addWidget(icon_label)
|
|
|
|
|
except Exception as e:
|
|
|
|
|
print(f"加载图标失败: {e}")
|
|
|
|
|
|
|
|
|
|
# 添加标题和版本信息
|
|
|
|
|
title_layout = QVBoxLayout()
|
|
|
|
|
title_label = QLabel("MagicWord")
|
|
|
|
|
title_label.setStyleSheet("font-size: 24px; font-weight: bold; color: #0078d7;")
|
|
|
|
|
title_label.setAlignment(Qt.AlignCenter)
|
|
|
|
|
|
|
|
|
|
version_label = QLabel("版本 1.0")
|
|
|
|
|
version_label.setStyleSheet("font-size: 14px; color: #666;")
|
|
|
|
|
version_label.setAlignment(Qt.AlignCenter)
|
|
|
|
|
|
|
|
|
|
title_layout.addWidget(title_label)
|
|
|
|
|
title_layout.addWidget(version_label)
|
|
|
|
|
header_layout.addLayout(title_layout)
|
|
|
|
|
|
|
|
|
|
layout.addLayout(header_layout)
|
|
|
|
|
|
|
|
|
|
# 添加分隔线
|
|
|
|
|
separator = QFrame()
|
|
|
|
|
separator.setFrameShape(QFrame.HLine)
|
|
|
|
|
separator.setFrameShadow(QFrame.Sunken)
|
|
|
|
|
separator.setStyleSheet("color: #ddd;")
|
|
|
|
|
layout.addWidget(separator)
|
|
|
|
|
|
|
|
|
|
# 添加关于信息
|
|
|
|
|
about_text = QLabel(
|
|
|
|
|
"隐私学习软件\n\n"
|
|
|
|
|
"基于 Microsoft Word 界面设计\n\n"
|
|
|
|
|
"功能特色:\n"
|
|
|
|
|
"• 仿Word界面设计\n"
|
|
|
|
|
@ -2021,6 +2268,79 @@ class WordStyleMainWindow(QMainWindow):
|
|
|
|
|
"• 实时进度跟踪\n"
|
|
|
|
|
"• 天气和名言显示"
|
|
|
|
|
)
|
|
|
|
|
about_text.setAlignment(Qt.AlignCenter)
|
|
|
|
|
about_text.setStyleSheet("font-size: 12px; line-height: 1.5;")
|
|
|
|
|
layout.addWidget(about_text)
|
|
|
|
|
|
|
|
|
|
# 添加按钮布局
|
|
|
|
|
button_layout = QHBoxLayout()
|
|
|
|
|
button_layout.addStretch() # 添加弹性空间使按钮居中
|
|
|
|
|
|
|
|
|
|
# 添加"沃式烁"按钮
|
|
|
|
|
woshishuo_button = QPushButton("沃式烁")
|
|
|
|
|
woshishuo_button.clicked.connect(lambda: self.show_woshishuo_image())
|
|
|
|
|
button_layout.addWidget(woshishuo_button)
|
|
|
|
|
|
|
|
|
|
# 添加OK按钮
|
|
|
|
|
ok_button = QPushButton("OK")
|
|
|
|
|
ok_button.clicked.connect(dialog.accept)
|
|
|
|
|
button_layout.addWidget(ok_button)
|
|
|
|
|
|
|
|
|
|
button_layout.addStretch() # 添加弹性空间使按钮居中
|
|
|
|
|
|
|
|
|
|
layout.addLayout(button_layout)
|
|
|
|
|
dialog.setLayout(layout)
|
|
|
|
|
|
|
|
|
|
# 显示对话框
|
|
|
|
|
dialog.exec_()
|
|
|
|
|
|
|
|
|
|
def show_woshishuo_image(self):
|
|
|
|
|
"""显示沃式烁图片"""
|
|
|
|
|
try:
|
|
|
|
|
# 图片路径
|
|
|
|
|
image_path = os.path.join(os.path.dirname(__file__), "ui", "114514.png")
|
|
|
|
|
|
|
|
|
|
# 检查图片是否存在
|
|
|
|
|
if not os.path.exists(image_path):
|
|
|
|
|
QMessageBox.warning(self, "错误", "图片文件不存在: 114514.png")
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
# 创建图片查看对话框
|
|
|
|
|
image_dialog = QDialog(self)
|
|
|
|
|
image_dialog.setWindowTitle("沃式烁")
|
|
|
|
|
image_dialog.setModal(True)
|
|
|
|
|
image_dialog.setFixedSize(500, 400)
|
|
|
|
|
|
|
|
|
|
# 创建布局
|
|
|
|
|
layout = QVBoxLayout()
|
|
|
|
|
|
|
|
|
|
# 添加图片标签
|
|
|
|
|
image_label = QLabel()
|
|
|
|
|
image_label.setAlignment(Qt.AlignCenter)
|
|
|
|
|
image_label.setScaledContents(True)
|
|
|
|
|
|
|
|
|
|
# 加载图片
|
|
|
|
|
pixmap = QPixmap(image_path)
|
|
|
|
|
if pixmap.isNull():
|
|
|
|
|
QMessageBox.warning(self, "错误", "无法加载图片文件")
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
# 缩放图片以适应对话框
|
|
|
|
|
scaled_pixmap = pixmap.scaled(450, 300, Qt.KeepAspectRatio, Qt.SmoothTransformation)
|
|
|
|
|
image_label.setPixmap(scaled_pixmap)
|
|
|
|
|
|
|
|
|
|
layout.addWidget(image_label)
|
|
|
|
|
|
|
|
|
|
# 添加关闭按钮
|
|
|
|
|
close_button = QPushButton("关闭")
|
|
|
|
|
close_button.clicked.connect(image_dialog.accept)
|
|
|
|
|
layout.addWidget(close_button)
|
|
|
|
|
|
|
|
|
|
image_dialog.setLayout(layout)
|
|
|
|
|
image_dialog.exec_()
|
|
|
|
|
|
|
|
|
|
except Exception as e:
|
|
|
|
|
QMessageBox.warning(self, "错误", f"显示图片时出错: {str(e)}")
|
|
|
|
|
|
|
|
|
|
def highlight_next_char(self, position, expected_char):
|
|
|
|
|
"""高亮显示下一个期望字符"""
|
|
|
|
|
@ -2067,50 +2387,137 @@ class WordStyleMainWindow(QMainWindow):
|
|
|
|
|
except Exception as e:
|
|
|
|
|
self.status_bar.showMessage(f"显示图片失败: {str(e)}", 3000)
|
|
|
|
|
|
|
|
|
|
def set_light_mode(self):
|
|
|
|
|
"""设置为白色模式"""
|
|
|
|
|
theme_manager.set_dark_theme(False)
|
|
|
|
|
self.light_mode_action.setChecked(True)
|
|
|
|
|
self.dark_mode_action.setChecked(False)
|
|
|
|
|
self.status_bar.showMessage("已切换到白色模式", 2000)
|
|
|
|
|
|
|
|
|
|
def set_dark_mode(self):
|
|
|
|
|
"""设置为黑色模式"""
|
|
|
|
|
theme_manager.set_dark_theme(True)
|
|
|
|
|
self.light_mode_action.setChecked(False)
|
|
|
|
|
self.dark_mode_action.setChecked(True)
|
|
|
|
|
self.status_bar.showMessage("已切换到黑色模式", 2000)
|
|
|
|
|
|
|
|
|
|
def show_image_viewer(self, filename, image_data):
|
|
|
|
|
"""显示图片查看器"""
|
|
|
|
|
"""显示图片查看器 - 图片真正铺满整个窗口上方"""
|
|
|
|
|
try:
|
|
|
|
|
# 创建图片查看窗口
|
|
|
|
|
# 创建自定义图片查看窗口
|
|
|
|
|
viewer = QDialog(self)
|
|
|
|
|
viewer.setWindowTitle(f"图片查看 - {filename}")
|
|
|
|
|
viewer.setModal(False)
|
|
|
|
|
viewer.resize(800, 600)
|
|
|
|
|
|
|
|
|
|
# 创建布局
|
|
|
|
|
layout = QVBoxLayout()
|
|
|
|
|
# 移除窗口边框和标题栏装饰,设置为工具窗口样式
|
|
|
|
|
viewer.setWindowFlags(Qt.Tool | Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint)
|
|
|
|
|
|
|
|
|
|
# 创建滚动区域
|
|
|
|
|
scroll_area = QScrollArea()
|
|
|
|
|
scroll_area.setWidgetResizable(True)
|
|
|
|
|
# 设置窗口背景为黑色,完全无边距
|
|
|
|
|
viewer.setStyleSheet("""
|
|
|
|
|
QDialog {
|
|
|
|
|
background-color: #000000;
|
|
|
|
|
border: none;
|
|
|
|
|
margin: 0px;
|
|
|
|
|
padding: 0px;
|
|
|
|
|
}
|
|
|
|
|
""")
|
|
|
|
|
|
|
|
|
|
# 创建布局,完全移除边距
|
|
|
|
|
layout = QVBoxLayout()
|
|
|
|
|
layout.setContentsMargins(0, 0, 0, 0) # 移除布局边距
|
|
|
|
|
layout.setSpacing(0) # 移除组件间距
|
|
|
|
|
layout.setAlignment(Qt.AlignCenter) # 布局居中对齐
|
|
|
|
|
|
|
|
|
|
# 创建图片标签
|
|
|
|
|
# 创建图片标签,设置为完全填充模式
|
|
|
|
|
image_label = QLabel()
|
|
|
|
|
image_label.setAlignment(Qt.AlignCenter)
|
|
|
|
|
image_label.setScaledContents(True) # 关键:允许图片缩放以填充标签
|
|
|
|
|
image_label.setMinimumSize(1, 1) # 设置最小尺寸
|
|
|
|
|
image_label.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) # 设置大小策略为扩展
|
|
|
|
|
image_label.setStyleSheet("""
|
|
|
|
|
QLabel {
|
|
|
|
|
border: none;
|
|
|
|
|
margin: 0px;
|
|
|
|
|
padding: 0px;
|
|
|
|
|
background-color: #000000;
|
|
|
|
|
}
|
|
|
|
|
""")
|
|
|
|
|
|
|
|
|
|
# 加载图片
|
|
|
|
|
pixmap = QPixmap()
|
|
|
|
|
if pixmap.loadFromData(image_data):
|
|
|
|
|
image_label.setPixmap(pixmap)
|
|
|
|
|
image_label.setScaledContents(False)
|
|
|
|
|
|
|
|
|
|
# 设置标签大小为图片实际大小
|
|
|
|
|
image_label.setFixedSize(pixmap.size())
|
|
|
|
|
else:
|
|
|
|
|
image_label.setText("无法加载图片")
|
|
|
|
|
if not pixmap.loadFromData(image_data):
|
|
|
|
|
self.status_bar.showMessage(f"加载图片失败: {filename}", 3000)
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
scroll_area.setWidget(image_label)
|
|
|
|
|
layout.addWidget(scroll_area)
|
|
|
|
|
layout.addWidget(image_label)
|
|
|
|
|
viewer.setLayout(layout)
|
|
|
|
|
|
|
|
|
|
# 添加关闭按钮
|
|
|
|
|
close_btn = QPushButton("关闭")
|
|
|
|
|
close_btn.clicked.connect(viewer.close)
|
|
|
|
|
layout.addWidget(close_btn)
|
|
|
|
|
# 计算位置和大小
|
|
|
|
|
if self:
|
|
|
|
|
parent_geometry = self.geometry()
|
|
|
|
|
screen_geometry = QApplication.primaryScreen().geometry()
|
|
|
|
|
|
|
|
|
|
# 设置窗口宽度与主窗口相同,高度为屏幕高度的40%
|
|
|
|
|
window_width = parent_geometry.width()
|
|
|
|
|
window_height = int(screen_geometry.height() * 0.4)
|
|
|
|
|
|
|
|
|
|
# 计算位置:显示在主窗口正上方
|
|
|
|
|
x = parent_geometry.x()
|
|
|
|
|
y = parent_geometry.y() - window_height
|
|
|
|
|
|
|
|
|
|
# 确保不会超出屏幕边界
|
|
|
|
|
if y < screen_geometry.top():
|
|
|
|
|
y = parent_geometry.y() + 50 # 如果上方空间不足,显示在下方
|
|
|
|
|
|
|
|
|
|
# 调整宽度确保不超出屏幕
|
|
|
|
|
if x + window_width > screen_geometry.right():
|
|
|
|
|
window_width = screen_geometry.right() - x
|
|
|
|
|
|
|
|
|
|
viewer.setGeometry(x, y, window_width, window_height)
|
|
|
|
|
|
|
|
|
|
viewer.setLayout(layout)
|
|
|
|
|
viewer.show()
|
|
|
|
|
|
|
|
|
|
# 关键:强制图片立即填充整个标签区域
|
|
|
|
|
def force_image_fill():
|
|
|
|
|
try:
|
|
|
|
|
if pixmap and not pixmap.isNull():
|
|
|
|
|
# 获取标签的实际大小
|
|
|
|
|
label_size = image_label.size()
|
|
|
|
|
if label_size.width() > 10 and label_size.height() > 10: # 确保尺寸有效
|
|
|
|
|
# 完全填充,忽略宽高比,真正铺满
|
|
|
|
|
scaled_pixmap = pixmap.scaled(
|
|
|
|
|
label_size,
|
|
|
|
|
Qt.IgnoreAspectRatio, # 关键:忽略宽高比,强制填充
|
|
|
|
|
Qt.SmoothTransformation
|
|
|
|
|
)
|
|
|
|
|
image_label.setPixmap(scaled_pixmap)
|
|
|
|
|
print(f"图片已强制缩放至 {label_size.width()}x{label_size.height()}")
|
|
|
|
|
|
|
|
|
|
# 确保标签完全填充布局
|
|
|
|
|
image_label.setMinimumSize(label_size)
|
|
|
|
|
except Exception as e:
|
|
|
|
|
print(f"图片缩放失败: {e}")
|
|
|
|
|
|
|
|
|
|
# 使用多个定时器确保图片正确填充
|
|
|
|
|
from PyQt5.QtCore import QTimer
|
|
|
|
|
QTimer.singleShot(50, force_image_fill) # 50毫秒后执行
|
|
|
|
|
QTimer.singleShot(200, force_image_fill) # 200毫秒后执行
|
|
|
|
|
QTimer.singleShot(1000, force_image_fill) # 1000毫秒后再执行一次
|
|
|
|
|
|
|
|
|
|
# 连接窗口大小变化事件
|
|
|
|
|
viewer.resizeEvent = lambda event: force_image_fill()
|
|
|
|
|
|
|
|
|
|
# 添加点击关闭功能
|
|
|
|
|
def close_viewer():
|
|
|
|
|
viewer.close()
|
|
|
|
|
|
|
|
|
|
image_label.mousePressEvent = lambda event: close_viewer()
|
|
|
|
|
viewer.mousePressEvent = lambda event: close_viewer()
|
|
|
|
|
|
|
|
|
|
except Exception as e:
|
|
|
|
|
self.status_bar.showMessage(f"创建图片查看器失败: {str(e)}", 3000)
|
|
|
|
|
import traceback
|
|
|
|
|
traceback.print_exc()
|
|
|
|
|
|
|
|
|
|
def insert_images_in_text(self):
|
|
|
|
|
"""在文本中插入图片 - 修复图片显示逻辑"""
|
|
|
|
|
|