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
Forum Updated to NodeBB v4.3 + New Features

Custom Button, paintEvent issue

Scheduled Pinned Locked Moved Unsolved Qt for Python
pyqt5pyside6custom widgetpainteventbutton
11 Posts 3 Posters 1.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