add notification

This commit is contained in:
unknown 2025-09-29 01:10:14 +03:00
parent e8427ceb5d
commit d72239b3ab

View File

@ -64,6 +64,7 @@ class YobbleHomeView(QWidget):
# --- Боковое меню и оверлей --- # --- Боковое меню и оверлей ---
self.setup_side_menu() self.setup_side_menu()
self._setup_notification_widget()
self.update_styles() self.update_styles()
theme_manager.theme_changed.connect(self.update_styles) theme_manager.theme_changed.connect(self.update_styles)
@ -107,6 +108,81 @@ class YobbleHomeView(QWidget):
if self.is_menu_closing: if self.is_menu_closing:
self.overlay.hide() self.overlay.hide()
def _setup_notification_widget(self):
"""Настраивает виджет для всплывающих уведомлений."""
self.notification_widget = QFrame(self)
self.notification_widget.setObjectName("NotificationWidget")
# Тень
shadow = QGraphicsDropShadowEffect(self)
shadow.setBlurRadius(20)
shadow.setColor(QColor(0, 0, 0, 80))
shadow.setOffset(0, 3)
self.notification_widget.setGraphicsEffect(shadow)
self.notification_widget.hide()
layout = QHBoxLayout(self.notification_widget)
layout.setContentsMargins(15, 10, 15, 10)
self.notification_label = QLabel()
self.notification_label.setObjectName("NotificationLabel")
layout.addWidget(self.notification_label)
# Эффект прозрачности для анимации
self.notification_opacity_effect = QGraphicsOpacityEffect(self.notification_widget)
self.notification_widget.setGraphicsEffect(self.notification_opacity_effect)
self.notification_animation = QPropertyAnimation(self.notification_opacity_effect, b"opacity")
self.notification_animation.setDuration(300) # мс на появление/исчезание
self.notification_timer = QTimer(self)
self.notification_timer.setSingleShot(True)
self.notification_timer.timeout.connect(self.hide_notification)
def show_notification(self, message, is_error=True, duration=3000):
"""Показывает всплывающее уведомление."""
self.notification_label.setText(message)
self.notification_widget.setProperty("is_error", is_error)
self.notification_widget.style().unpolish(self.notification_widget)
self.notification_widget.style().polish(self.notification_widget)
# Позиционирование
self.notification_widget.adjustSize()
x = (self.width() - self.notification_widget.width()) / 2
y = 30 # Отступ сверху
self.notification_widget.move(int(x), y)
self.notification_widget.show()
self.notification_widget.raise_() # Поднять поверх всех
# Анимация появления
self.notification_animation.stop()
self.notification_animation.setStartValue(0.0)
self.notification_animation.setEndValue(1.0)
self.notification_animation.start()
# Таймер на скрытие
self.notification_timer.start(duration)
def hide_notification(self):
"""Плавно скрывает уведомление."""
self.notification_animation.stop()
self.notification_animation.setStartValue(self.notification_opacity_effect.opacity())
self.notification_animation.setEndValue(0.0)
self.notification_animation.start()
# Прячем виджет только после завершения анимации
def on_finished():
self.notification_widget.hide()
# Отключаем, чтобы не вызывался многократно
try:
self.notification_animation.finished.disconnect(on_finished)
except (TypeError, RuntimeError):
pass # Уже отключен
self.notification_animation.finished.connect(on_finished)
def toggle_side_menu(self): def toggle_side_menu(self):
"""Показывает или скрывает боковое меню с анимацией.""" """Показывает или скрывает боковое меню с анимацией."""
# Останавливаем текущие анимации, чтобы избежать конфликтов # Останавливаем текущие анимации, чтобы избежать конфликтов
@ -143,6 +219,11 @@ class YobbleHomeView(QWidget):
self.side_menu.move(-self.side_menu.width(), 0) self.side_menu.move(-self.side_menu.width(), 0)
self.side_menu.setFixedHeight(self.height()) self.side_menu.setFixedHeight(self.height())
if hasattr(self, 'notification_widget') and self.notification_widget.isVisible():
self.notification_widget.adjustSize()
x = (self.width() - self.notification_widget.width()) / 2
self.notification_widget.move(int(x), 30)
def update_styles(self): def update_styles(self):
"""Обновляет стили компонента при смене темы.""" """Обновляет стили компонента при смене темы."""
self.setStyleSheet(self.get_stylesheet()) self.setStyleSheet(self.get_stylesheet())
@ -182,6 +263,16 @@ class YobbleHomeView(QWidget):
top_bar_layout.addWidget(self.notification_button) top_bar_layout.addWidget(self.notification_button)
self.notification_button.clicked.connect(self.handle_notification_click) self.notification_button.clicked.connect(self.handle_notification_click)
# --- Временные кнопки для теста ---
# self.test_ok_button = QPushButton("Test OK")
# self.test_ok_button.clicked.connect(lambda: self.show_notification("Операция прошла успешно", is_error=False))
# top_bar_layout.addWidget(self.test_ok_button)
# self.test_err_button = QPushButton("Test Error")
# self.test_err_button.clicked.connect(lambda: self.show_notification("Произошла ошибка при обновлении", is_error=True))
# top_bar_layout.addWidget(self.test_err_button)
# --- Конец временного кода ---
return top_bar_widget return top_bar_widget
def create_bottom_bar(self): def create_bottom_bar(self):
@ -377,13 +468,8 @@ class YobbleHomeView(QWidget):
self.title_label.setText(titles[index]) self.title_label.setText(titles[index])
def show_error_message(self, message): def show_error_message(self, message):
"""Показывает диалоговое окно с сообщением об ошибке.""" """Показывает всплывающее уведомление об ошибке."""
show_themed_messagebox( self.show_notification(message, is_error=True)
self,
QMessageBox.Warning,
localizer.translate("Ошибка доступа"),
message
)
def update_tab_selection(self, selected_index): def update_tab_selection(self, selected_index):
if not hasattr(self, 'bottom_bar'): if not hasattr(self, 'bottom_bar'):
@ -470,6 +556,27 @@ class YobbleHomeView(QWidget):
background-color: {overlay_color}; background-color: {overlay_color};
}} }}
/* --- Уведомления --- */
#NotificationWidget {{
border-radius: 12px;
background-color: {"#333" if is_dark else "#FFF"};
border: 1px solid {"#444" if is_dark else "#E0E0E0"};
}}
#NotificationWidget[is_error="true"] {{
background-color: {"#D32F2F" if is_dark else "#f44336"};
border: 1px solid {"#C62828" if is_dark else "#E53935"};
}}
#NotificationWidget[is_error="false"] {{
background-color: {"#388E3C" if is_dark else "#4CAF50"};
border: 1px solid {"#2E7D32" if is_dark else "#43A047"};
}}
#NotificationLabel {{
color: white;
font-size: 14px;
background: transparent;
}}
/* --- Конец Уведомлений --- */
/* Глобально для кнопок */ /* Глобально для кнопок */
QPushButton {{ QPushButton {{
background: transparent; background: transparent;