1#!/usr/bin/env python 2 3""" 4polygonwidget.py 5 6A PyQt custom widget example for Qt Designer. 7 8Copyright (C) 2006 David Boddie <david@boddie.org.uk> 9Copyright (C) 2005-2006 Trolltech ASA. All rights reserved. 10 11This program is free software; you can redistribute it and/or modify 12it under the terms of the GNU General Public License as published by 13the Free Software Foundation; either version 2 of the License, or 14(at your option) any later version. 15 16This program is distributed in the hope that it will be useful, 17but WITHOUT ANY WARRANTY; without even the implied warranty of 18MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19GNU General Public License for more details. 20 21You should have received a copy of the GNU General Public License 22along with this program; if not, write to the Free Software 23Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 24""" 25 26import math 27 28from PyQt5.QtCore import pyqtProperty, pyqtSlot, QPointF, QSize 29from PyQt5.QtGui import QBrush, QColor, QPainter, QPainterPath, QRadialGradient 30from PyQt5.QtWidgets import QApplication, QWidget 31 32 33class PolygonWidget(QWidget): 34 """PolygonWidget(QWidget) 35 36 Provides a custom widget to display a polygon with properties and slots 37 that can be used to customize its appearance. 38 """ 39 40 def __init__(self, parent=None): 41 42 super(PolygonWidget, self).__init__(parent) 43 44 self._sides = 5 45 self._innerRadius = 20 46 self._outerRadius = 50 47 self._angle = 0 48 49 self.createPath() 50 51 self._innerColor = QColor(255, 255, 128) 52 self._outerColor = QColor(255, 0, 128) 53 54 self.createGradient() 55 56 def paintEvent(self, event): 57 58 painter = QPainter() 59 painter.begin(self) 60 painter.setRenderHint(QPainter.Antialiasing) 61 painter.setBrush(QBrush(QColor(192, 192, 255))) 62 painter.drawRect(event.rect()) 63 64 painter.translate(self.width()/2.0, self.height()/2.0) 65 painter.rotate(self._angle) 66 painter.setBrush(QBrush(self.gradient)) 67 painter.drawPath(self.path) 68 painter.end() 69 70 def sizeHint(self): 71 72 return QSize(2*self._outerRadius + 20, 2*self._outerRadius + 20) 73 74 def createPath(self): 75 76 self.path = QPainterPath() 77 angle = 2*math.pi/self._sides 78 self.path.moveTo(self._outerRadius, 0) 79 for step in range(1, self._sides + 1): 80 self.path.lineTo( 81 self._innerRadius * math.cos((step - 0.5) * angle), 82 self._innerRadius * math.sin((step - 0.5) * angle) 83 ) 84 self.path.lineTo( 85 self._outerRadius * math.cos(step * angle), 86 self._outerRadius * math.sin(step * angle) 87 ) 88 self.path.closeSubpath() 89 90 def createGradient(self): 91 92 center = QPointF(0, 0) 93 self.gradient = QRadialGradient(center, self._outerRadius, center) 94 self.gradient.setColorAt(0.5, QColor(self._innerColor)) 95 self.gradient.setColorAt(1.0, QColor(self._outerColor)) 96 97 # The angle property is implemented using the getAngle() and setAngle() 98 # methods. 99 100 def getAngle(self): 101 return self._angle 102 103 # The setAngle() setter method is also a slot. 104 @pyqtSlot(int) 105 def setAngle(self, angle): 106 self._angle = min(max(0, angle), 360) 107 self.update() 108 109 angle = pyqtProperty(int, getAngle, setAngle) 110 111 # The innerRadius property is implemented using the getInnerRadius() and 112 # setInnerRadius() methods. 113 114 def getInnerRadius(self): 115 return self._innerRadius 116 117 # The setInnerRadius() setter method is also a slot. 118 @pyqtSlot(int) 119 def setInnerRadius(self, radius): 120 self._innerRadius = radius 121 self.createPath() 122 self.createGradient() 123 self.update() 124 125 innerRadius = pyqtProperty(int, getInnerRadius, setInnerRadius) 126 127 # The outerRadius property is implemented using the getOuterRadius() and 128 # setOuterRadius() methods. 129 130 def getOuterRadius(self): 131 return self._outerRadius 132 133 # The setOuterRadius() setter method is also a slot. 134 @pyqtSlot(int) 135 def setOuterRadius(self, radius): 136 self._outerRadius = radius 137 self.createPath() 138 self.createGradient() 139 self.update() 140 141 outerRadius = pyqtProperty(int, getOuterRadius, setOuterRadius) 142 143 # The numberOfSides property is implemented using the getNumberOfSides() 144 # and setNumberOfSides() methods. 145 146 def getNumberOfSides(self): 147 return self._sides 148 149 # The setNumberOfSides() setter method is also a slot. 150 @pyqtSlot(int) 151 def setNumberOfSides(self, sides): 152 self._sides = max(3, sides) 153 self.createPath() 154 self.update() 155 156 numberOfSides = pyqtProperty(int, getNumberOfSides, setNumberOfSides) 157 158 # The innerColor property is implemented using the getInnerColor() and 159 # setInnerColor() methods. 160 161 def getInnerColor(self): 162 return self._innerColor 163 164 def setInnerColor(self, color): 165 self._innerColor = max(3, color) 166 self.createGradient() 167 self.update() 168 169 innerColor = pyqtProperty(QColor, getInnerColor, setInnerColor) 170 171 # The outerColor property is implemented using the getOuterColor() and 172 # setOuterColor() methods. 173 174 def getOuterColor(self): 175 return self._outerColor 176 177 def setOuterColor(self, color): 178 self._outerColor = color 179 self.createGradient() 180 self.update() 181 182 outerColor = pyqtProperty(QColor, getOuterColor, setOuterColor) 183 184 185if __name__ == "__main__": 186 187 import sys 188 189 app = QApplication(sys.argv) 190 window = PolygonWidget() 191 window.show() 192 sys.exit(app.exec_()) 193