|
|
|
@ -6,7 +6,8 @@ from PyQt5.QtWidgets import (QMainWindow, QWidget, QVBoxLayout, QHBoxLayout,
|
|
|
|
QTextEdit, QLabel, QSplitter, QFrame, QMenuBar,
|
|
|
|
QTextEdit, QLabel, QSplitter, QFrame, QMenuBar,
|
|
|
|
QAction, QFileDialog, QMessageBox, QApplication,
|
|
|
|
QAction, QFileDialog, QMessageBox, QApplication,
|
|
|
|
QDialog, QLineEdit, QCheckBox, QPushButton, QListWidget,
|
|
|
|
QDialog, QLineEdit, QCheckBox, QPushButton, QListWidget,
|
|
|
|
QListWidgetItem, QScrollArea)
|
|
|
|
QListWidgetItem, QScrollArea, QSizePolicy,
|
|
|
|
|
|
|
|
QGraphicsScene, QGraphicsView)
|
|
|
|
from PyQt5.QtCore import Qt, QThread, pyqtSignal, QTimer, QRect, QByteArray, QBuffer, QIODevice
|
|
|
|
from PyQt5.QtCore import Qt, QThread, pyqtSignal, QTimer, QRect, QByteArray, QBuffer, QIODevice
|
|
|
|
from PyQt5.QtGui import QFont, QPalette, QColor, QIcon, QPixmap, QTextCharFormat, QTextCursor, QTextDocument, QImage, QTextImageFormat, QTextFormat, QTextBlockFormat
|
|
|
|
from PyQt5.QtGui import QFont, QPalette, QColor, QIcon, QPixmap, QTextCharFormat, QTextCursor, QTextDocument, QImage, QTextImageFormat, QTextFormat, QTextBlockFormat
|
|
|
|
|
|
|
|
|
|
|
|
@ -323,6 +324,11 @@ class WordStyleMainWindow(QMainWindow):
|
|
|
|
# 更新功能区下拉框样式
|
|
|
|
# 更新功能区下拉框样式
|
|
|
|
if hasattr(self, 'ribbon'):
|
|
|
|
if hasattr(self, 'ribbon'):
|
|
|
|
self.update_ribbon_styles(is_dark)
|
|
|
|
self.update_ribbon_styles(is_dark)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# 更新日历组件样式
|
|
|
|
|
|
|
|
if hasattr(self, 'calendar_widget') and self.calendar_widget is not None:
|
|
|
|
|
|
|
|
# 日历组件有自己的主题管理机制,只需触发其主题更新
|
|
|
|
|
|
|
|
self.calendar_widget.apply_theme()
|
|
|
|
|
|
|
|
|
|
|
|
def update_ribbon_styles(self, is_dark):
|
|
|
|
def update_ribbon_styles(self, is_dark):
|
|
|
|
"""更新功能区样式"""
|
|
|
|
"""更新功能区样式"""
|
|
|
|
@ -694,6 +700,21 @@ class WordStyleMainWindow(QMainWindow):
|
|
|
|
insert_image_action.triggered.connect(self.insert_image_in_typing_mode)
|
|
|
|
insert_image_action.triggered.connect(self.insert_image_in_typing_mode)
|
|
|
|
insert_menu.addAction(insert_image_action)
|
|
|
|
insert_menu.addAction(insert_image_action)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# 插入天气信息功能
|
|
|
|
|
|
|
|
insert_weather_action = QAction('插入天气信息', self)
|
|
|
|
|
|
|
|
insert_weather_action.triggered.connect(self.insert_weather_info)
|
|
|
|
|
|
|
|
insert_menu.addAction(insert_weather_action)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# 插入每日一句名言功能
|
|
|
|
|
|
|
|
insert_quote_action = QAction('插入每日一句名言', self)
|
|
|
|
|
|
|
|
insert_quote_action.triggered.connect(self.insert_daily_quote)
|
|
|
|
|
|
|
|
insert_menu.addAction(insert_quote_action)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# 插入古诗词功能
|
|
|
|
|
|
|
|
insert_poetry_action = QAction('插入古诗词', self)
|
|
|
|
|
|
|
|
insert_poetry_action.triggered.connect(self.insert_chinese_poetry)
|
|
|
|
|
|
|
|
insert_menu.addAction(insert_poetry_action)
|
|
|
|
|
|
|
|
|
|
|
|
# 绘图菜单
|
|
|
|
# 绘图菜单
|
|
|
|
paint_menu = menubar.addMenu('绘图(D)')
|
|
|
|
paint_menu = menubar.addMenu('绘图(D)')
|
|
|
|
|
|
|
|
|
|
|
|
@ -1833,7 +1854,7 @@ class WordStyleMainWindow(QMainWindow):
|
|
|
|
self.status_bar.showMessage("新建文档 - 打字模式,可以自由开始打字", 3000)
|
|
|
|
self.status_bar.showMessage("新建文档 - 打字模式,可以自由开始打字", 3000)
|
|
|
|
|
|
|
|
|
|
|
|
def import_file(self):
|
|
|
|
def import_file(self):
|
|
|
|
"""导入文件 - 仅在导入时存储内容,不立即显示"""
|
|
|
|
"""导入文件 - 根据模式决定是否立即显示"""
|
|
|
|
file_path, _ = QFileDialog.getOpenFileName(
|
|
|
|
file_path, _ = QFileDialog.getOpenFileName(
|
|
|
|
self, "导入文件", "",
|
|
|
|
self, "导入文件", "",
|
|
|
|
"文档文件 (*.docx *.txt *.pdf *.html);;所有文件 (*.*)"
|
|
|
|
"文档文件 (*.docx *.txt *.pdf *.html);;所有文件 (*.*)"
|
|
|
|
@ -1854,7 +1875,7 @@ class WordStyleMainWindow(QMainWindow):
|
|
|
|
if result.get('is_temp_file', False):
|
|
|
|
if result.get('is_temp_file', False):
|
|
|
|
self.temp_files.append(txt_path)
|
|
|
|
self.temp_files.append(txt_path)
|
|
|
|
|
|
|
|
|
|
|
|
# 存储完整内容但不立即显示
|
|
|
|
# 存储完整内容
|
|
|
|
self.imported_content = content
|
|
|
|
self.imported_content = content
|
|
|
|
self.displayed_chars = 0
|
|
|
|
self.displayed_chars = 0
|
|
|
|
|
|
|
|
|
|
|
|
@ -1896,8 +1917,9 @@ class WordStyleMainWindow(QMainWindow):
|
|
|
|
|
|
|
|
|
|
|
|
self.status_bar.showMessage(f"已导入: {os.path.basename(txt_path)},开始打字逐步显示学习内容!", 5000)
|
|
|
|
self.status_bar.showMessage(f"已导入: {os.path.basename(txt_path)},开始打字逐步显示学习内容!", 5000)
|
|
|
|
else:
|
|
|
|
else:
|
|
|
|
# 打字模式:不显示导入内容,保持当前内容
|
|
|
|
# 打字模式:直接显示完整内容
|
|
|
|
self.status_bar.showMessage(f"已导入: {os.path.basename(txt_path)},切换到学习模式查看内容", 5000)
|
|
|
|
self.text_edit.setPlainText(content)
|
|
|
|
|
|
|
|
self.status_bar.showMessage(f"已导入: {os.path.basename(txt_path)}", 5000)
|
|
|
|
|
|
|
|
|
|
|
|
# 提取并显示图片(如果有)
|
|
|
|
# 提取并显示图片(如果有)
|
|
|
|
if images:
|
|
|
|
if images:
|
|
|
|
@ -1914,7 +1936,7 @@ class WordStyleMainWindow(QMainWindow):
|
|
|
|
content = parser.parse_file(file_path)
|
|
|
|
content = parser.parse_file(file_path)
|
|
|
|
|
|
|
|
|
|
|
|
if content:
|
|
|
|
if content:
|
|
|
|
# 存储完整内容但不立即显示
|
|
|
|
# 存储完整内容
|
|
|
|
self.imported_content = content
|
|
|
|
self.imported_content = content
|
|
|
|
self.displayed_chars = 0
|
|
|
|
self.displayed_chars = 0
|
|
|
|
|
|
|
|
|
|
|
|
@ -1929,8 +1951,9 @@ class WordStyleMainWindow(QMainWindow):
|
|
|
|
|
|
|
|
|
|
|
|
self.status_bar.showMessage(f"已导入: {os.path.basename(file_path)},开始打字逐步显示学习内容!", 5000)
|
|
|
|
self.status_bar.showMessage(f"已导入: {os.path.basename(file_path)},开始打字逐步显示学习内容!", 5000)
|
|
|
|
else:
|
|
|
|
else:
|
|
|
|
# 打字模式:不显示导入内容,保持当前内容
|
|
|
|
# 打字模式:直接显示完整内容
|
|
|
|
self.status_bar.showMessage(f"已导入: {os.path.basename(file_path)},切换到学习模式查看内容", 5000)
|
|
|
|
self.text_edit.setPlainText(content)
|
|
|
|
|
|
|
|
self.status_bar.showMessage(f"已导入: {os.path.basename(file_path)}", 5000)
|
|
|
|
|
|
|
|
|
|
|
|
except Exception as fallback_e:
|
|
|
|
except Exception as fallback_e:
|
|
|
|
QMessageBox.critical(self, "错误", f"无法导入文件:\n{str(e)}\n\n回退方法也失败:\n{str(fallback_e)}")
|
|
|
|
QMessageBox.critical(self, "错误", f"无法导入文件:\n{str(e)}\n\n回退方法也失败:\n{str(fallback_e)}")
|
|
|
|
@ -1955,7 +1978,7 @@ class WordStyleMainWindow(QMainWindow):
|
|
|
|
# 设置文件加载标志
|
|
|
|
# 设置文件加载标志
|
|
|
|
self.is_loading_file = True
|
|
|
|
self.is_loading_file = True
|
|
|
|
|
|
|
|
|
|
|
|
# 存储完整内容但不立即显示
|
|
|
|
# 存储完整内容
|
|
|
|
self.imported_content = content
|
|
|
|
self.imported_content = content
|
|
|
|
self.displayed_chars = 0
|
|
|
|
self.displayed_chars = 0
|
|
|
|
|
|
|
|
|
|
|
|
@ -2129,8 +2152,17 @@ class WordStyleMainWindow(QMainWindow):
|
|
|
|
current_position = 0
|
|
|
|
current_position = 0
|
|
|
|
self.imported_content = current_text
|
|
|
|
self.imported_content = current_text
|
|
|
|
|
|
|
|
|
|
|
|
# 创建学习模式窗口,直接传递导入内容
|
|
|
|
# 准备图片数据
|
|
|
|
self.learning_window = LearningModeWindow(self, imported_content, current_position)
|
|
|
|
image_data = None
|
|
|
|
|
|
|
|
image_positions = None
|
|
|
|
|
|
|
|
if hasattr(self, 'typing_logic') and self.typing_logic:
|
|
|
|
|
|
|
|
if hasattr(self.typing_logic, 'image_data'):
|
|
|
|
|
|
|
|
image_data = self.typing_logic.image_data
|
|
|
|
|
|
|
|
if hasattr(self.typing_logic, 'image_positions'):
|
|
|
|
|
|
|
|
image_positions = self.typing_logic.image_positions
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# 创建学习模式窗口,传递导入内容和图片数据
|
|
|
|
|
|
|
|
self.learning_window = LearningModeWindow(self, imported_content, current_position, image_data, image_positions)
|
|
|
|
|
|
|
|
|
|
|
|
# 连接学习模式窗口的内容变化信号
|
|
|
|
# 连接学习模式窗口的内容变化信号
|
|
|
|
self.learning_window.content_changed.connect(self.on_learning_content_changed)
|
|
|
|
self.learning_window.content_changed.connect(self.on_learning_content_changed)
|
|
|
|
@ -2718,46 +2750,37 @@ class WordStyleMainWindow(QMainWindow):
|
|
|
|
self.status_bar.showMessage("已切换到黑色模式", 2000)
|
|
|
|
self.status_bar.showMessage("已切换到黑色模式", 2000)
|
|
|
|
|
|
|
|
|
|
|
|
def show_image_viewer(self, filename, image_data):
|
|
|
|
def show_image_viewer(self, filename, image_data):
|
|
|
|
"""显示图片查看器 - 图片真正铺满整个窗口上方"""
|
|
|
|
"""显示图片查看器 - 支持缩放功能"""
|
|
|
|
try:
|
|
|
|
try:
|
|
|
|
# 创建自定义图片查看窗口
|
|
|
|
# 创建自定义图片查看窗口
|
|
|
|
viewer = QDialog(self)
|
|
|
|
viewer = QDialog(self)
|
|
|
|
viewer.setWindowTitle(f"图片查看 - {filename}")
|
|
|
|
viewer.setWindowTitle(f"图片查看 - {filename}")
|
|
|
|
viewer.setModal(False)
|
|
|
|
viewer.setModal(False)
|
|
|
|
|
|
|
|
|
|
|
|
# 移除窗口边框和标题栏装饰,设置为工具窗口样式
|
|
|
|
# 设置窗口标志,保留标题栏以便用户可以移动和调整大小
|
|
|
|
viewer.setWindowFlags(Qt.Tool | Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint)
|
|
|
|
viewer.setWindowFlags(Qt.Tool | Qt.WindowCloseButtonHint | Qt.WindowMinMaxButtonsHint)
|
|
|
|
|
|
|
|
|
|
|
|
# 设置窗口背景为黑色,完全无边距
|
|
|
|
# 设置窗口背景为黑色
|
|
|
|
viewer.setStyleSheet("""
|
|
|
|
viewer.setStyleSheet("""
|
|
|
|
QDialog {
|
|
|
|
QDialog {
|
|
|
|
background-color: #000000;
|
|
|
|
background-color: #000000;
|
|
|
|
border: none;
|
|
|
|
|
|
|
|
margin: 0px;
|
|
|
|
|
|
|
|
padding: 0px;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
""")
|
|
|
|
""")
|
|
|
|
|
|
|
|
|
|
|
|
# 创建布局,完全移除边距
|
|
|
|
# 创建场景和视图
|
|
|
|
layout = QVBoxLayout()
|
|
|
|
scene = QGraphicsScene(viewer)
|
|
|
|
layout.setContentsMargins(0, 0, 0, 0) # 移除布局边距
|
|
|
|
view = QGraphicsView(scene)
|
|
|
|
layout.setSpacing(0) # 移除组件间距
|
|
|
|
view.setStyleSheet("border: none;") # 移除视图边框
|
|
|
|
layout.setAlignment(Qt.AlignCenter) # 布局居中对齐
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# 创建图片标签,设置为完全填充模式
|
|
|
|
# 设置视图为可交互的,并启用滚动条
|
|
|
|
image_label = QLabel()
|
|
|
|
view.setDragMode(QGraphicsView.ScrollHandDrag)
|
|
|
|
image_label.setAlignment(Qt.AlignCenter)
|
|
|
|
view.setViewportUpdateMode(QGraphicsView.FullViewportUpdate)
|
|
|
|
image_label.setScaledContents(True) # 关键:允许图片缩放以填充标签
|
|
|
|
|
|
|
|
image_label.setMinimumSize(1, 1) # 设置最小尺寸
|
|
|
|
# 创建布局
|
|
|
|
image_label.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) # 设置大小策略为扩展
|
|
|
|
layout = QVBoxLayout()
|
|
|
|
image_label.setStyleSheet("""
|
|
|
|
layout.setContentsMargins(0, 0, 0, 0)
|
|
|
|
QLabel {
|
|
|
|
layout.addWidget(view)
|
|
|
|
border: none;
|
|
|
|
viewer.setLayout(layout)
|
|
|
|
margin: 0px;
|
|
|
|
|
|
|
|
padding: 0px;
|
|
|
|
|
|
|
|
background-color: #000000;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
""")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# 加载图片
|
|
|
|
# 加载图片
|
|
|
|
pixmap = QPixmap()
|
|
|
|
pixmap = QPixmap()
|
|
|
|
@ -2765,10 +2788,10 @@ class WordStyleMainWindow(QMainWindow):
|
|
|
|
self.status_bar.showMessage(f"加载图片失败: {filename}", 3000)
|
|
|
|
self.status_bar.showMessage(f"加载图片失败: {filename}", 3000)
|
|
|
|
return
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
layout.addWidget(image_label)
|
|
|
|
# 将图片添加到场景
|
|
|
|
viewer.setLayout(layout)
|
|
|
|
scene.addPixmap(pixmap)
|
|
|
|
|
|
|
|
|
|
|
|
# 计算位置和大小
|
|
|
|
# 设置视图大小和位置
|
|
|
|
if self:
|
|
|
|
if self:
|
|
|
|
parent_geometry = self.geometry()
|
|
|
|
parent_geometry = self.geometry()
|
|
|
|
screen_geometry = QApplication.primaryScreen().geometry()
|
|
|
|
screen_geometry = QApplication.primaryScreen().geometry()
|
|
|
|
@ -2793,42 +2816,24 @@ class WordStyleMainWindow(QMainWindow):
|
|
|
|
|
|
|
|
|
|
|
|
viewer.show()
|
|
|
|
viewer.show()
|
|
|
|
|
|
|
|
|
|
|
|
# 关键:强制图片立即填充整个标签区域
|
|
|
|
# 设置视图适应图片大小
|
|
|
|
def force_image_fill():
|
|
|
|
view.fitInView(scene.sceneRect(), Qt.KeepAspectRatio)
|
|
|
|
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
|
|
|
|
def wheelEvent(event):
|
|
|
|
QTimer.singleShot(50, force_image_fill) # 50毫秒后执行
|
|
|
|
factor = 1.2
|
|
|
|
QTimer.singleShot(200, force_image_fill) # 200毫秒后执行
|
|
|
|
if event.angleDelta().y() > 0:
|
|
|
|
QTimer.singleShot(1000, force_image_fill) # 1000毫秒后再执行一次
|
|
|
|
view.scale(factor, factor)
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
|
|
|
view.scale(1.0/factor, 1.0/factor)
|
|
|
|
|
|
|
|
|
|
|
|
# 连接窗口大小变化事件
|
|
|
|
view.wheelEvent = wheelEvent
|
|
|
|
viewer.resizeEvent = lambda event: force_image_fill()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# 添加点击关闭功能
|
|
|
|
# 添加双击重置视图功能
|
|
|
|
def close_viewer():
|
|
|
|
def mouseDoubleClickEvent(event):
|
|
|
|
viewer.close()
|
|
|
|
view.fitInView(scene.sceneRect(), Qt.KeepAspectRatio)
|
|
|
|
|
|
|
|
|
|
|
|
image_label.mousePressEvent = lambda event: close_viewer()
|
|
|
|
view.mouseDoubleClickEvent = mouseDoubleClickEvent
|
|
|
|
viewer.mousePressEvent = lambda event: close_viewer()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
except Exception as e:
|
|
|
|
except Exception as e:
|
|
|
|
self.status_bar.showMessage(f"创建图片查看器失败: {str(e)}", 3000)
|
|
|
|
self.status_bar.showMessage(f"创建图片查看器失败: {str(e)}", 3000)
|
|
|
|
@ -3152,7 +3157,6 @@ class WordStyleMainWindow(QMainWindow):
|
|
|
|
max-width: 100%;
|
|
|
|
max-width: 100%;
|
|
|
|
height: auto;
|
|
|
|
height: auto;
|
|
|
|
border-radius: 3px;
|
|
|
|
border-radius: 3px;
|
|
|
|
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
|
|
|
|
|
|
|
}}
|
|
|
|
}}
|
|
|
|
.image-caption {{
|
|
|
|
.image-caption {{
|
|
|
|
margin-top: 8px;
|
|
|
|
margin-top: 8px;
|
|
|
|
@ -3279,6 +3283,8 @@ class WordStyleMainWindow(QMainWindow):
|
|
|
|
|
|
|
|
|
|
|
|
if file_path:
|
|
|
|
if file_path:
|
|
|
|
try:
|
|
|
|
try:
|
|
|
|
|
|
|
|
import os
|
|
|
|
|
|
|
|
import tempfile
|
|
|
|
from docx import Document
|
|
|
|
from docx import Document
|
|
|
|
from docx.shared import Inches
|
|
|
|
from docx.shared import Inches
|
|
|
|
|
|
|
|
|
|
|
|
@ -3303,10 +3309,6 @@ class WordStyleMainWindow(QMainWindow):
|
|
|
|
break
|
|
|
|
break
|
|
|
|
|
|
|
|
|
|
|
|
if img_data:
|
|
|
|
if img_data:
|
|
|
|
# 创建临时图片文件
|
|
|
|
|
|
|
|
import tempfile
|
|
|
|
|
|
|
|
import os
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# 检测图片类型
|
|
|
|
# 检测图片类型
|
|
|
|
if img_name.lower().endswith('.png'):
|
|
|
|
if img_name.lower().endswith('.png'):
|
|
|
|
img_ext = '.png'
|
|
|
|
img_ext = '.png'
|
|
|
|
@ -3404,8 +3406,8 @@ class WordStyleMainWindow(QMainWindow):
|
|
|
|
|
|
|
|
|
|
|
|
# 为每张图片创建位置信息 - 修复位置计算,确保早期显示
|
|
|
|
# 为每张图片创建位置信息 - 修复位置计算,确保早期显示
|
|
|
|
content_length = len(self.imported_content)
|
|
|
|
content_length = len(self.imported_content)
|
|
|
|
if content_length == 0:
|
|
|
|
#if content_length == 0:
|
|
|
|
content_length = len(content) if 'content' in locals() else 1000 # 备用长度
|
|
|
|
#content_length = len(content) if 'content' in locals() else 1000 # 备用长度
|
|
|
|
|
|
|
|
|
|
|
|
# 修复图片位置计算,确保图片能在用户早期打字时显示
|
|
|
|
# 修复图片位置计算,确保图片能在用户早期打字时显示
|
|
|
|
if len(images) == 1:
|
|
|
|
if len(images) == 1:
|
|
|
|
@ -3496,7 +3498,7 @@ class WordStyleMainWindow(QMainWindow):
|
|
|
|
|
|
|
|
|
|
|
|
# 如果日历组件可见,调整其大小和位置以适应窗口底部
|
|
|
|
# 如果日历组件可见,调整其大小和位置以适应窗口底部
|
|
|
|
if hasattr(self, 'calendar_widget') and self.calendar_widget.isVisible():
|
|
|
|
if hasattr(self, 'calendar_widget') and self.calendar_widget.isVisible():
|
|
|
|
calendar_height = 250 # 减小高度使比例更美观
|
|
|
|
calendar_height = 350 # 增加高度以确保所有日期都能完整显示
|
|
|
|
self.calendar_widget.setGeometry(0, self.height() - calendar_height,
|
|
|
|
self.calendar_widget.setGeometry(0, self.height() - calendar_height,
|
|
|
|
self.width(), calendar_height)
|
|
|
|
self.width(), calendar_height)
|
|
|
|
|
|
|
|
|
|
|
|
@ -3507,7 +3509,7 @@ class WordStyleMainWindow(QMainWindow):
|
|
|
|
self.calendar_widget.hide()
|
|
|
|
self.calendar_widget.hide()
|
|
|
|
else:
|
|
|
|
else:
|
|
|
|
# 设置日历组件位置在窗口底部
|
|
|
|
# 设置日历组件位置在窗口底部
|
|
|
|
calendar_height = 250 # 减小高度使比例更美观
|
|
|
|
calendar_height = 350 # 增加高度以确保所有日期都能完整显示
|
|
|
|
|
|
|
|
|
|
|
|
# 将日历组件放置在窗口底部,占据整个宽度
|
|
|
|
# 将日历组件放置在窗口底部,占据整个宽度
|
|
|
|
self.calendar_widget.setGeometry(0, self.height() - calendar_height,
|
|
|
|
self.calendar_widget.setGeometry(0, self.height() - calendar_height,
|
|
|
|
@ -3515,6 +3517,95 @@ class WordStyleMainWindow(QMainWindow):
|
|
|
|
self.calendar_widget.show()
|
|
|
|
self.calendar_widget.show()
|
|
|
|
self.calendar_widget.raise_() # 确保日历组件在最上层显示
|
|
|
|
self.calendar_widget.raise_() # 确保日历组件在最上层显示
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def insert_weather_info(self):
|
|
|
|
|
|
|
|
"""在光标位置插入天气信息"""
|
|
|
|
|
|
|
|
# 检查是否处于打字模式
|
|
|
|
|
|
|
|
if self.view_mode != "typing":
|
|
|
|
|
|
|
|
self.status_bar.showMessage("请在打字模式下使用插入天气信息功能", 3000)
|
|
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# 检查是否已经定位了天气(即是否有有效的天气数据)
|
|
|
|
|
|
|
|
if not hasattr(self, 'current_weather_data') or not self.current_weather_data:
|
|
|
|
|
|
|
|
# 弹出对话框提示用户先定位天气
|
|
|
|
|
|
|
|
QMessageBox.information(self, "附加工具", "先定位天气")
|
|
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
|
|
|
# 直接使用已经获取到的天气数据
|
|
|
|
|
|
|
|
weather_data = self.current_weather_data
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# 格式化天气信息
|
|
|
|
|
|
|
|
if weather_data:
|
|
|
|
|
|
|
|
# 处理嵌套的天气数据结构
|
|
|
|
|
|
|
|
city = weather_data.get('city', '未知城市')
|
|
|
|
|
|
|
|
current_data = weather_data.get('current', {})
|
|
|
|
|
|
|
|
temp = current_data.get('temp', 'N/A')
|
|
|
|
|
|
|
|
desc = current_data.get('weather', 'N/A')
|
|
|
|
|
|
|
|
weather_info = f"天气: {desc}, 温度: {temp}°C, 城市: {city}"
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
|
|
|
weather_info = "天气信息获取失败"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# 在光标位置插入天气信息
|
|
|
|
|
|
|
|
cursor = self.text_edit.textCursor()
|
|
|
|
|
|
|
|
cursor.insertText(weather_info)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# 更新状态栏
|
|
|
|
|
|
|
|
self.status_bar.showMessage("已插入天气信息", 2000)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
except Exception as e:
|
|
|
|
|
|
|
|
QMessageBox.warning(self, "错误", f"插入天气信息失败: {str(e)}")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def insert_daily_quote(self):
|
|
|
|
|
|
|
|
"""在光标位置插入每日一句名言"""
|
|
|
|
|
|
|
|
# 检查是否处于打字模式
|
|
|
|
|
|
|
|
if self.view_mode != "typing":
|
|
|
|
|
|
|
|
self.status_bar.showMessage("请在打字模式下使用插入每日一句名言功能", 3000)
|
|
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
|
|
|
# 使用与Ribbon界面相同的API获取每日一言,确保内容一致
|
|
|
|
|
|
|
|
from ui.word_style_ui import daily_sentence_API
|
|
|
|
|
|
|
|
quote_api = daily_sentence_API("https://api.nxvav.cn/api/yiyan")
|
|
|
|
|
|
|
|
quote_data = quote_api.get_sentence('json')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# 处理获取到的数据
|
|
|
|
|
|
|
|
if quote_data and isinstance(quote_data, dict):
|
|
|
|
|
|
|
|
quote_text = quote_data.get('yiyan', '暂无每日一言')
|
|
|
|
|
|
|
|
quote_info = quote_text
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
|
|
|
quote_info = "每日一句名言获取失败"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# 在光标位置插入名言信息
|
|
|
|
|
|
|
|
cursor = self.text_edit.textCursor()
|
|
|
|
|
|
|
|
cursor.insertText(quote_info)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# 更新状态栏
|
|
|
|
|
|
|
|
self.status_bar.showMessage("已插入每日一句名言", 2000)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
except Exception as e:
|
|
|
|
|
|
|
|
QMessageBox.warning(self, "错误", f"插入每日一句名言失败: {str(e)}")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def insert_chinese_poetry(self):
|
|
|
|
|
|
|
|
"""在光标位置插入古诗词"""
|
|
|
|
|
|
|
|
# 检查是否处于打字模式
|
|
|
|
|
|
|
|
if self.view_mode != "typing":
|
|
|
|
|
|
|
|
self.status_bar.showMessage("请在打字模式下使用插入古诗词功能", 3000)
|
|
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
|
|
|
# 获取古诗词
|
|
|
|
|
|
|
|
poetry_data = self.ribbon.get_chinese_poetry()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# 在光标位置插入古诗词
|
|
|
|
|
|
|
|
cursor = self.text_edit.textCursor()
|
|
|
|
|
|
|
|
cursor.insertText(poetry_data)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# 更新状态栏
|
|
|
|
|
|
|
|
self.status_bar.showMessage("已插入古诗词", 2000)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
except Exception as e:
|
|
|
|
|
|
|
|
QMessageBox.warning(self, "错误", f"插入古诗词失败: {str(e)}")
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
if __name__ == "__main__":
|
|
|
|
app = QApplication(sys.argv)
|
|
|
|
app = QApplication(sys.argv)
|
|
|
|
|
|
|
|
|
|
|
|
|