Uploaded image for project: 'Qt for Python'
  1. Qt for Python
  2. PYSIDE-2968

styleHints().colorSchemeChanged signal doesn't work without the use of a lambda in a class

    XMLWordPrintable

Details

    • Bug
    • Resolution: Fixed
    • Not Evaluated
    • None
    • 6.8.0, 6.8.1, 6.8.0.2
    • PySide
    • None
    • Windows

    Description

      styleHints().colorSchemeChanged fails without a lambda being used, regardless if you use the Slot() decorator or not. There is no error, it's just a silent fail.

      A simple example with a nested function works without the lambda.

      def build_auto_theme_icon_buttons(
          widget,
          icon: str,
          object_name: str,
          width: int,
          height: int,
          text_included: bool = False,
          parent: QWidget | None = None,
      ) -> Any:
          """
          Builds icon buttons and returns them with light/dark mode icons.

          We need to ensure to include a '_dark.svg' version of each svg file.
          """
          # Create the button
          button = widget(parent=parent)
          button.setObjectName(object_name)
          svg_path = Path(RUNTIME_DIR) / "svg" / icon

          # Function to update the icon based on the color scheme
          def update_icon(color_scheme: Qt.ColorScheme):
              if color_scheme == Qt.ColorScheme.Dark:
                  dark_icon_path = svg_path.parent / (svg_path.stem + "_dark.svg")
                  button.setIcon(QIcon(str(dark_icon_path)))  # Set the dark mode icon
              else:
                  button.setIcon(QIcon(str(svg_path)))  # Set the light mode icon
              button.setIconSize(QSize(width, height))

          # Get the current app instance and connect to the color scheme change signal
          app = QApplication.instance()
          app.styleHints().colorSchemeChanged.connect(update_icon)  # Update on color scheme change

          # Set the icon based on the current color scheme
          update_icon(app.styleHints().colorScheme())  # Set the initial icon

          # Set other button properties
          button.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonIconOnly)
          if text_included:
              button.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonTextBesideIcon)
          button.setCursor(QCursor(Qt.CursorShape.PointingHandCursor))

          return button
      However, this same thing in a class fails.

      class IconButton:
          def _init_(
              self,
              widget: Any,
              icon: str,
              object_name: str,
              width: int,
              height: int,
              text_included: bool = False,
              parent: QWidget | None = None,
          ):
              """Initializes the IconButton object."""
              self.widget = widget
              self.icon = icon
              self.object_name = object_name
              self.width = width
              self.height = height
              self.text_included = text_included
              self.parent = parent

              self.button = self.widget(parent=self.parent)
              self.button.setObjectName(self.object_name)
              self.svg_path = Path(RUNTIME_DIR) / "svg" / self.icon

              # set up the button's icon and style
              self.setup_button()

              # connect to color scheme change signal
              self.app = QApplication.instance()
              self.app.styleHints().colorSchemeChanged.connect(lambda e: self.update_icon(e))  # pyright: ignore [reportAttributeAccessIssue, reportOptionalMemberAccess]
              # self.app.styleHints().colorSchemeChanged.connect(self.update_icon)  # pyright: ignore [reportAttributeAccessIssue, reportOptionalMemberAccess]

              # set the initial icon based on the current color scheme
              self.update_icon(self.app.styleHints().colorScheme())  # pyright: ignore [reportAttributeAccessIssue, reportOptionalMemberAccess]

          def setup_button(self):
              """Sets up the button's initial properties."""
              self.button.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonIconOnly)
              if self.text_included:
                  self.button.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonTextBesideIcon)
              self.button.setCursor(QCursor(Qt.CursorShape.PointingHandCursor))

          @Slot(Qt.ColorScheme)
          def update_icon(self, color_scheme: Qt.ColorScheme):
              """Updates the button icon based on the color scheme."""
              if color_scheme == Qt.ColorScheme.Dark:
                  dark_icon_path = self.svg_path.parent / (self.svg_path.stem + "_dark.svg")
                  # set the dark mode icon
                  self.button.setIcon(QIcon(str(dark_icon_path)))
              else:
                  # set the light mode icon
                  self.button.setIcon(QIcon(str(self.svg_path)))
              self.button.setIconSize(QSize(self.width, self.height))

          def get_button(self):
              """Returns the created button."""
              return self.button

      Attachments

        No reviews matched the request. Check your Options in the drop-down menu of this sections header.

        Activity

          People

            crmaurei Cristian Maureira-Fredes
            jlw_4049 Jessie Wilson
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Gerrit Reviews

                There are no open Gerrit changes