Custom Button, paintEvent issue
-
Hello, I am trying to create a animated custom button.
In this link: Buttons I liked 3 & 19.When I try to create it: if you look closely you can see that there is another color in all the corners, i don't know why.
My Code:
AnimateEnabled = True def paintEvent(self, event:QPaintEvent): ret = None 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.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, int(self.width()*self.AnimateVal/100.00), self.height()), self.ButtonData.Radius, self.ButtonData.Radius) painter.drawPath(path) return ret
I would be very grateful if you could help me solve the different color problem in these corners and how I can make the button on the 19th number in this link best way?
Thanks! -
Hi,
Isn't that the color of the first brush you are using ?
-
Are you sure the actual width is the same ?
You are doing some maths that may alter that. -
@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)
-
Can you provide a complete minimal script that shows this ?
-
@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())
-
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
-
-
The smoothing done for the antialiasing will not be the same for all colors.