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
QtWS25 Last Chance

Custom Button, paintEvent issue

Scheduled Pinned Locked Moved Unsolved Qt for Python
pyqt5pyside6custom widgetpainteventbutton
11 Posts 3 Posters 1.1k 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.
  • S Offline
    S Offline
    SGaist
    Lifetime Qt Champion
    wrote on 13 Jul 2022, 17:35 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

    E 1 Reply Last reply 13 Jul 2022, 17:40
    0
    • S SGaist
      13 Jul 2022, 17:35

      Hi,

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

      E Offline
      E Offline
      Emrecp
      wrote on 13 Jul 2022, 17:40 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
      • S Offline
        S Offline
        SGaist
        Lifetime Qt Champion
        wrote on 13 Jul 2022, 19:41 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

        E 1 Reply Last reply 13 Jul 2022, 20:02
        0
        • S SGaist
          13 Jul 2022, 19:41

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

          E Offline
          E Offline
          Emrecp
          wrote on 13 Jul 2022, 20:02 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
          • S Offline
            S Offline
            SGaist
            Lifetime Qt Champion
            wrote on 14 Jul 2022, 05:56 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

            E 2 Replies Last reply 14 Jul 2022, 09:09
            0
            • S SGaist
              14 Jul 2022, 05:56

              Can you provide a complete minimal script that shows this ?

              E Offline
              E Offline
              Emrecp
              wrote on 14 Jul 2022, 09:09 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
              • N Offline
                N Offline
                ndias
                wrote on 14 Jul 2022, 09:50 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

                E 1 Reply Last reply 14 Jul 2022, 11:19
                2
                • N ndias
                  14 Jul 2022, 09:50

                  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

                  E Offline
                  E Offline
                  Emrecp
                  wrote on 14 Jul 2022, 11:19 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
                  • S SGaist
                    14 Jul 2022, 05:56

                    Can you provide a complete minimal script that shows this ?

                    E Offline
                    E Offline
                    Emrecp
                    wrote on 14 Jul 2022, 21:07 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
                    • S Offline
                      S Offline
                      SGaist
                      Lifetime Qt Champion
                      wrote on 15 Jul 2022, 19:42 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

                      11/11

                      15 Jul 2022, 19:42

                      • Login

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