Re: How to make a circular button?
Maurizio Berti <[email protected]>
| Newsgroups | gmane.comp.python.pyqt-pykde |
|---|---|
| Message-ID | <CAPn+-XQ1Cf+v3ixyy8bM-79ABFPUa8qko6M5fcTEYE68FKAX-Q@mail.gmail.com> |
You'll have to subclass QPushButton, provide a way to set/change the
radius, and at least override the paintEvent to actually draw the circle
and possibly the sizeHint to report the preferred size of the button (based
on the radius), unless you to set a fixed size when setting the radius.
In the following example I've used two gradients to get a round button with
borders that have a "shadow" effect: it's composed of a conical gradient
with a superimposed radial gradient to "mask" the center of the conical.
class CircleButton(QtWidgets.QPushButton):
def __init__(self, radius=None, parent=None):
super().__init__(parent)
if radius is None:
radius = self.font().pointSize() * 2
self.setRadius(radius)
# use the palette as source for the colors
palette = self.palette()
light = palette.color(palette.Light)
midlight = palette.color(palette.Midlight)
mid = palette.color(palette.Mid)
dark = palette.color(palette.Dark)
# a radial gradient for the "shadow effect" when button is unpressed
self.backgroundUp = QtGui.QConicalGradient(.5, .5, 135)
self.backgroundUp.setCoordinateMode(self.backgroundUp.ObjectBoundingMode)
self.backgroundUp.setStops([
(0.0, light),
(0.3, dark),
(0.6, dark),
(1.0, light),
])
# the same as above, but inverted for pressed state
self.backgroundDown = QtGui.QConicalGradient(.5, .5, 315)
self.backgroundDown.setCoordinateMode(self.backgroundDown.ObjectBoundingMode)
self.backgroundDown.setStops(self.backgroundUp.stops())
# a "mask" for the conical gradient
self.ringShapeDown = QtGui.QRadialGradient(.5, .5, .5)
self.ringShapeDown.setCoordinateMode(self.ringShapeDown.ObjectBoundingMode)
self.ringShapeDown.setStops([
(0.7536231884057971, midlight),
(0.7960662525879917, QtCore.Qt.transparent),
])
self.ringShapeUp = QtGui.QRadialGradient(.5, .5, .5)
self.ringShapeUp.setCoordinateMode(self.ringShapeUp.ObjectBoundingMode)
self.ringShapeUp.setStops([
(0.7536231884057971, mid),
(0.7960662525879917, QtCore.Qt.transparent),
(0.9627329192546584, QtCore.Qt.transparent),
])
def getButtonRect(self):
# just a helper function to avoid repetitions
size = min(self.width(), self.height()) - 1
rect = QtCore.QRect(0, 0, size, size)
rect.moveCenter(self.rect().center())
return rect
def mousePressEvent(self, event):
# ensure that the click happens within the circle
path = QtGui.QPainterPath()
path.addEllipse(QtCore.QRectF(self.getButtonRect()))
if path.contains(event.pos()):
super().mousePressEvent(event)
def setRadius(self, radius):
self.radius = radius
# notify the layout manager that the size hint has changed
self.updateGeometry()
def sizeHint(self):
return QtCore.QSize(self.radius, self.radius)
def hasHeightForWidth(self):
return True
def heightForWidth(self, width):
return width
def paintEvent(self, event):
qp = QtGui.QPainter(self)
qp.setRenderHints(qp.Antialiasing)
qp.translate(.5, .5)
qp.setPen(QtCore.Qt.NoPen)
rect = self.getButtonRect()
if self.isDown() or self.isChecked():
qp.setBrush(self.backgroundDown)
qp.drawEllipse(rect)
qp.setBrush(self.ringShapeDown)
qp.drawEllipse(rect)
else:
qp.setBrush(self.backgroundUp)
qp.drawEllipse(rect)
qp.setBrush(self.ringShapeUp)
qp.drawEllipse(rect)
Il giorno mar 3 mar 2020 alle ore 13:08 Souvik Dutta Chowdhury <
[email protected]> ha scritto:
> I want to make a perfect circular button and want to set a custom radius.
> How to do it?
> _______________________________________________
> PyQt mailing list [email protected]
> https://www.riverbankcomputing.com/mailman/listinfo/pyqt
>
--
È difficile avere una convinzione precisa quando si parla delle ragioni del
cuore. - "Sostiene Pereira", Antonio Tabucchi
http://www.jidesk.net
_______________________________________________
PyQt mailing list [email protected]
https://www.riverbankcomputing.com/mailman/listinfo/pyqt