Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Qt for Python
  4. Custom Button, paintEvent issue

Custom Button, paintEvent issue

Scheduled Pinned Locked Moved Unsolved Qt for Python
pyqt5pyside6custom widgetpainteventbutton
11 Posts 3 Posters 2.3k Views 2 Watching
  • 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.
  • SGaistS Offline
    SGaistS Offline
    SGaist
    Lifetime Qt Champion
    wrote on last edited by
    #2

    Hi,

    Isn't that the color of the first brush you are using ?

    Interested in AI ? www.idiap.ch
    Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

    EmrecpE 1 Reply Last reply
    0
    • SGaistS SGaist

      Hi,

      Isn't that the color of the first brush you are using ?

      EmrecpE Offline
      EmrecpE Offline
      Emrecp
      wrote on last edited by
      #3

      @SGaist Yes, but it has to be in the background because new drawing is being made on it (same radius)

      1 Reply Last reply
      0
      • SGaistS Offline
        SGaistS Offline
        SGaist
        Lifetime Qt Champion
        wrote on last edited by
        #4

        Are you sure the actual width is the same ?
        You are doing some maths that may alter that.

        Interested in AI ? www.idiap.ch
        Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

        EmrecpE 1 Reply Last reply
        0
        • SGaistS SGaist

          Are you sure the actual width is the same ?
          You are doing some maths that may alter that.

          EmrecpE Offline
          EmrecpE Offline
          Emrecp
          wrote on last edited by
          #5

          @SGaist I don't think so. I tried like this, still corners has the orange(my color).

           path.addRoundedRect(QRectF(0, 0, self.width(), self.height()), self.ButtonData.Radius, self.ButtonData.Radius)  # Base background of button
          painter.drawPath(path)  # I need to draw it else color will be changed
          
          if self.AnimateEnabled:
              painter.setBrush(QBrush(QColor(231, 231, 231)))
              path.addRoundedRect(QRectF(0, 0, 0, self.height()),self.ButtonData.Radius, self.ButtonData.Radius) # Changed here (setted width to 0)
              painter.drawPath(path)
          
          
          1 Reply Last reply
          0
          • SGaistS Offline
            SGaistS Offline
            SGaist
            Lifetime Qt Champion
            wrote on last edited by
            #6

            Can you provide a complete minimal script that shows this ?

            Interested in AI ? www.idiap.ch
            Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

            EmrecpE 2 Replies Last reply
            0
            • SGaistS SGaist

              Can you provide a complete minimal script that shows this ?

              EmrecpE Offline
              EmrecpE Offline
              Emrecp
              wrote on last edited by Emrecp
              #7

              @SGaist Sure, when run it take a screenshoot and zoom in to see closely.
              Note:
              PySide6 version: 6.3.0
              Python: 3.9.7

              # -*- coding: utf-8 -*-
              import sys, os, time
              from PySide6 import QtCore, QtWidgets, QtGui
              from PySide6.QtWidgets import *
              from PySide6.QtCore import *
              from PySide6.QtGui import *
              class Button(QPushButton):
                  Radius = 10
                  def __init__(self, *args, **kwargs):
                      super().__init__(*args, **kwargs)
                      self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
              
                  def paintEvent(self, event: QPaintEvent):
                      painter = QPainter(self)
                      painter.setRenderHint(QPainter.Antialiasing)
                      path = QPainterPath()
                      painter.setBrush(QBrush(QColor(255, 111, 42)))
                      painter.setPen(Qt.NoPen)
              
                      path.addRoundedRect(QRectF(0, 0, self.width(), self.height()), self.Radius, self.Radius)  # Base background of button
                      painter.drawPath(path)  # I need to draw it else color will be changed
              
                      painter.setBrush(QBrush(QColor(231, 231, 231)))
                      #path.addRoundedRect(QRectF(0, 0, int(self.width() * self.AnimateVal / 100.00), self.height()),self.ButtonData.Radius, self.ButtonData.Radius)
                      path.addRoundedRect(QRectF(0, 0, 0, self.height()), self.Radius, self.Radius)
                      painter.drawPath(path)
              
              if __name__ == "__main__":
                  app = QApplication(sys.argv)
                  wind = QMainWindow()
                  wind.setStyleSheet("QMainWindow{background-color:rgb(247,247,250)}")
                  wind.resize(150, 80)
                  wid = QWidget()
                  lay = QHBoxLayout(wid)
                  lay.setAlignment(Qt.AlignCenter)
              
                  mycustombutton = Button()
                  lay.addWidget(mycustombutton)
                  wind.setCentralWidget(wid)
                  wind.show()
                  sys.exit(app.exec())
              
              1 Reply Last reply
              0
              • ndiasN Offline
                ndiasN Offline
                ndias
                wrote on last edited by
                #8

                Hi @Emrecp ,

                Why you don't use animations to get the desired effect? I think you don't need to use QPaintEvent.

                Please check bellow a sample app I used before with animated button. Feel free to make any necessary changes. ;)

                # Import the necessary modules required
                import sys
                
                from PySide6.QtWidgets import *
                from PySide6.QtGui import *
                from PySide6.QtCore import *
                
                class animatedButton(QPushButton):
                    '''
                    Button containing animated background with gradient moving from left to right on hover and
                    backward on leave
                    '''
                    def __init__(self, str: str, parent=None):
                        super().__init__(parent)
                
                        self.setText(str)
                        self.setMinimumSize(50, 50)
                
                        self.color1 = "#0DF2C9"
                        self.color2 = "#4EC5F1"
                
                        self._animationHover = QVariantAnimation(self)
                        self._animationHover.setDuration(200)
                        self._animationHover.setStartValue(0.0)
                        self._animationHover.setEndValue(1.0)
                        self._animationHover.valueChanged.connect(self._setButtonStyleHover)
                
                        self._animationPressed = QVariantAnimation(self)
                        self._animationPressed.setDuration(100)
                        self._animationPressed.setStartValue(0.0)
                        self._animationPressed.setEndValue(1.0)
                        self._animationPressed.valueChanged.connect(self._setButtonStylePressed)
                
                        self._setButtonStyleHover(self._animationHover.startValue()) # set button initial style
                
                    def setColor1(self, color: str):
                        """ :param str color: hex color code, SVG color keyword names or other color definition """
                        self.color1 = color
                        self._setButtonStyleHover(self._animationHover.startValue())
                    def setColor2(self, color: str):
                        """ :param str color: hex color code, SVG color keyword names or other color definition """
                        self.color2 = color
                        self._setButtonStyleHover(self._animationHover.startValue())
                
                    def _setButtonStyleHover(self, value):
                        qss = """
                              padding: 12px;
                              font: 75 14pt "Microsoft YaHei UI";
                              font-weight: bold;
                              color: rgb(255, 255, 255);
                              border-style: solid;
                              border-radius:21px;
                              """
                        if value == 0:
                            gradient = "background-color: qlineargradient(spread: pad, x1:0, y1:0, x2:1, y2:0, stop:{value} {color2}, stop: 1.0 {color1});".format(
                                    color1=self.color1, color2=self.color2, value=value )
                        elif value == 1:
                            gradient = "background-color: qlineargradient(spread: pad, x1:0, y1:0, x2:1, y2:0, stop:0 {color1}, stop: 1.0 {color2});".format(
                                    color1=self.color1, color2=self.color2, value=value )
                        else:
                            gradient = "background-color: qlineargradient(spread: pad, x1:0, y1:0, x2:1, y2:0, stop:0 {color1}, stop:{value} {color2}, stop: 1.0 {color1});".format(
                                    color1=self.color1, color2=self.color2, value=value )
                        qss += gradient
                        self.setStyleSheet(qss)
                
                    def _setButtonStylePressed(self, value):
                        qss = """
                              padding: 12px;
                              font: 75 14pt "Microsoft YaHei UI";
                              font-weight: bold;
                              color: rgb(255, 255, 255);
                              border-style: solid;
                              border-radius:21px;
                              """
                        if value == 0:
                            gradient = "background-color: {color}".format(color=self.color2)
                        elif value == 1:
                            gradient = "background-color: qlineargradient(spread: pad, x1:0, y1:0, x2:1, y2:0, stop:0 {color1}, stop: 1.0 {color2});".format(
                                    color1=self.color1, color2=self.color2, value=value )
                        else:
                            gradient = "background-color: qlineargradient(spread: pad, x1:0, y1:0, x2:1, y2:0, stop:0 {color1}, stop: {value} {color2});".format(
                                    color1=self.color1, color2=self.color2, value=value )
                        qss += gradient
                        self.setStyleSheet(qss)
                
                    def enterEvent(self, event):
                        self._animationHover.setDirection(QAbstractAnimation.Forward)
                        self._animationHover.start()
                        super().enterEvent(event)
                
                    def leaveEvent(self, event):
                        self._animationHover.setDirection(QAbstractAnimation.Backward)
                        self._animationHover.start()
                        super().leaveEvent(event)
                
                    def mousePressEvent(self, event):
                        self._animationPressed.setDirection(QAbstractAnimation.Backward)
                        self._animationPressed.start()
                        super().mousePressEvent(event)
                
                    def mouseReleaseEvent(self, event):
                        self._animationPressed.setDirection(QAbstractAnimation.Forward)
                        self._animationPressed.start()
                        super().mouseReleaseEvent(event)
                

                Best regards

                EmrecpE 1 Reply Last reply
                2
                • ndiasN ndias

                  Hi @Emrecp ,

                  Why you don't use animations to get the desired effect? I think you don't need to use QPaintEvent.

                  Please check bellow a sample app I used before with animated button. Feel free to make any necessary changes. ;)

                  # Import the necessary modules required
                  import sys
                  
                  from PySide6.QtWidgets import *
                  from PySide6.QtGui import *
                  from PySide6.QtCore import *
                  
                  class animatedButton(QPushButton):
                      '''
                      Button containing animated background with gradient moving from left to right on hover and
                      backward on leave
                      '''
                      def __init__(self, str: str, parent=None):
                          super().__init__(parent)
                  
                          self.setText(str)
                          self.setMinimumSize(50, 50)
                  
                          self.color1 = "#0DF2C9"
                          self.color2 = "#4EC5F1"
                  
                          self._animationHover = QVariantAnimation(self)
                          self._animationHover.setDuration(200)
                          self._animationHover.setStartValue(0.0)
                          self._animationHover.setEndValue(1.0)
                          self._animationHover.valueChanged.connect(self._setButtonStyleHover)
                  
                          self._animationPressed = QVariantAnimation(self)
                          self._animationPressed.setDuration(100)
                          self._animationPressed.setStartValue(0.0)
                          self._animationPressed.setEndValue(1.0)
                          self._animationPressed.valueChanged.connect(self._setButtonStylePressed)
                  
                          self._setButtonStyleHover(self._animationHover.startValue()) # set button initial style
                  
                      def setColor1(self, color: str):
                          """ :param str color: hex color code, SVG color keyword names or other color definition """
                          self.color1 = color
                          self._setButtonStyleHover(self._animationHover.startValue())
                      def setColor2(self, color: str):
                          """ :param str color: hex color code, SVG color keyword names or other color definition """
                          self.color2 = color
                          self._setButtonStyleHover(self._animationHover.startValue())
                  
                      def _setButtonStyleHover(self, value):
                          qss = """
                                padding: 12px;
                                font: 75 14pt "Microsoft YaHei UI";
                                font-weight: bold;
                                color: rgb(255, 255, 255);
                                border-style: solid;
                                border-radius:21px;
                                """
                          if value == 0:
                              gradient = "background-color: qlineargradient(spread: pad, x1:0, y1:0, x2:1, y2:0, stop:{value} {color2}, stop: 1.0 {color1});".format(
                                      color1=self.color1, color2=self.color2, value=value )
                          elif value == 1:
                              gradient = "background-color: qlineargradient(spread: pad, x1:0, y1:0, x2:1, y2:0, stop:0 {color1}, stop: 1.0 {color2});".format(
                                      color1=self.color1, color2=self.color2, value=value )
                          else:
                              gradient = "background-color: qlineargradient(spread: pad, x1:0, y1:0, x2:1, y2:0, stop:0 {color1}, stop:{value} {color2}, stop: 1.0 {color1});".format(
                                      color1=self.color1, color2=self.color2, value=value )
                          qss += gradient
                          self.setStyleSheet(qss)
                  
                      def _setButtonStylePressed(self, value):
                          qss = """
                                padding: 12px;
                                font: 75 14pt "Microsoft YaHei UI";
                                font-weight: bold;
                                color: rgb(255, 255, 255);
                                border-style: solid;
                                border-radius:21px;
                                """
                          if value == 0:
                              gradient = "background-color: {color}".format(color=self.color2)
                          elif value == 1:
                              gradient = "background-color: qlineargradient(spread: pad, x1:0, y1:0, x2:1, y2:0, stop:0 {color1}, stop: 1.0 {color2});".format(
                                      color1=self.color1, color2=self.color2, value=value )
                          else:
                              gradient = "background-color: qlineargradient(spread: pad, x1:0, y1:0, x2:1, y2:0, stop:0 {color1}, stop: {value} {color2});".format(
                                      color1=self.color1, color2=self.color2, value=value )
                          qss += gradient
                          self.setStyleSheet(qss)
                  
                      def enterEvent(self, event):
                          self._animationHover.setDirection(QAbstractAnimation.Forward)
                          self._animationHover.start()
                          super().enterEvent(event)
                  
                      def leaveEvent(self, event):
                          self._animationHover.setDirection(QAbstractAnimation.Backward)
                          self._animationHover.start()
                          super().leaveEvent(event)
                  
                      def mousePressEvent(self, event):
                          self._animationPressed.setDirection(QAbstractAnimation.Backward)
                          self._animationPressed.start()
                          super().mousePressEvent(event)
                  
                      def mouseReleaseEvent(self, event):
                          self._animationPressed.setDirection(QAbstractAnimation.Forward)
                          self._animationPressed.start()
                          super().mouseReleaseEvent(event)
                  

                  Best regards

                  EmrecpE Offline
                  EmrecpE Offline
                  Emrecp
                  wrote on last edited by
                  #9

                  @ndias Well thanks for your answer. Using setStyleSheet is good idea but I think it's not advanced better than custom paintEvent. Still don't know why corners has first brush color?

                  And I don't know hot to make 19th button on this website Website
                  Can someone help me to this too?
                  Thanks!

                  1 Reply Last reply
                  0
                  • SGaistS SGaist

                    Can you provide a complete minimal script that shows this ?

                    EmrecpE Offline
                    EmrecpE Offline
                    Emrecp
                    wrote on last edited by
                    #10

                    @SGaist I found the problem. When I remove

                       painter.setRenderHint(QPainter.Antialiasing)
                    

                    The colors on the corner gone. But why? Anyway to use antialiasing?

                    1 Reply Last reply
                    0
                    • SGaistS Offline
                      SGaistS Offline
                      SGaist
                      Lifetime Qt Champion
                      wrote on last edited by
                      #11

                      The smoothing done for the antialiasing will not be the same for all colors.

                      Interested in AI ? www.idiap.ch
                      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                      1 Reply Last reply
                      0

                      • Login

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