add notification
This commit is contained in:
parent
e8427ceb5d
commit
d72239b3ab
@ -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;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user