def initBrushes(): """ returns a list of brush families. Eraser is the last item of the list. @return: @rtype: list of brushFamily instances """ brushes = [] ###################### # standard round brush ###################### baseSize = 400 # 25 qpp = QPainterPath() qpp.addEllipse(QRect(0, 0, baseSize, baseSize)) roundBrushFamily = brushFamily('Round', baseSize, qpp, presetFilename=None) brushes.append(roundBrushFamily) ########## # eraser ########## qpp = QPainterPath() qpp.addEllipse(QRect(0, 0, baseSize, baseSize)) eraserFamily = brushFamily('Eraser', baseSize, qpp) # eraser must be added last brushes.append(eraserFamily) return brushes
def updatePath(self): qpp = QPainterPath() # coordinates are relative to activeTangent object qpp.moveTo(0, 0) qpp.lineTo((self.controlPoint - self.contactPoint)) qpp.addEllipse(self.controlPoint - self.contactPoint, 5.0, 5.0) self.setPath(qpp)
def __init__(self, x, y, color=Qt.white, fillColor=None, persistent=False, rect=None, parentItem=None): super().__init__(parent=parentItem) self.color = color self.setAcceptHoverEvents(True) self.persistent = persistent self.rect = rect if self.rect is not None: self.xmin, self.xmax, self.ymin, self.ymax = rect.left( ), rect.right(), rect.top(), rect.bottom() x = min(max(x, self.xmin), self.xmax) y = min(max(y, self.ymin), self.ymax) self.setPos(QPointF(x, y)) self.clicked = False self.setPen(QPen(color, 2)) # filling brush if fillColor is not None: self.setBrush(QBrush(fillColor)) qpp = QPainterPath() # coordinates are relative to activePoint qpp.addEllipse(-4, -4, 8, 8) self.setPath(qpp)
def drawGrid(self): step = 4 qpp = QPainterPath() for i in range(self.size): for j in range(self.size): node = self.gridNodes[i][j] if i % step == 0 and j % step == 0: if i > 0: qpp.moveTo(node.gridPos()) qpp.lineTo(self.gridNodes[i-step][j].gridPos()) if j > 0: qpp.moveTo(node.gridPos()) qpp.lineTo(self.gridNodes[i][j-step].gridPos()) if not node.isSelected(): continue # mark initial position qpp.moveTo(node.gridPos()) qpp.lineTo(node.initialPos) qpp.addEllipse(node.initialPos, 5, 5) # mark visible neighbors for n in node.neighbors(): if n.isVisible(): qpp.moveTo(n.gridPos()) qpp.lineTo(node.gridPos()) self.setPath(qpp)
def __init__(self, x, y, persistent=False, rect=None, parentItem=None): """ Interactive control point for the scene current spline. Persistent activePoints cannot be removed by mouse click (default is non persistent). If rect is not None, the moves of the point are restricted to rect. @param x: initial x-coordinate @type x: float @param y: initial y-coordinate @type y: float @param persistent: persistent flag @type persistent: boolean @param parentItem: @type parentItem: object """ super(activePoint, self).__init__() self.tangent = None # link to tangent : used only by qudratic spline self.setAcceptHoverEvents(True) self.setParentItem(parentItem) self.persistent = persistent self.rect = rect if self.rect is not None: self.xmin, self.xmax, self.ymin, self.ymax = rect.left( ), rect.right(), rect.top(), rect.bottom() x = min(max(x, self.xmin), self.xmax) y = min(max(y, self.ymin), self.ymax) self.setPos(QPointF(x, y)) self.clicked = False self.setPen(QPen(QColor(255, 255, 255), 2)) qpp = QPainterPath() # coordinates are relative to activePoint qpp.addEllipse(-4, -4, 8, 8) self.setPath(qpp)
def update(self): qpp = QPainterPath() trans = QPointF(-4, -4) # coordinates are relative to activeTriangle for p in [self.A, self.B, self.C]: qpp.addEllipse(p + trans, 4, 4) self.setPath(qpp) super().update()
def shape(self): """自动调用,决定了交互的边界线范围,不设置正确的shape,事件失效或不灵敏""" path = QPainterPath() x, y = self.pos().toTuple() if self.paintMode == self.MODE_Default: path.addEllipse(x, y, self.wh, self.wh) elif self.paintMode == self.MODE_HoverText: path.addRoundRect(QRect(x, y, self.wh * 2, self.wh * 2), 25) return path
def loadPresets(filename, first=1): """ Loads brush preset from file @param filename: @type filename: str @return: @rtype: list of brushFamily instances """ brushes = [] patterns = [] baseSize = 400 # 25 try: rank = first entry = os.path.basename(filename) if entry[-4:].lower() in ['.png', '.jpg']: try: qpp = QPainterPath() qpp.addEllipse(QRect(0, 0, baseSize, baseSize)) presetBrushFamily = brushFamily('Preset ' + str(rank), baseSize, qpp, presetFilename=os.getcwd() + '\\' + BRUSHES_PATH + '\\' + entry) brushes.append(presetBrushFamily) rank += 1 except IOError: pass elif entry[-4:].lower() in ['.abr']: sImages, pImages = aParser.readFile(os.getcwd() + '\\' + BRUSHES_PATH + '\\' + entry) for im in sImages: qpp = QPainterPath() qpp.addEllipse(QRect(0, 0, baseSize, baseSize)) alpha = np.full_like(im, 255) im = np.dstack((im, im, im, im)) # alpha)) qim = ndarrayToQImage(im, format=QImage.Format_ARGB32) presetBrushFamily = brushFamily('Preset ' + str(rank), baseSize, qpp, image=qim) brushes.append(presetBrushFamily) rank += 1 rank = first for im in pImages: #alpha = np.full_like(im, 255) im = np.dstack((im, im, im, im)) qim = ndarrayToQImage(im, format=QImage.Format_ARGB32) p = pattern('pattern ' + str(rank), im=qim, pxmp=QPixmap.fromImage(qim)) patterns.append(p) rank += 1 except IOError: pass return brushes, patterns
def _make_ellipse_path(self): """Returns an ellipse path for the link's base. Returns: QPainterPath """ ellipse_path = QPainterPath() rect = QRectF(0, 0, 1.6 * self.magic_number, 1.6 * self.magic_number) rect.moveCenter(self.src_center) ellipse_path.addEllipse(rect) return ellipse_path
def __init__(self, controlPoint=QPointF(), contactPoint=QPointF(), parentItem=None): super().__init__(parent=parentItem) self.savedPen = self.pen() self.setAcceptHoverEvents(True) self.controlPoint = controlPoint self.contactPoint = contactPoint self.setPos(contactPoint) qpp = QPainterPath() # coordinates are relative to activeTangent object qpp.moveTo(0, 0) qpp.lineTo((controlPoint - contactPoint)) qpp.addEllipse(controlPoint - contactPoint, 5.0, 5.0) self.setPath(qpp) self.setZValue(-1) # set item pen self.setPen(QPen(QBrush(self.brushColor), self.penWidth))
class wheel(QWidget): currentColorChanged = Signal(QColor) def __init__(self, parent=None): super(wheel, self).__init__(parent) self.setFixedSize(256, 256) # start, end angles for value arc self.s_ang, self.e_ang = 135, 225 # offset angle and direction for color wheel self.o_ang, self.rot_d = 45, -1 # 1 for clock-wise, -1 for widdershins # other initializations self.pos = QPointF(-100, -100) self.vIdCen = QPointF(-100, -100) self.vIdAng = radians(self.s_ang) self.chPt = self.pos self.hue = self.sat = self.value = 255 self.setup() self.pos = self.cWhBox.center() self._namedColorList = [] self._namedColorPts = [] self._showNames = False self.setMouseTracking(True) self.installEventFilter(self) self._startedTimer = False ## def timerSpinner(self): ## "won't this be fun" ## self.o_ang -= 1; self.o_ang %= 360 ## stable = False ## ## colWhl = QConicalGradient(self.cen, self.o_ang) ## whl_cols = [Qt.red, Qt.magenta, ## Qt.blue, Qt.cyan, Qt.green, ## Qt.yellow, Qt.red] ## for i, c in enumerate(whl_cols[::self.rot_d]): ## colWhl.setColorAt(i / 6.0, c) ## ## if stable: # crosshairs stay on color ## t = radians(self.hue + self.o_ang * -self.rot_d) * -self.rot_d ## r = self.sat / 255.0 * self.cW_rad ## x, y = r * cos(t) + self.cen.x(), r * -sin(t) + self.cen.y() ## self.chPt = QPointF(x, y) ## else: # crosshairs stay on point ## t = atan2(self.cen.y() - self.pos.y(), self.pos.x() - self.cen.x()) ## h = (int(degrees(t)) - self.o_ang) * -self.rot_d ## self.hue = (h if h > 0 else h + 360) % 360 ## col = QColor(); col.setHsv(self.hue, self.sat, self.value) ## self.currentColorChanged.emit(col) ## ## self.cWhlBrush1 = QBrush(colWhl) ## self.update() def resizeEvent(self, event): self.setup() # re-construct the sizes self.setNamedColors(self._namedColorList) def getColor(self): col = QColor() col.setHsv(self.hue, self.sat, self.value) return col def setNamedColors(self, colorList): "sets list [(name, #html)] of named colors" self._namedColorList = colorList lst = [] r2 = (self.vAoBox.width() + self.vAiBox.width()) / 4.0 for i in self._namedColorList: h, s, v, a = QColor(i[1]).getHsv() t = radians(h + self.o_ang * -self.rot_d) * -self.rot_d r = s / 255.0 * self.cW_rad x, y = r * cos(t) + self.cen.x(), r * -sin(t) + self.cen.y() lst.append(QPointF(x, y)) #t2 = ((v / 255.0) * self.ang_w + radians(self.e_ang) + 2 * pi) % (2 * pi) #x, y = r2 * cos(t2) + self.cen.x(), r2 * -sin(t2) + self.cen.y() #lst.append(QPointF(x, y)) self._namedColorPts = lst def showNamedColors(self, flag=False): "show/hide location of named colors on color wheel" self._showNames = flag self.update() def setColor(self, color): # saturation -> radius h, s, v, a = color.getHsv() # hue -> angle self.hue, self.sat, self.value = h, s, v # value -> side bar thingy t = radians(h + self.o_ang * -self.rot_d) * -self.rot_d r = s / 255.0 * self.cW_rad x, y = r * cos(t) + self.cen.x(), r * -sin(t) + self.cen.y() self.chPt = QPointF(x, y) # hue, saturation self.vIdAng = t2 = (v / 255.0) * self.ang_w + radians(self.e_ang) self.vIdAng = t2 = t2 if t2 > 0 else t2 + 2 * pi r2 = self.vAoBox.width() / 2.0 x, y = r2 * cos(t2) + self.cen.x(), r2 * -sin(t2) + self.cen.y() self.vIdCen, self.vIdAng = QPointF(x, y), t2 # value self.vIdBox.moveCenter(self.vIdCen) self.update() def eventFilter(self, source, event): if (event.type() == QEvent.MouseButtonPress or (event.type() == QEvent.MouseMove and event.buttons() == Qt.LeftButton)): self.pos = pos = event.pos() t = atan2(self.cen.y() - pos.y(), pos.x() - self.cen.x()) if self.colWhlPath.contains(pos): # in the color wheel self.chPt = pos #if not self._startedTimer: # self.timer = QTimer() # self.timer.timeout.connect(self.timerSpinner) # self.timer.start(30.303) # self._startedTimer = True # hue -> mouse angle (same as t here) h = (int(degrees(t)) - self.o_ang) * -self.rot_d self.hue = (h if h > 0 else h + 360) % 360 # saturation -> mouse radius (clipped to wheel radius) m_rad = sqrt((self.pos.x() - self.cen.x())**2 + (self.pos.y() - self.cen.y())**2) self.sat = int(255 * min(m_rad / self.cW_rad, 1)) if self.vInArcPath.contains(pos): # in the value selection arc self.vIdAng = t if t > 0 else t + 2 * pi r2 = self.vAoBox.width() / 2.0 x, y = r2 * cos(t) + self.cen.x(), r2 * -sin(t) + self.cen.y() self.vIdCen = QPointF(x, y) self.vIdBox.moveCenter(self.vIdCen) self.value = int(255 * (t - radians(self.e_ang)) / self.ang_w) % 256 self.update() col = QColor() col.setHsv(self.hue, self.sat, self.value) self.currentColorChanged.emit(col) return QWidget.eventFilter(self, source, event) def paintEvent(self, event): painter = QPainter(self) painter.setRenderHint(painter.Antialiasing) #painter.setBrush(QBrush(Qt.black, Qt.NoBrush)) #painter.drawRect(self.winBox) # border # value selector indicator painter.setBrush(QBrush(Qt.black, Qt.SolidPattern)) painter.drawPie(self.vIdBox, 16 * (degrees(self.vIdAng) - 22.5), 720) # value selector arc painter.setClipPath(self.vArcPath) painter.setPen(Qt.NoPen) arc = QConicalGradient(self.cen, self.e_ang) color = QColor() color.setHsv(self.hue, self.sat, 255) arc.setColorAt(1 - (self.e_ang - self.s_ang) / 360.0, color) arc.setColorAt(1, Qt.black) arc.setColorAt(0, Qt.black) painter.setBrush(arc) painter.drawPath(self.vArcPath) painter.setClipPath(self.vArcPath, Qt.NoClip) # color wheel painter.setPen(Qt.NoPen) painter.setBrush(self.cWhlBrush1) painter.drawEllipse(self.cWhBox) painter.setBrush(self.cWhlBrush2) painter.drawEllipse(self.cWhBox) # crosshairs painter.setClipPath(self.colWhlPath) painter.setBrush(QBrush(Qt.black, Qt.SolidPattern)) chVert = QRectF(0, 0, 2, 20) chHort = QRectF(0, 0, 20, 2) chVert.moveCenter(self.chPt) chHort.moveCenter(self.chPt) painter.drawRect(chVert) painter.drawRect(chHort) # named color locations if self._showNames: painter.setClipPath(self.vArcPath, Qt.NoClip) painter.setPen(Qt.SolidLine) try: painter.drawPoints(*self._namedColorPts) # PyQt except: painter.drawPoints(self._namedColorPts) # PySide def setup(self): "sets bounds on value arc and color wheel" # bounding boxes self.winBox = QRectF(self.rect()) self.vIoBox = QRectF() # value indicator arc outer self.vIdBox = QRectF() # value indicator box self.vAoBox = QRectF() # value arc outer self.vAiBox = QRectF() # value arc inner self.cWhBox = QRectF() # color wheel self.vIdBox.setSize(QSizeF(15, 15)) self.vIoBox.setSize(self.winBox.size()) self.vAoBox.setSize(self.winBox.size() - self.vIdBox.size() / 2.0) self.vAiBox.setSize(self.vAoBox.size() - QSizeF(20, 20)) self.cWhBox.setSize(self.vAiBox.size() - QSizeF(20, 20)) # center - shifted to the right slightly x = self.winBox.width() - (self.vIdBox.width() + self.vAiBox.width()) / 2.0 self.cen = QPointF(x, self.winBox.height() / 2.0) # positions and initial settings self.vAoBox.moveCenter(self.cen) self.vAiBox.moveCenter(self.cen) self.cWhBox.moveCenter(self.cen) self.vIdBox.moveCenter(self.vIdCen) self.cW_rad = self.cWhBox.width() / 2.0 self.ang_w = radians(self.s_ang) - radians(self.e_ang) # gradients colWhl = QConicalGradient(self.cen, self.o_ang) whl_cols = [ Qt.red, Qt.magenta, Qt.blue, Qt.cyan, Qt.green, Qt.yellow, Qt.red ] for i, c in enumerate(whl_cols[::self.rot_d]): colWhl.setColorAt(i / 6.0, c) rad = min(self.cWhBox.width() / 2.0, self.cWhBox.height() / 2.0) cWhlFade = QRadialGradient(self.cen, rad, self.cen) cWhlFade.setColorAt(0, Qt.white) cWhlFade.setColorAt(1, QColor(255, 255, 255, 0)) self.cWhlBrush1 = QBrush(colWhl) self.cWhlBrush2 = QBrush(cWhlFade) # painter paths (arcs, wheel) rad = self.vAoBox.width() / 2.0 x, y = rad * cos(radians(self.s_ang)), -rad * sin(radians(self.s_ang)) x += self.cen.x() y += self.cen.y() self.vArcPath = QPainterPath(QPointF(x, y)) # value arc (for color) self.vArcPath.arcTo(self.vAoBox, self.s_ang, self.e_ang - self.s_ang) self.vArcPath.arcTo(self.vAiBox, self.e_ang, self.s_ang - self.e_ang) self.vArcPath.closeSubpath() self.vInArcPath = QPainterPath(QPointF(x, y)) # value arc (for mouse) self.vInArcPath.arcTo(self.vIoBox, self.s_ang, self.e_ang - self.s_ang) self.vInArcPath.arcTo(self.vAiBox, self.e_ang, self.s_ang - self.e_ang) self.vInArcPath.closeSubpath() self.colWhlPath = QPainterPath() self.colWhlPath.addEllipse(self.cWhBox)
def shape(self): path = QPainterPath() path.addEllipse(QPointF(), self._radius, self._radius) return path
def paintEvent(self, event): p = QPainter() p.begin(self) self._normalMap.render(p, event.rect()) p.setPen(Qt.black) # p.drawText(self.rect(), Qt.AlignBottom | Qt.TextWordWrap, "Map data CCBYSA 2009 OpenStreetMap.org contributors") p.end() if self.zoomed: dim = min(self.width(), self.height()) magnifierSize = min(MAX_MAGNIFIER, dim * 2 / 3) radius = magnifierSize / 2 ring = radius - 15 box = QSize(magnifierSize, magnifierSize) # reupdate our mask if self.maskPixmap.size() != box: self.maskPixmap = QPixmap(box) self.maskPixmap.fill(Qt.transparent) g = QRadialGradient() g.setCenter(radius, radius) g.setFocalPoint(radius, radius) g.setRadius(radius) g.setColorAt(1.0, QColor(255, 255, 255, 0)) g.setColorAt(0.5, QColor(128, 128, 128, 255)) mask = QPainter(self.maskPixmap) mask.setRenderHint(QPainter.Antialiasing) mask.setCompositionMode(QPainter.CompositionMode_Source) mask.setBrush(g) mask.setPen(Qt.NoPen) mask.drawRect(self.maskPixmap.rect()) mask.setBrush(QColor(Qt.transparent)) mask.drawEllipse(g.center(), ring, ring) mask.end() center = self.dragPos - QPoint(0, radius) center += QPoint(0, radius / 2) corner = center - QPoint(radius, radius) xy = center * 2 - QPoint(radius, radius) # only set the dimension to the magnified portion if self.zoomPixmap.size() != box: self.zoomPixmap = QPixmap(box) self.zoomPixmap.fill(Qt.lightGray) if True: p = QPainter(self.zoomPixmap) p.translate(-xy) self._largeMap.render(p, QRect(xy, box)) p.end() clipPath = QPainterPath() clipPath.addEllipse(QPointF(center), ring, ring) p = QPainter(self) p.setRenderHint(QPainter.Antialiasing) p.setClipPath(clipPath) p.drawPixmap(corner, self.zoomPixmap) p.setClipping(False) p.drawPixmap(corner, self.maskPixmap) p.setPen(Qt.gray) p.drawPath(clipPath) if self.invert: p = QPainter(self) p.setCompositionMode(QPainter.CompositionMode_Difference) p.fillRect(event.rect(), Qt.white) p.end()
def draw_game(self, painter): self.my_painters[ModelType.SHIP_MODEL].setup() self.my_painters[ModelType.BOLT_MODEL].setup() self.my_painters['background'].setup() painter.setBrush(QBrush(QColor('#20124d'))) painter.drawRect(0, 0, self.width(), self.height()) try: # DRAW BACKGROUND painter.setPen(QPen(QBrush(QColor(255, 255, 255)), 2, Qt.SolidLine)) self.my_painters['background'].paint(painter) # DRAW DEAD ZONE _dz_radius = self.controller.get_dead_zone_radius() _xy = self.controller.get_dead_zone_center().tolist() _point_center = self.transform_world_to_screen(*_xy, is_point=True) # GET MOBILE OBJECTS _model_ships = self.controller.get_data_from_players( enemy_only=False) _model_bolts = self.controller.get_data_from_bolts() _model_asteroids = self.controller.get_data_from_asteroids() # SET CAMERA PSOTOPM _ship_to_follow = None if self.camera_is_locked: _ship_to_follow = self.controller.get_player( self.controller.get_name()) if _ship_to_follow is not None and _ship_to_follow.is_alive: self.camera_pst = QPoint( -_ship_to_follow.x + self.width() // 2, _ship_to_follow.y + self.height() // 2) elif len(_model_ships): _ship_to_follow = _model_ships[self.camera_increment % len(_model_ships)] self.camera_pst = QPoint( -_ship_to_follow.x + self.width() // 2, _ship_to_follow.y + self.height() // 2) # DRAW MOBILE OBJECTS for _mob in _model_bolts + _model_ships + _model_asteroids: self.my_painters[_mob.type].paint(painter, model=_mob) # DRAW OVERLAY _brush_band = QBrush(QColor('#00284d')) _barre_height = 100 _rect_top_title = QRect(0, 0, self.width(), 50) _rect_band = QRect(0, (self.height() - _barre_height) // 2, self.width(), _barre_height) _rect_text1 = QRect(0, (self.height() - _barre_height) // 2, self.width(), _barre_height // 2) _rect_text2 = QRect(0, self.height() // 2, self.width(), _barre_height // 2) _rect_board_score_bg = QRect(self.width() // 2 - 250, 50, 500, self.height() - 200) _rect_board_title = QRect(0, 100, self.width(), 100) _rect_board_score = QRect(0, 200, self.width(), self.height() - 200) painter.setPen(QPen(QColor('#ffffff'), 10)) painter.setFont(QFont('Open Sans', weight=QFont.Bold, pointSize=20)) if self.controller.is_party_waiting(): painter.setPen(QPen(Qt.NoPen)) painter.setBrush(_brush_band) painter.setOpacity(.75) painter.drawRect(_rect_band) painter.setOpacity(1) painter.setPen(QPen(QColor('#ffffff'), 50)) painter.drawText(_rect_text1, Qt.AlignCenter, 'WAITING FOR PLAYERS') painter.drawText(_rect_text2, Qt.AlignCenter, '{}'.format(self.controller.get_time_left())) elif self.controller.is_party_ready_to_fight(): painter.setPen(QPen(Qt.NoPen)) painter.setBrush(_brush_band) painter.setOpacity(.75) painter.drawRect(_rect_band) painter.setOpacity(1) painter.setPen( QPen( QColor('#ffffff' if self.controller.get_time_left() > 5 else '#ff5555'), 50)) painter.drawText(_rect_text1, Qt.AlignCenter, 'READY TO FIGHT?') painter.drawText(_rect_text2, Qt.AlignCenter, '{}'.format(self.controller.get_time_left())) elif self.controller.has_party_winner(): painter.setPen(QPen(Qt.NoPen)) painter.setBrush(_brush_band) painter.setOpacity(.75) painter.drawRect(_rect_board_score_bg) painter.setOpacity(1) painter.setPen(QPen(QColor('#ffffff'), 50)) painter.drawText( _rect_board_title, Qt.AlignHCenter, 'Winner is: {} !'.format(self.controller.get_winner())) _text_score = [ '=========================', 'PARTY: {}'.format(self.controller.get_party_name()), '========= SCORE =========' ] painter.setPen(QPen(QColor('#8be9fd'), 50)) painter.setFont( QFont('Open Sans', weight=QFont.Bold, pointSize=15)) for _i, _player in enumerate( self.controller.get_rank_board()[::-1]): _text_score.append('> {: >2}. {: >35}'.format( _i + 1, _player)) painter.drawText(_rect_board_score, Qt.AlignHCenter, '\n'.join(_text_score)) elif self.controller.is_party_done(): painter.drawText(50, 50, 'PARTY DONE !') elif self.controller.is_party_in_progress(): painter.setPen(QPen(Qt.NoPen)) painter.setBrush(_brush_band) painter.setOpacity(.75) painter.drawRect(_rect_top_title) painter.setOpacity(1) painter.setPen(QPen(QColor('#8be9fd'), 50)) painter.setFont( QFont('Open Sans', weight=QFont.Bold, pointSize=10)) if _ship_to_follow is not None: painter.drawText( 50, 25, 'TimeLeft: {1} | Alive: {0} | Player: {2} |' ' Life: {3}%'.format( sum([_ship.is_alive for _ship in _model_ships]), self.controller.get_time_left(), _ship_to_follow.name, int(_ship_to_follow.life * 100))) else: painter.drawText( 50, 25, 'TimeLeft: {1} | Alive: {0}'.format( sum([_ship.is_alive for _ship in _model_ships]), self.controller.get_time_left())) # DRAW DEAD ZONE FILL _path = QPainterPath() _path.addRect( QRect(_point_center.x() - PartyConst.WIDTH, _point_center.y() - PartyConst.HEIGHT, PartyConst.WIDTH * 2, PartyConst.HEIGHT * 2)) _path.addEllipse(_point_center, _dz_radius, _dz_radius) painter.setPen(QPen(QColor('#00ffff'), 10, Qt.SolidLine)) painter.setBrush(QBrush(QColor('#00ffff'))) painter.setOpacity(.25) painter.drawPath(_path) painter.setOpacity(1.) painter.setBrush(QBrush(Qt.NoBrush)) painter.drawEllipse(_point_center, _dz_radius, _dz_radius) painter.setPen(QPen(QColor('#ffffff'), 5, Qt.SolidLine)) painter.drawEllipse(_point_center, _dz_radius, _dz_radius) except Exception as e: print('> [ERR] paintEvent: {}:{}'.format(type(e).__name__, e))
def getSymbolFromCmnd(self, symbolinfo): ''' Returns the SymbolPath for the symbol described in symbolinfo, which can either be a string or a dictionary. If symbolinfo is a string, it should be the name of a symbol that has already been defined, either as a pre-defined symbol or from a previous symbol definition. Current pre-defined symbol names are ones involving circles: 'dot': very small filled circle 'dotex': very small filled circle and outer lines of an ex mark 'dotplus': very small filled circle and outer lines of a plus mark 'circle': unfilled circle 'circfill': normal-sized filled circle 'circex': small unfilled circle and outer lines of an ex mark 'circplus': small unfilled circle and outer lines of a plus mark If symbolinfo is a dictionary, the following key/value pairs are recognized: 'name' : (string) symbol name (required) 'pts' : (sequence of pairs of floats) vertex coordinates 'fill' : (bool) color-fill symbol? If 'pts' is given, the value is coordinates that define the symbol as multiline subpaths in a [-50,50] square for typical size. The location of the point this symbol represents will be at the center of the square. A coordinate outside [-100,100] will terminate the current subpath, and the next valid coordinate will start a new subpath. This definition will replace an existing symbol with the given name. If 'pts' is not given, the symbol must already be defined, either as a pre-defined symbol (see above) or from a previous symbol definition. Raises: TypeError - if symbolinfo is neither a string nor a dictionary KeyError - if symbolinfo is a dictionary and the key 'name' is not given ValueError - if there are problems generating the symbol ''' # get the information about the symbol if isinstance(symbolinfo, str): symbol = symbolinfo pts = None fill = False elif isinstance(symbolinfo, dict): symbol = symbolinfo['name'] pts = symbolinfo.get('pts', None) fill = symbolinfo.get('fill', False) else: raise TypeError('symbolinfo must either be a dictionary or a string') if pts is None: # no path given; check if already defined sympath = self.__symbolpaths.get(symbol) if sympath is not None: return sympath # symbol not defined - if well known, create a SymbolPath for it if symbol == 'dot': path = QPainterPath() path.addEllipse(-10.0, -10.0, 20.0, 20.0) sympath = SymbolPath(path, True) elif symbol == 'dotplus': path = QPainterPath() path.addEllipse(-10.0, -10.0, 20.0, 20.0) # filled path, so need to draw "lines" as rectangles path.addRect( -4.0, -50.0, 8.0, 24.0) path.addRect( -4.0, 26.0, 8.0, 24.0) path.addRect(-50.0, -4.0, 24.0, 8.0) path.addRect( 26.0, -4.0, 24.0, 8.0) sympath = SymbolPath(path, True) elif symbol == 'dotex': path = QPainterPath() path.addEllipse(-10.0, -10.0, 20.0, 20.0) # filled path, so need to draw "lines" as rectangles path.moveTo(-38.18, -32.53) path.lineTo(-32.53, -38.18) path.lineTo(-15.56, -21.21) path.lineTo(-21.21, -15.56) # moveTo adds an implicit closeSubpath in QPainterPath path.moveTo(-38.18, 32.53) path.lineTo(-32.53, 38.18) path.lineTo(-15.56, 21.21) path.lineTo(-21.21, 15.56) # moveTo adds an implicit closeSubpath in QPainterPath path.moveTo( 38.18, -32.53) path.lineTo( 32.53, -38.18) path.lineTo( 15.56, -21.21) path.lineTo( 21.21, -15.56) # moveTo adds an implicit closeSubpath in QPainterPath path.moveTo( 38.18, 32.53) path.lineTo( 32.53, 38.18) path.lineTo( 15.56, 21.21) path.lineTo( 21.21, 15.56) # Qt closes the subpath automatically sympath = SymbolPath(path, True) elif symbol == 'circle': path = QPainterPath() path.addEllipse(-35.0, -35.0, 70.0, 70.0) sympath = SymbolPath(path, False) elif symbol == 'circfill': path = QPainterPath() path.addEllipse(-39.0, -39.0, 78.0, 78.0) sympath = SymbolPath(path, True) elif symbol == 'circplus': path = QPainterPath() path.addEllipse(-20.0, -20.0, 40.0, 40.0) # not a filled path, so just draw the lines path.moveTo( 0.0, -50.0) path.lineTo( 0.0, -20.0) path.moveTo( 0.0, 50.0) path.lineTo( 0.0, 20.0) path.moveTo(-50.0, 0.0) path.lineTo(-20.0, 0.0) path.moveTo( 50.0, 0.0) path.lineTo( 20.0, 0.0) sympath = SymbolPath(path, False) elif symbol == 'circex': path = QPainterPath() path.addEllipse(-20.0, -20.0, 40.0, 40.0) # not a filled path, so just draw the lines path.moveTo(-35.35, -35.35) path.lineTo(-14.15, -14.15) path.moveTo(-35.35, 35.35) path.lineTo(-14.15, 14.15) path.moveTo( 35.35, -35.35) path.lineTo( 14.15, -14.15) path.moveTo( 35.35, 35.35) path.lineTo( 14.15, 14.15) sympath = SymbolPath(path, False) else: raise ValueError("Unknown symbol '%s'" % str(symbol)) else: # define (or redefine) a symbol from the given path try: coords = [ [ float(val) for val in coord ] for coord in pts ] if not coords: raise ValueError for crd in coords: if len(crd) != 2: raise ValueError except Exception: raise ValueError('pts, if given, must be a sequence of pairs of numbers') path = QPainterPath() somethingdrawn = False newstart = True for (xval, yval) in coords: # flip so positive y is up yval *= -1.0 if (xval < -100.0) or (xval > 100.0) or (yval < -100.0) or (yval > 100.0): # end the current subpath newstart = True elif newstart: # start a new subpath; moveTo adds an implicit closeSubpath in QPainterPath path.moveTo(xval, yval) newstart = False else: # continue the current subpath path.lineTo(xval, yval) somethingdrawn = True if not somethingdrawn: del path raise ValueError('symbol definition does not contain any drawn lines') # Qt closes the (sub)path automatically sympath = SymbolPath(path, fill) # save and return the SymbolPath self.__symbolpaths[symbol] = sympath return sympath
def shape(self) -> QPainterPath: path = QPainterPath() path.addEllipse(-10, -10, 20, 20) return path