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