#!/usr/bin/env python # -*- coding: utf-8 -*- """ LLMClipboard 通知样式测试脚本 用于测试各种通知样式、颜色和交互 """ import sys import os import logging import traceback # 添加项目根目录到路径 sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) # 配置日志 logging.basicConfig( level=logging.DEBUG, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', handlers=[ logging.StreamHandler(), logging.FileHandler('notification_style_test.log', encoding='utf-8') ] ) logger = logging.getLogger('notification_style_test') try: from PyQt6.QtWidgets import ( QApplication, QMainWindow, QPushButton, QVBoxLayout, QWidget, QLabel, QHBoxLayout, QComboBox, QLineEdit, QTextEdit, QGroupBox, QSlider, QCheckBox, QColorDialog, QDialog ) from PyQt6.QtCore import Qt, QTimer from PyQt6.QtGui import QColor # 导入LLMClipboard模块 from llmclipboard.gui import NotificationDialog # 尝试导入apply_stylesheet函数 try: from qt_material import apply_stylesheet except ImportError: # 如果qt_material未安装,创建一个空的apply_stylesheet函数 def apply_stylesheet(widget, theme=None): logger.warning(f"qt_material未安装,无法应用主题: {theme}") except Exception as e: logger.error(f"导入模块时出错: {str(e)}") traceback.print_exc() sys.exit(1) # 创建一个简化版的通知对话框,直接使用NotificationDialog类 class SimpleNotificationTester(QMainWindow): def __init__(self): super().__init__() self.setWindowTitle("LLMClipboard 通知样式测试") self.resize(800, 600) # 初始化颜色 self.bg_color = QColor("#f0f0f0") self.title_color = QColor("#333333") self.content_color = QColor("#555555") # 创建通知队列 self.notification_queue = [] self.is_showing_notification = False # 创建UI self.setup_ui() def setup_ui(self): """设置UI""" central_widget = QWidget() self.setCentralWidget(central_widget) main_layout = QVBoxLayout(central_widget) # 通知类型选择 type_group = QGroupBox("通知类型") type_layout = QHBoxLayout() type_group.setLayout(type_layout) type_label = QLabel("类型:") self.type_combo = QComboBox() self.type_combo.addItems(["info", "success", "warning", "error"]) type_layout.addWidget(type_label) type_layout.addWidget(self.type_combo) # 通知内容 content_group = QGroupBox("通知内容") content_layout = QVBoxLayout() content_group.setLayout(content_layout) title_layout = QHBoxLayout() title_label = QLabel("标题:") self.title_edit = QLineEdit("测试通知") title_layout.addWidget(title_label) title_layout.addWidget(self.title_edit) message_layout = QVBoxLayout() message_label = QLabel("消息内容:") self.message_edit = QTextEdit("这是一条测试通知消息,用于测试LLMClipboard的通知系统。") self.message_edit.setMaximumHeight(100) message_layout.addWidget(message_label) message_layout.addWidget(self.message_edit) buttons_layout = QHBoxLayout() buttons_label = QLabel("按钮(逗号分隔):") self.buttons_edit = QLineEdit("确定,取消") buttons_layout.addWidget(buttons_label) buttons_layout.addWidget(self.buttons_edit) content_layout.addLayout(title_layout) content_layout.addLayout(message_layout) content_layout.addLayout(buttons_layout) # 通知设置 settings_group = QGroupBox("通知设置") settings_layout = QVBoxLayout() settings_group.setLayout(settings_layout) duration_layout = QHBoxLayout() duration_label = QLabel("持续时间(秒):") self.duration_slider = QSlider(Qt.Orientation.Horizontal) self.duration_slider.setMinimum(1) self.duration_slider.setMaximum(10) self.duration_slider.setValue(5) self.duration_value_label = QLabel("5") self.duration_slider.valueChanged.connect(lambda v: self.duration_value_label.setText(str(v))) duration_layout.addWidget(duration_label) duration_layout.addWidget(self.duration_slider) duration_layout.addWidget(self.duration_value_label) auto_close_layout = QHBoxLayout() self.auto_close_check = QCheckBox("自动关闭") self.auto_close_check.setChecked(True) auto_close_layout.addWidget(self.auto_close_check) settings_layout.addLayout(duration_layout) settings_layout.addLayout(auto_close_layout) # 样式设置 style_group = QGroupBox("样式设置") style_layout = QVBoxLayout() style_group.setLayout(style_layout) bg_color_layout = QHBoxLayout() bg_color_label = QLabel("背景颜色:") self.bg_color_button = QPushButton() self.bg_color_button.setStyleSheet(f"background-color: {self.bg_color.name()};") self.bg_color_button.setFixedSize(30, 20) self.bg_color_button.clicked.connect(lambda: self.choose_color("bg")) bg_color_layout.addWidget(bg_color_label) bg_color_layout.addWidget(self.bg_color_button) bg_color_layout.addStretch() title_color_layout = QHBoxLayout() title_color_label = QLabel("标题颜色:") self.title_color_button = QPushButton() self.title_color_button.setStyleSheet(f"background-color: {self.title_color.name()};") self.title_color_button.setFixedSize(30, 20) self.title_color_button.clicked.connect(lambda: self.choose_color("title")) title_color_layout.addWidget(title_color_label) title_color_layout.addWidget(self.title_color_button) title_color_layout.addStretch() content_color_layout = QHBoxLayout() content_color_label = QLabel("内容颜色:") self.content_color_button = QPushButton() self.content_color_button.setStyleSheet(f"background-color: {self.content_color.name()};") self.content_color_button.setFixedSize(30, 20) self.content_color_button.clicked.connect(lambda: self.choose_color("content")) content_color_layout.addWidget(content_color_label) content_color_layout.addWidget(self.content_color_button) content_color_layout.addStretch() style_layout.addLayout(bg_color_layout) style_layout.addLayout(title_color_layout) style_layout.addLayout(content_color_layout) # 测试按钮 buttons_layout = QHBoxLayout() test_button = QPushButton("测试通知") test_button.clicked.connect(self.test_notification) queue_button = QPushButton("测试通知队列") queue_button.clicked.connect(self.test_notification_queue) dialog_button = QPushButton("测试直接对话框") dialog_button.clicked.connect(self.test_direct_dialog) buttons_layout.addWidget(test_button) buttons_layout.addWidget(queue_button) buttons_layout.addWidget(dialog_button) # 状态标签 self.status_label = QLabel("就绪") self.status_label.setStyleSheet("color: blue;") # 添加所有组件到主布局 main_layout.addWidget(type_group) main_layout.addWidget(content_group) main_layout.addWidget(settings_group) main_layout.addWidget(style_group) main_layout.addLayout(buttons_layout) main_layout.addWidget(self.status_label) def choose_color(self, target): """选择颜色""" try: if target == "bg": color = QColorDialog.getColor(self.bg_color, self) if color.isValid(): self.bg_color = color self.bg_color_button.setStyleSheet(f"background-color: {color.name()};") elif target == "title": color = QColorDialog.getColor(self.title_color, self) if color.isValid(): self.title_color = color self.title_color_button.setStyleSheet(f"background-color: {color.name()};") elif target == "content": color = QColorDialog.getColor(self.content_color, self) if color.isValid(): self.content_color = color self.content_color_button.setStyleSheet(f"background-color: {color.name()};") except Exception as e: logger.error(f"选择颜色时出错: {str(e)}") def update_status(self, message): """更新状态标签""" try: self.status_label.setText(message) logger.info(message) # 5秒后重置状态 QTimer.singleShot(5000, lambda: self.status_label.setText("就绪")) except Exception as e: logger.error(f"更新状态标签时出错: {str(e)}") def get_notification_params(self): """获取通知参数""" try: notification_type = self.type_combo.currentText() title = self.title_edit.text() message = self.message_edit.toPlainText() buttons = [btn.strip() for btn in self.buttons_edit.text().split(",") if btn.strip()] duration = self.duration_slider.value() * 1000 # 转换为毫秒 auto_close = self.auto_close_check.isChecked() return { "type": notification_type, "title": title, "message": message, "buttons": buttons, "duration": duration, "auto_close": auto_close } except Exception as e: logger.error(f"获取通知参数时出错: {str(e)}") return None def show_notification(self, title, message, notification_type="info", buttons=None, file_path=None, duration=0): """显示通知""" try: # 将通知添加到队列 self.notification_queue.append({ "title": title, "message": message, "type": notification_type, "buttons": buttons, "file_path": file_path, "duration": duration }) # 如果当前没有显示通知,则开始处理队列 if not self.is_showing_notification: self._process_notification_queue() except Exception as e: logger.error(f"添加通知到队列时出错: {str(e)}") def _process_notification_queue(self): """处理通知队列""" try: if not self.notification_queue: self.is_showing_notification = False return self.is_showing_notification = True notification = self.notification_queue.pop(0) # 创建通知对话框 dialog = NotificationDialog( self, notification["title"], notification["message"], notification["type"], notification["buttons"], notification["file_path"] ) # 应用自定义样式 style = f""" QDialog {{ background-color: {self.bg_color.name()}; border: 1px solid #cccccc; border-radius: 5px; }} QLabel#title_label {{ color: {self.title_color.name()}; font-size: 14px; font-weight: bold; }} QLabel#message_label {{ color: {self.content_color.name()}; }} """ dialog.setStyleSheet(style) # 显示对话框 dialog.show() # 如果需要自动关闭 if notification["duration"] > 0: QTimer.singleShot(notification["duration"], dialog.close) # 当对话框关闭时,处理下一个通知 dialog.finished.connect(self._process_notification_queue) except Exception as e: logger.error(f"处理通知队列时出错: {str(e)}") self.is_showing_notification = False def test_notification(self): """测试通知""" try: params = self.get_notification_params() if not params: self.update_status("获取通知参数失败") return self.update_status(f"正在测试通知: {params['title']}") self.show_notification( params["title"], params["message"], params["type"], params["buttons"] if params["buttons"] else None, None, # 文件路径 params["duration"] if params["auto_close"] else 0 ) except Exception as e: logger.error(f"测试通知时出错: {str(e)}") self.update_status(f"显示通知失败: {e}") def test_notification_queue(self): """测试通知队列""" try: params = self.get_notification_params() if not params: self.update_status("获取通知参数失败") return self.update_status("正在测试通知队列...") # 发送多个通知 for i in range(3): try: self.show_notification( f"{params['title']} {i+1}", f"{params['message']}\n这是第 {i+1} 个队列通知", params["type"], params["buttons"] if params["buttons"] else None, None, # 文件路径 params["duration"] if params["auto_close"] else 0 ) except Exception as e: logger.error(f"显示通知队列失败: {e}") self.update_status(f"显示通知队列失败: {e}") except Exception as e: logger.error(f"测试通知队列时出错: {str(e)}") def test_direct_dialog(self): """测试直接创建通知对话框""" try: params = self.get_notification_params() if not params: self.update_status("获取通知参数失败") return self.update_status("正在测试直接创建通知对话框...") # 创建自定义样式 style = f""" QDialog {{ background-color: {self.bg_color.name()}; border: 1px solid #cccccc; border-radius: 5px; }} QLabel#title_label {{ color: {self.title_color.name()}; font-size: 14px; font-weight: bold; }} QLabel#message_label {{ color: {self.content_color.name()}; }} """ # 创建通知对话框 dialog = NotificationDialog( self, params["title"], params["message"], params["type"], params["buttons"] if params["buttons"] else None, None # 文件路径 ) # 应用自定义样式 dialog.setStyleSheet(style) # 显示对话框 dialog.show() # 如果需要自动关闭 if params["auto_close"]: QTimer.singleShot(params["duration"], dialog.close) except Exception as e: logger.error(f"测试直接创建通知对话框时出错: {str(e)}") self.update_status(f"创建通知对话框失败: {e}") def main(): try: app = QApplication(sys.argv) window = SimpleNotificationTester() window.show() sys.exit(app.exec()) except Exception as e: logger.error(f"主函数执行时出错: {str(e)}") traceback.print_exc() sys.exit(1) if __name__ == "__main__": main()