Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Widget weird hover behavior

Widget weird hover behavior

Scheduled Pinned Locked Moved Unsolved General and Desktop
3 Posts 2 Posters 390 Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • D Offline
    D Offline
    Dimas Atmaja
    wrote on 25 Jun 2023, 01:29 last edited by
    #1

    So I am trying to make a custom widget consisting of a label and a button. The button will be hidden by default and only showed when the user hovers over the widget. I also connect the button to a function for deleting the custom widget.

    The problem arise when I add my custom widget to a container with QVBoxLayout applied. When I click the button, the custom widget will be deleted and the item inside the layout will be adjusted. Now the cursor is positioned over another widget.

    The issue is the state of this another widget is not updated. The button is not showed, until i move the cursor.

    At first i though it is because of my implementation using the enterEvent and leaveEvent, but it looks it have things to do with the qt itself, since the background-color style that I apply to the widget also not updated

    Issue
    Peek 2023-06-25 08-25.gif

    Code

    from PySide6.QtWidgets import *
    from PySide6.QtCore import *
    from PySide6.QtGui import *
    import sys
    
    class Item(QWidget):
        def __init__(self, text: str):
            super(Item, self).__init__()
    
            # Widget configuration
            self.setAttribute(Qt.WidgetAttribute.WA_StyledBackground, True)
            self.setObjectName("Item")
            self.setStyleSheet("""
                #Item:hover { background: #bbb }
                #Item QPushButton:hover { background: red }
            """)
    
            # Layout
            self.setLayout(QHBoxLayout())
    
            # Button
            button_size_policy = QSizePolicy()
            button_size_policy.setRetainSizeWhenHidden(True)
            self.button = QPushButton("X")
            self.button.setFixedSize(28, 28)
            self.button.setSizePolicy(button_size_policy)
            self.button.clicked.connect(lambda: self.setParent(None))
            self.layout().addWidget(self.button)
            self.button.hide()
    
            # Label
            label = QLabel(f"Item {text}")
            self.layout().addWidget(label)
        
        def enterEvent(self, event: QEnterEvent):
            self.button.show()
        
        def leaveEvent(self, event: QEvent):
            self.button.hide()
    
    class MainWindow(QMainWindow):
        def __init__(self):
            super(MainWindow, self).__init__()
    
            # Container
            container = QFrame()
            container.setLayout(QVBoxLayout())
            container.layout().setAlignment(Qt.AlignmentFlag.AlignTop)
    
            # Populate container
            for i in range(4):
                item = Item(str(i))
                container.layout().addWidget(item)
    
            # Attach container
            self.setCentralWidget(container)
    
    if __name__ == "__main__":
        app = QApplication(sys.argv)
        window = MainWindow()
        window.show()
        sys.exit(app.exec())
    
    P 1 Reply Last reply 25 Jun 2023, 03:18
    0
    • D Dimas Atmaja
      25 Jun 2023, 01:29

      So I am trying to make a custom widget consisting of a label and a button. The button will be hidden by default and only showed when the user hovers over the widget. I also connect the button to a function for deleting the custom widget.

      The problem arise when I add my custom widget to a container with QVBoxLayout applied. When I click the button, the custom widget will be deleted and the item inside the layout will be adjusted. Now the cursor is positioned over another widget.

      The issue is the state of this another widget is not updated. The button is not showed, until i move the cursor.

      At first i though it is because of my implementation using the enterEvent and leaveEvent, but it looks it have things to do with the qt itself, since the background-color style that I apply to the widget also not updated

      Issue
      Peek 2023-06-25 08-25.gif

      Code

      from PySide6.QtWidgets import *
      from PySide6.QtCore import *
      from PySide6.QtGui import *
      import sys
      
      class Item(QWidget):
          def __init__(self, text: str):
              super(Item, self).__init__()
      
              # Widget configuration
              self.setAttribute(Qt.WidgetAttribute.WA_StyledBackground, True)
              self.setObjectName("Item")
              self.setStyleSheet("""
                  #Item:hover { background: #bbb }
                  #Item QPushButton:hover { background: red }
              """)
      
              # Layout
              self.setLayout(QHBoxLayout())
      
              # Button
              button_size_policy = QSizePolicy()
              button_size_policy.setRetainSizeWhenHidden(True)
              self.button = QPushButton("X")
              self.button.setFixedSize(28, 28)
              self.button.setSizePolicy(button_size_policy)
              self.button.clicked.connect(lambda: self.setParent(None))
              self.layout().addWidget(self.button)
              self.button.hide()
      
              # Label
              label = QLabel(f"Item {text}")
              self.layout().addWidget(label)
          
          def enterEvent(self, event: QEnterEvent):
              self.button.show()
          
          def leaveEvent(self, event: QEvent):
              self.button.hide()
      
      class MainWindow(QMainWindow):
          def __init__(self):
              super(MainWindow, self).__init__()
      
              # Container
              container = QFrame()
              container.setLayout(QVBoxLayout())
              container.layout().setAlignment(Qt.AlignmentFlag.AlignTop)
      
              # Populate container
              for i in range(4):
                  item = Item(str(i))
                  container.layout().addWidget(item)
      
              # Attach container
              self.setCentralWidget(container)
      
      if __name__ == "__main__":
          app = QApplication(sys.argv)
          window = MainWindow()
          window.show()
          sys.exit(app.exec())
      
      P Offline
      P Offline
      Pl45m4
      wrote on 25 Jun 2023, 03:18 last edited by
      #2

      @Dimas-Atmaja said in Widget weird hover behavior:

      def enterEvent(self, event: QEnterEvent):
          self.button.show()
      
      def leaveEvent(self, event: QEvent):
          self.button.hide()
      

      Since the mouse does not actively enter the widget, I think it's not weird, that the event is not received.

      You could check/update it yourself as soon as one widget is removed

      Mouse events occur when a mouse cursor is moved into, out of, or within a widget, and if the widget has the Qt::WA_Hover attribute.

      (From: https://doc.qt.io/qt-6/qhoverevent.html#details)


      If debugging is the process of removing software bugs, then programming must be the process of putting them in.

      ~E. W. Dijkstra

      D 1 Reply Last reply 25 Jun 2023, 10:58
      0
      • P Pl45m4
        25 Jun 2023, 03:18

        @Dimas-Atmaja said in Widget weird hover behavior:

        def enterEvent(self, event: QEnterEvent):
            self.button.show()
        
        def leaveEvent(self, event: QEvent):
            self.button.hide()
        

        Since the mouse does not actively enter the widget, I think it's not weird, that the event is not received.

        You could check/update it yourself as soon as one widget is removed

        Mouse events occur when a mouse cursor is moved into, out of, or within a widget, and if the widget has the Qt::WA_Hover attribute.

        (From: https://doc.qt.io/qt-6/qhoverevent.html#details)

        D Offline
        D Offline
        Dimas Atmaja
        wrote on 25 Jun 2023, 10:58 last edited by Dimas Atmaja
        #3

        @Pl45m4 Well, I can certainly fix the show and hide issue by listening to moveEvent and updating the widget manually. But how to fix the stylesheet one? Let's say I have a stylesheet like this:

         #CustomWidget:hover {
            background: red;
         }
        

        As you can see in the gif, the hover style is not applied until I move the cursor. Is there a way to tell the widget to apply this hover style? I am doing self.update() but it's doesn't work.

        I am aware that I can do something like this, but I think it is kinda unintuitive.

        def enterEvent(self, e) {
            self.setStyleSheet("hover style")
        }
        def leaveEvent(self, e) {
            self.setStyleSheet("normal style")
        }
        

        Is there any better solution?

        1 Reply Last reply
        0

        1/3

        25 Jun 2023, 01:29

        • Login

        • Login or register to search.
        1 out of 3
        • First post
          1/3
          Last post
        0
        • Categories
        • Recent
        • Tags
        • Popular
        • Users
        • Groups
        • Search
        • Get Qt Extensions
        • Unsolved