Source code for ansys.aedt.toolkits.common.ui.utils.widgets.py_icon_button.py_icon_button

# -*- coding: utf-8 -*-
#
# Copyright (C) 2023 - 2025 ANSYS, Inc. and/or its affiliates.
# SPDX-License-Identifier: MIT
#
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.

from PySide6.QtCore import QEvent
from PySide6.QtCore import QRect
from PySide6.QtCore import Qt
from PySide6.QtGui import QBrush
from PySide6.QtGui import QColor
from PySide6.QtGui import QPainter
from PySide6.QtGui import QPixmap
from PySide6.QtWidgets import QGraphicsDropShadowEffect
from PySide6.QtWidgets import QLabel
from PySide6.QtWidgets import QPushButton


[docs] class PyIconButton(QPushButton): """ Icon button widget that can be used as a colored icon. The icon and color can be customized during initialization. Parameters ---------- icon_path : str Path to the icon image file. tooltip_text : str, optional Text for tooltip. btn_id : str, optional Identifier for the button. width : int, optional Width of the button. height : int, optional Height of the button. radius : int, optional Radius for rounded corners. bg_color : str, optional Background color in hex color code. bg_color_hover : str, optional Background color when hovered in hex color code. bg_color_pressed : str, optional Background color when being pressed in hex color code. icon_color : str, optional Icon color in hex color code. icon_color_hover : str, optional Icon color when hovered in hex color code. icon_color_pressed : str, optional Icon color when being pressed in hex color code. icon_color_active : str, optional Active icon color in hex color code. dark_one : str, optional Color for dark theme in hex color code. text_foreground : str, optional Text color in hex color code. context_color : str, optional Context color in hex color code. top_margin : int, optional Top margin for tooltip. is_active : bool, optional Whether the button is currently active. The rest of the parameters customize the look and emit signals for different user interactions. Examples -------- >>> import sys >>> from PySide6.QtWidgets import QApplication, QVBoxLayout, QPushButton >>> from ansys.aedt.toolkits.common.ui.utils.widgets import * >>> class Example(QWidget): >>> def __init__(self): >>> super().__init__() >>> layout = QVBoxLayout(self) >>> layout.addWidget(QPushButton("Button 1")) >>> layout.addWidget(PyIconButton('icon_signal.svg', "#FF0000", tooltip_text="Example") >>> ) >>> layout.addWidget(QPushButton("Button 2")) >>> if __name__ == "__main__": >>> app = QApplication([]) >>> window = Example() >>> window.show() >>> app.exec() """ def __init__( self, icon_path=None, tooltip_text="", btn_id=None, width=30, height=30, radius=8, bg_color="#343b48", bg_color_hover="#3c4454", bg_color_pressed="#2c313c", icon_color="#c3ccdf", icon_color_hover="#dce1ec", icon_color_pressed="#edf0f5", icon_color_active="#f5f6f9", dark_one="#1b1e23", text_foreground="#8a95aa", context_color="#568af2", top_margin=40, is_active=False, ): super().__init__() self.setFixedSize(width, height) self.setCursor(Qt.PointingHandCursor) self.setObjectName(btn_id) self._bg_color = bg_color self._bg_color_hover = bg_color_hover self._bg_color_pressed = bg_color_pressed self._icon_color = icon_color self._icon_color_hover = icon_color_hover self._icon_color_pressed = icon_color_pressed self._icon_color_active = icon_color_active self._context_color = context_color self._top_margin = top_margin self._is_active = is_active # Set Parameters self._set_bg_color = bg_color self._set_icon_path = icon_path self._set_icon_color = icon_color self._set_border_radius = radius # TOOLTIP if tooltip_text: self._tooltip_text = tooltip_text self._tooltip = Tooltip(tooltip_text, dark_one, text_foreground) self._tooltip.hide()
[docs] def set_active(self, is_active): """ Set the active state of the button. Parameters ---------- is_active : bool Whether the button is active or not. """ self._is_active = is_active self.repaint()
[docs] def is_active(self): """ Check if the button is in an active state. Returns ------- bool True if the button is active, False otherwise. """ return self._is_active
[docs] def paintEvent(self, event): """ Paint the button. Parameters ---------- event : QEvent Paint event. """ # PAINTER paint = QPainter() paint.begin(self) paint.setRenderHint(QPainter.RenderHint.Antialiasing) if self._is_active: # BRUSH brush = QBrush(QColor(self._context_color)) else: # BRUSH brush = QBrush(QColor(self._set_bg_color)) # CREATE RECTANGLE rect = QRect(0, 0, self.width(), self.height()) paint.setPen(Qt.NoPen) paint.setBrush(brush) paint.drawRoundedRect(rect, self._set_border_radius, self._set_border_radius) # DRAW ICONS self.icon_paint(paint, self._set_icon_path, rect) # END PAINTER paint.end()
[docs] def change_style(self, event): """ Change the style of the button based on the given event. Parameters ---------- event : QEvent Event triggering the style change. """ if event == QEvent.Enter: self._set_bg_color = self._bg_color_hover self._set_icon_color = self._icon_color_hover self.repaint() elif event == QEvent.Leave: self._set_bg_color = self._bg_color self._set_icon_color = self._icon_color self.repaint() elif event == QEvent.MouseButtonPress: self._set_bg_color = self._bg_color_pressed self._set_icon_color = self._icon_color_pressed self.repaint() elif event == QEvent.MouseButtonRelease: self._set_bg_color = self._bg_color_hover self._set_icon_color = self._icon_color_hover self.repaint()
[docs] def enterEvent(self, event): """ Handle the enter event. Parameters ---------- event : QEvent Enter event. """ self.change_style(QEvent.Enter)
[docs] def leaveEvent(self, event): """ Handle the leave event. Parameters ---------- event : QEvent Leave event. """ self.change_style(QEvent.Leave)
[docs] def mousePressEvent(self, event): """ Handle the mouse press event. Parameters ---------- event : QEvent Mouse press event. """ if event.button() == Qt.LeftButton: self.change_style(QEvent.MouseButtonPress) self.setFocus() return self.clicked.emit()
[docs] def mouseReleaseEvent(self, event): """ Handle the mouse release event. Parameters ---------- event : QEvent Mouse release event. """ if event.button() == Qt.LeftButton: self.change_style(QEvent.MouseButtonRelease) return self.released.emit()
[docs] def icon_paint(self, qp, image, rect): """ Paint the icon on the button. Parameters ---------- qp : QPainter QPainter object. image : str Path to the icon image file. rect : QRect Rectangle for the icon placement. """ icon = QPixmap(image) painter = QPainter(icon) painter.setCompositionMode(QPainter.CompositionMode_SourceIn) if self._is_active: painter.fillRect(icon.rect(), self._icon_color_active) else: painter.fillRect(icon.rect(), self._set_icon_color) qp.drawPixmap((rect.width() - icon.width()) / 2, (rect.height() - icon.height()) / 2, icon) painter.end()
[docs] def set_icon(self, icon_path): """ Set the icon for the button. Parameters ---------- icon_path : str Path to the icon image file. """ self._set_icon_path = icon_path self.repaint()
class Tooltip(QLabel): """ Tooltip class to display tooltip for the PyIconButton. Parameters ---------- tooltip : str Text to be displayed in the tooltip. dark_one : str Dark color for theming. text_foreground : str Text foreground color. """ style_tooltip = """ QLabel {{ background-color: {_dark_one}; color: {_text_foreground}; padding-left: 10px; padding-right: 10px; border-radius: 17px; border: 0px solid transparent; font: 800 9pt "Segoe UI"; }} """ def __init__(self, tooltip, dark_one, text_foreground): QLabel.__init__(self) style = self.style_tooltip.format(_dark_one=dark_one, _text_foreground=text_foreground) self.setObjectName("label_tooltip") self.setStyleSheet(style) self.setMinimumHeight(34) self.setText(tooltip) self.adjustSize() self.shadow = QGraphicsDropShadowEffect(self) self.shadow.setBlurRadius(30) self.shadow.setXOffset(0) self.shadow.setYOffset(0) self.shadow.setColor(QColor(0, 0, 0, 80)) self.setGraphicsEffect(self.shadow)