def __draw_link(self, name: str, points: Sequence[int]) -> None: """Draw link function. The link color will be the default color. """ pen = QPen(Qt.black if self.monochrome else color_qt('blue')) pen.setWidth(self.link_width) self.painter.setPen(pen) brush = color_qt('dark-gray') if self.monochrome else LINK_COLOR brush.setAlphaF(0.70) self.painter.setBrush(brush) qpoints = tuple( QPointF(self.pos[i][0], -self.pos[i][1]) * self.zoom for i in points if self.pos[i] and (not isnan(self.pos[i][0])) ) if len(qpoints) == len(points): self.painter.drawPolygon(*qpoints) self.painter.setBrush(Qt.NoBrush) if self.show_point_mark and name != VLink.FRAME and qpoints: pen.setColor(Qt.darkGray) self.painter.setPen(pen) self.painter.setFont(QFont('Arial', self.font_size)) cen_x = sum(self.pos[i][0] for i in points if self.pos[i]) cen_y = sum(self.pos[i][1] for i in points if self.pos[i]) self.painter.drawText( QPointF(cen_x, -cen_y) * self.zoom / len(points), f"[{name}]" )
def draw_point( self, i: int, cx, cy, fixed: bool, color: Tuple[int, int, int], mul: int = 1 ) -> None: """Draw a joint.""" pen = QPen(Qt.black if self.monochrome else QColor(*color)) pen.setWidth(2) self.painter.setPen(pen) x = cx * self.zoom y = cy * -self.zoom if fixed: # Draw a triangle below self.painter.drawPolygon( QPointF(x, y), QPointF(x - self.joint_size, y + 2 * self.joint_size), QPointF(x + self.joint_size, y + 2 * self.joint_size) ) r = self.joint_size for _ in range(1 if mul < 1 else mul): self.draw_circle(QPointF(x, y), r) r += 5 if not self.show_point_mark: return pen.setColor(Qt.darkGray) pen.setWidth(2) self.painter.setPen(pen) text = f"[Point{i}]" if self.show_dimension: text += f":({cx:.02f}, {cy:.02f})" self.painter.drawText(QPointF(x, y) + QPointF(6, -6), text)
def __draw_path(self) -> None: """Draw paths. Recording first.""" paths = self.path_record or self.path.path or self.path_preview if len(self.vpoints) != len(paths): return pen = QPen() fmt_paths: List[Tuple[int, _Path]] = list(enumerate(paths)) if paths is self.path_preview: fmt_paths.extend(self.slider_path_preview.items()) for i, path in fmt_paths: if self.path.show != i and self.path.show != -1: continue if self.monochrome: color = Qt.gray elif self.vpoints[i].color is None: color = color_qt('Green') else: color = QColor(*self.vpoints[i].color) pen.setColor(color) pen.setWidth(self.path_width) self.painter.setPen(pen) if self.path.curve: self.draw_curve(path) else: self.draw_dot(path)
def draw_slvs_ranges(self) -> None: """Draw solving range.""" pen = QPen() pen.setWidth(5) for i, (tag, rect) in enumerate(self.ranges.items()): range_color = QColor(color_num(i + 1)) range_color.setAlpha(30) self.painter.setBrush(range_color) range_color.setAlpha(255) pen.setColor(range_color) self.painter.setPen(pen) cx = rect.x() * self.zoom cy = rect.y() * -self.zoom if rect.width(): self.painter.drawRect(QRectF( QPointF(cx, cy), QSizeF(rect.width(), rect.height()) * self.zoom )) else: self.draw_circle(QPointF(cx, cy), 3) range_color.setAlpha(255) pen.setColor(range_color) self.painter.setPen(pen) self.painter.drawText(QPointF(cx, cy) + QPointF(6, -6), tag) self.painter.setBrush(Qt.NoBrush)
def __draw_path(self) -> None: """Draw paths. Recording first.""" paths: _Paths = self.path_record or self.path.path or self.path_preview if len(self.vpoints) != len(paths): return pen = QPen() fmt_paths = [(i, p) for i, p in enumerate(paths)] if paths is self.path_preview: fmt_paths.extend(self.slider_path_preview.items()) elif paths is self.path_record: fmt_paths.extend(self.slider_record.items()) else: # User paths fmt_paths.extend(self.path.slider_path.items()) for i, path in fmt_paths: if self.path.show != i and self.path.show != -1: continue vpoint = self.vpoints[i] if self.monochrome: color = color_qt('gray') else: color = color_qt(vpoint.color) pen.setColor(color) pen.setWidth(self.path_width) self.painter.setPen(pen) if self.path.curve: self.draw_curve(path) else: self.draw_dot(path)
def paintEvent(self, event: QPaintEvent): painter = QPainter(self) painter.drawImage(self.rect(), self.image) if self.show_frame: painter.save() pen = QPen() pen.setWidth(2) pen.setColor(QColor("black")) painter.setPen(pen) rect = QRect(1, 1, self.width() - 2, self.height() - 2) painter.drawRect(rect) pen.setColor(QColor("white")) painter.setPen(pen) rect = QRect(3, 3, self.width() - 6, self.height() - 6) painter.drawRect(rect) painter.restore() if self.show_arrow: painter.save() triangle = QPolygonF() dist = 4 point1 = QPoint(self.width() - self.triangle_width, 0) size = QSize(20, self.height() // 2) rect = QRect(point1, size) painter.fillRect(rect, QColor("white")) triangle.append(point1 + QPoint(dist, dist)) triangle.append(point1 + QPoint(size.width() - dist, dist)) triangle.append(point1 + QPoint(size.width() // 2, size.height() - dist)) painter.setBrush(Qt.black) painter.drawPolygon(triangle, Qt.WindingFill) painter.restore()
def paint(self, q_painter: 'QPainter', style_option_graphics_item: 'QStyleOptionGraphicsItem', widget: 'QWidget' = None): pen = QPen() pen.setColor(self.color) pen.setWidth(3) pen.setJoinStyle(Qt.MiterJoin) # 让箭头变尖 q_painter.setPen(pen) path = QPainterPath() point1 = self.start_port path.moveTo(self.start_port.center_pos) # for i in self.line_items: # i.setPen(QColor(255, 0, 0)) # i.update() for p in self.center_points + [self.end_port]: pen.setWidth(3) q_painter.setPen(pen) path.lineTo(p.center_pos) q_painter.drawLine(QLineF(point1.center_pos, p.center_pos)) arrow = self.draw_arrow(q_painter, point1.center_pos, p.center_pos) path.addPolygon(arrow) # 将箭头添加到连线上 point1 = p
def paintEvent(self, a0: QPaintEvent) -> None: super().paintEvent(a0) painter = QPainter(self) painter.save() painter.setRenderHint(QPainter.Antialiasing) pen2 = QPen() rect = QRectF(self.margin, self.height() / 2, self.width() - self.margin * 2, self.height() / 2 - self.margin) rect2 = QRectF(3 * self.margin, 2 * self.margin, self.width() - self.margin * 6, self.height()) pen2.setWidth(6) painter.setPen(pen2) painter.drawArc(rect2, 0, 180 * 16) pen2.setWidth(3) pen2.setColor(Qt.white) painter.setPen(pen2) painter.drawArc(rect2, 0, 180 * 16) painter.fillRect(rect, Qt.white) pen2.setWidth(2) pen2.setColor(Qt.black) painter.setPen(pen2) painter.drawRect(rect) painter.restore()
def paint(self, painter, option, index): QItemDelegate.paint(self, painter, option, index) column = index.column() row = index.row() rect = option.rect # Draw borders pen = QPen() pen.setWidth(1) pen.setColor(QColor('#cdcdcd')) painter.setPen(pen) painter.drawLine(rect.topLeft(), rect.topRight()) if (row == self.current_hover_row() or row == self.current_row() and (self.has_focus_or_context())): brush = QBrush(Qt.SolidPattern) brush.setColor(QColor(255, 255, 255, 100)) painter.fillRect(rect, brush) if row == self.current_row() and column in [const.COL_START]: pen = QPen() pen.setWidth(10) pen.setColor(QColor('#7cbb4c')) painter.setPen(pen) dyt = QPoint(0, 5) dyb = QPoint(0, 4) painter.drawLine(rect.bottomLeft()-dyb, rect.topLeft()+dyt)
def paintEvent(self, paintEvent): pen1 = QPen() pen1.setColor(self.color) painter = QPainter(self) painter.setPen(pen1) painter.begin(self) painter.drawRoundedRect(self.boundingRect(), 10, 10) # 绘制函数 painter.end()
def paintEvent(self, event: QPaintEvent) -> None: """Using a QPainter under 'self', so just change QPen or QBrush before painting. """ if not self.__grab_mode: self.painter.begin(self) self.painter.fillRect(event.rect(), QBrush(Qt.white)) # Translation self.painter.translate(self.ox, self.oy) # Background if not self.background.isNull(): rect = self.background.rect() self.painter.setOpacity(self.background_opacity) self.painter.drawImage( QRectF( self.background_offset * self.zoom, QSizeF(rect.width(), rect.height()) * self.background_scale * self.zoom), self.background, QRectF(rect)) self.painter.setOpacity(1) # Show frame pen = QPen(Qt.blue) pen.setWidth(1) self.painter.setPen(pen) self.painter.setFont(QFont("Arial", self.font_size)) # Draw origin lines if self.show_ticks not in {_TickMark.SHOW, _TickMark.SHOW_NUM}: return pen.setColor(Qt.gray) self.painter.setPen(pen) x_l = -self.ox x_r = self.width() - self.ox self.painter.drawLine(QPointF(x_l, 0), QPointF(x_r, 0)) y_t = self.height() - self.oy y_b = -self.oy self.painter.drawLine(QPointF(0, y_b), QPointF(0, y_t)) def indexing(v: float) -> int: """Draw tick.""" return int(v / self.zoom - v / self.zoom % 5) # Draw tick for x in range(indexing(x_l), indexing(x_r) + 1, 5): if x == 0: continue is_ten = x % 10 == 0 end = QPointF(x * self.zoom, -10 if is_ten else -5) self.painter.drawLine(QPointF(x, 0) * self.zoom, end) if self.show_ticks == _TickMark.SHOW_NUM and is_ten: self.painter.drawText(end + QPointF(0, 3), f"{x}") for y in range(indexing(y_b), indexing(y_t) + 1, 5): if y == 0: continue is_ten = y % 10 == 0 end = QPointF(10 if is_ten else 5, y * self.zoom) self.painter.drawLine(QPointF(0, y) * self.zoom, end) if self.show_ticks == _TickMark.SHOW_NUM and is_ten: self.painter.drawText(end + QPointF(3, 0), f"{-y}")
def paint(self, painter, styles, widget=None): pen1 = QPen(Qt.SolidLine) pen1.setColor(QColor(128, 128, 128)) painter.setPen(pen1) brush1 = QBrush(Qt.SolidPattern) brush1.setColor(self.color) painter.setBrush(brush1) painter.setRenderHint(QPainter.Antialiasing) # 反锯齿 painter.drawRoundedRect(self.boundingRect(), 10, 10)
def __draw_path(self) -> None: """Draw a path. A simple function than main canvas. """ pen = QPen() for i, path in enumerate(self.path.path): color = color_qt('Green') if f"P{i}" in self.target_path: color = color_qt('Dark-Orange') pen.setColor(color) pen.setWidth(self.path_width) self.painter.setPen(pen) self.draw_curve(path)
def paint(self, painter, option: QStyleOptionViewItem, index: QModelIndex) -> None: text = index.data(RealLabelHint) colors = tuple(index.data(RealJobColorHint)) real_status_color = index.data(RealStatusColorHint) painter.save() painter.setRenderHint(QPainter.Antialiasing, False) painter.setRenderHint(QPainter.TextAntialiasing, True) painter.setRenderHint(QPainter.SmoothPixmapTransform, False) border_pen = QPen() border_pen.setColor(QColorConstants.Black) border_pen.setWidth(1) painter.setBrush(QColorConstants.Blue) painter.setPen(border_pen) painter.drawRect(option.rect) margin = 0 if option.state & QStyle.State_Selected: margin = 5 real_status_rect = QRect( option.rect.x() + margin, option.rect.y() + margin, option.rect.width() - (margin * 2), option.rect.height() - (margin * 2), ) painter.setBrush(QColorConstants.Gray) painter.setBrush(real_status_color) painter.drawRect(real_status_rect) job_rect_margin = 10 job_rect = QRect( option.rect.x() + job_rect_margin, option.rect.y() + job_rect_margin, option.rect.width() - (job_rect_margin * 2), option.rect.height() - (job_rect_margin * 2), ) self._paint_inner_grid(painter, job_rect, colors) text_pen = QPen() text_pen.setColor(QColorConstants.Black) painter.setPen(text_pen) painter.drawText(option.rect, Qt.AlignCenter, text) painter.restore()
def drawContents(self, painter): """ @type painter: QPainter """ w = self.width() h = self.height() margin = 10 background = QColor(210, 211, 215) text_color = QColor(0, 0, 0) foreground = QColor(255, 255, 255) painter.setBrush(background) painter.fillRect(0, 0, w, h, background) pen = QPen() pen.setWidth(2) pen.setColor(foreground) painter.setPen(pen) painter.drawRect(0, 0, w - 1, h - 1) text_x = 2 * margin top_offset = margin text_area_width = w - 2 * margin painter.setPen(text_color) text_size = 150 font = QFont("Serif") font.setStyleHint(QFont.Serif) font.setPixelSize(text_size) painter.setFont(font) painter.drawText(text_x, margin + top_offset, text_area_width, text_size, int(Qt.AlignHCenter | Qt.AlignCenter), self.ert) top_offset += text_size + 2 * margin text_size = 25 font.setPixelSize(text_size) painter.setFont(font) painter.drawText(text_x, top_offset, text_area_width, text_size, int(Qt.AlignHCenter | Qt.AlignCenter), self.ert_title) top_offset += text_size + 4 * margin text_size = 20 font.setPixelSize(text_size) painter.setFont(font) painter.drawText(text_x, top_offset, text_area_width, text_size, int(Qt.AlignHCenter | Qt.AlignCenter), self.version)
def draw_sketch_line(painter, connection, style): if not connection.requires_port: return p = QPen() p.setWidth(style.construction_line_width) p.setColor(style.construction_color) p.setStyle(Qt.DashLine) painter.setPen(p) painter.setBrush(Qt.NoBrush) geom = connection.geometry cubic = cubic_path(geom) # cubic spline painter.drawPath(cubic)
def paint(self, painter: QPainter, option: QStyleOptionViewItem, index: QModelIndex) -> None: super().paint(painter, option, index) cellState: CellState = index.data(Qt.BackgroundRole) if cellState == CellState.Invalid: padding = 0 x = option.rect.x() + padding y = option.rect.y() + padding w = option.rect.width() - 1 - padding h = option.rect.height() - 1 - padding pen = QPen() pen.setColor(QColor(*(Color.Red).value)) pen.setWidth(1) painter.setPen(pen) painter.drawRect(QRect(x, y, w, h))
def __init__(self, data, color=Qt.green, parent=None): if ("size_x" in data.index) and ("size_y" in data.index): size_x = data["size_x"] size_y = data["size_y"] else: size_x = size_y = data["size"] super().__init__(data["x"] - size_x + 0.5, data["y"] - size_y + 0.5, 2 * size_x, 2 * size_y, parent) pen = QPen() pen.setWidthF(1.25) pen.setCosmetic(True) pen.setColor(color) self.setPen(pen) ttStr = "\n".join([ "{}: {:.2f}".format(k, v) for k, v in data.items() if k != "frame" ]) self.setToolTip(ttStr)
def paintEvent(self, event): bw = float(self._border_width) br = self._border_radius val = self.value() if self.orientation() == Qt.Horizontal: w = QStyle.sliderPositionFromValue(self.minimum(), self.maximum(), val, self.width()) h = self.height() rect = QRectF(bw / 2, bw / 2, w - bw, h - bw) else: w = self.width() h = self.height() - QStyle.sliderPositionFromValue( self.minimum(), self.maximum(), val, self.height()) rect = QRectF(bw / 2, h - bw / 2, w - bw, self.height() - bw) p = QPainter(self) p.setRenderHint(QPainter.Antialiasing) # draw the load meter value bar p.setPen(Qt.transparent) p.setBrush(self.gradient) p.drawRoundedRect(rect, br, br) # draw the border p.setBrush(Qt.transparent) border_pen = QPen() border_pen.setWidth(bw) border_pen.setColor(self._border_color) p.setPen(border_pen) rect = QRectF(bw / 2, bw / 2, self.width() - bw, self.height() - bw) p.drawRoundedRect(rect, br, br) # draw the load percentage text p.setPen(self._text_color) if self.orientation() == Qt.Vertical: p.rotate(-90) p.drawText(-self.height(), 0, self.height(), self.width(), Qt.AlignCenter, self.text()) else: p.drawText(0, 0, self.width(), self.height(), Qt.AlignCenter, self.text())
def createPen(self, color, offset=None): """ Creates a pen of the color specified Args: color (QColor): color for the line to be set to offset (bool): if color should be offset or not. Since this is only two colors, this can be a boolean, rather than an index. """ pen = QPen() pen.setColor(color) total_line_space = self.length() + (2 * self.spacing()) if offset: pen.setDashOffset(self.length() + self.spacing()) pen.setDashPattern([self.length(), total_line_space]) pen.setWidth(self.width) return pen
def drawPrimitive(self, element, option, painter, widget=None): """ https://www.qtcentre.org/threads/35443-Customize-drop-indicator-in-QTreeView Draw a line across the entire row rather than just the column we're hovering over. This may not always work depending on global style - for instance I think it won't work on OSX. Still draws the original line - not really sure why - clearing the painter will clear the entire view """ if element == self.PE_IndicatorItemViewItemDrop: # border # get attrs size = AbstractDragDropIndicator.INDICATOR_SIZE width = AbstractDragDropIndicator.INDICATOR_WIDTH # border color border_color = QColor(*iColor["rgba_selected"]) pen = QPen() pen.setWidth(AbstractDragDropIndicator.INDICATOR_WIDTH) pen.setColor(border_color) # background background_color = QColor(*iColor["rgba_selected"]) background_color.setAlpha(64) brush = QBrush(background_color) # set painter painter.setPen(pen) painter.setBrush(brush) # draw if self.orientation() == Qt.Vertical: self.__drawVertical(widget, option, painter, size, width) elif self.orientation() == Qt.Horizontal: self.__drawHorizontal(widget, option, painter, size, width) else: super(AbstractDragDropIndicator, self).drawPrimitive(element, option, painter, widget)
def __draw_link(self, vlink: VLink) -> None: """Draw a link.""" if vlink.name == VLink.FRAME or not vlink.points: return pen = QPen() # Rearrange: Put the nearest point to the next position. qpoints = convex_hull( [(c.x * self.zoom, c.y * -self.zoom) for c in vlink.points_pos(self.vpoints)], as_qpoint=True) if ( self.select_mode == SelectMode.LINK and self.vlinks.index(vlink) in self.selections ): pen.setWidth(self.link_width + 6) pen.setColor(Qt.black if self.monochrome else QColor(161, 16, 239)) self.painter.setPen(pen) self.painter.drawPolygon(*qpoints) pen.setWidth(self.link_width) pen.setColor(Qt.black if self.monochrome else color_qt(vlink.color)) self.painter.setPen(pen) self.painter.drawPolygon(*qpoints) if not self.show_point_mark: return pen.setColor(Qt.darkGray) self.painter.setPen(pen) p_count = len(qpoints) cen_x = sum(p.x() for p in qpoints) / p_count cen_y = sum(p.y() for p in qpoints) / p_count self.painter.drawText( QRectF(cen_x - 50, cen_y - 50, 100, 100), Qt.AlignCenter, f'[{vlink.name}]' )
def __draw_link(self, vlink: VLink) -> None: """Draw a link.""" if vlink.name == VLink.FRAME or not vlink.points: return points = self.__points_pos(vlink) pen = QPen() # Rearrange: Put the nearest point to the next position. qpoints = convex_hull(points, as_qpoint=True) if (self.select_mode == SelectMode.LINK and self.vlinks.index(vlink) in self.selections): pen.setWidth(self.link_width + 6) pen.setColor(Qt.black if self.monochrome else QColor(161, 16, 239)) self.painter.setPen(pen) self.painter.drawPolygon(*qpoints) pen.setWidth(self.link_width) pen.setColor(Qt.black if self.monochrome else QColor(*vlink.color)) self.painter.setPen(pen) brush = QColor(Qt.darkGray) if self.monochrome else LINK_COLOR brush.setAlphaF(self.transparency) self.painter.setBrush(brush) self.painter.drawPolygon(*qpoints) self.painter.setBrush(Qt.NoBrush) if not self.show_point_mark: return pen.setColor(Qt.darkGray) self.painter.setPen(pen) p_count = len(points) cen_x = sum(p[0] for p in points) / p_count cen_y = sum(p[1] for p in points) / p_count self.painter.drawText(QRectF(cen_x - 50, cen_y - 50, 100, 100), Qt.AlignCenter, f'[{vlink.name}]')
def paintEvent(self, event): """Override Qt method.""" painter = QPainter(self) painter.setOpacity(self.current_opacity) max_width = ( SASS_VARIABLES.WIDGET_CONTENT_TOTAL_WIDTH - 2 * SASS_VARIABLES.WIDGET_CONTENT_PADDING - 2 * SASS_VARIABLES.WIDGET_CONTENT_MARGIN ) # Hover top br = self.label_icon.rect().bottomRight() tl = self.label_icon.rect().topLeft() + QPoint(1, 1) y = br.y() + self.label_text.height() - 2 # br_new = QPoint(br.x() + 2, y) - QPoint(1, 1) br_new = QPoint(max_width - 1, y) - QPoint(1, 1) rect_hover = QRect(tl, br_new) # 2 is the border pen = QPen(Qt.NoPen) brush = QBrush(Qt.SolidPattern) brush.setColor(QColor('#fff')) painter.setBrush(brush) painter.setPen(pen) painter.drawRect(rect_hover) font = self.font() font.setPointSize(10) painter.setFont(font) pen = QPen() pen.setColor(QColor('black')) painter.setPen(pen) td = self.text_document td.setPageSize(QSizeF(rect_hover.size())) td.setHtml(self.summary) td.drawContents(painter) self.raise_()
def draw_scale_line(self, p): p.save() p.rotate(self._start_angle) scale_nums = self._scale_main_num * self._scaleSubNum angle_step = (360 - (self._start_angle - self._end_angle)) / scale_nums p.setPen(Qt.white) pen = QPen(Qt.white) for i in range(0, scale_nums + 1): if i >= self._warning_rate * scale_nums: pen.setColor(Qt.red) if i % self._scale_main_num == 0: pen.setWidth(2) p.setPen(pen) p.drawLine(64, 0, 72, 0) else: pen.setWidth(1) p.setPen(pen) p.drawLine(67, 0, 72, 0) p.rotate(angle_step) p.restore()
def __draw_path(self) -> None: """Draw a path. A simple function than main canvas. """ pen = QPen() pen.setWidth(self.path_width) for i, path in enumerate(self.path.path): if self.no_mechanism and i not in self.target_path: continue if i in self.target_path: if self.monochrome: color = color_qt('black') else: color = color_qt('dark-orange') else: if self.monochrome: color = color_qt('gray') else: color = color_qt('green') pen.setColor(color) self.painter.setPen(pen) self.draw_curve(path)
def draw_hovered_or_selected(painter, connection, style): geom = connection.geometry hovered = geom.hovered graphics_object = connection.graphics_object selected = graphics_object.isSelected() # drawn as a fat background if hovered or selected: p = QPen() line_width = style.line_width p.setWidth(2 * line_width) p.setColor( (style.selected_halo_color if selected else style.hovered_color)) painter.setPen(p) painter.setBrush(Qt.NoBrush) # cubic spline cubic = cubic_path(geom) painter.drawPath(cubic)
def paintEvent(self, event: QPaintEvent) -> None: """Drawing function.""" super(_DynamicCanvas, self).paintEvent(event) pen = QPen() pen.setWidth(self.link_width) brush = color_qt('dark-gray') if self.monochrome else LINK_COLOR self.painter.setBrush(brush) for vlink in self.vlinks: if vlink.name == VLink.FRAME or not vlink.points: continue points = [] for i in vlink.points: vpoint = self.vpoints[i] if (vpoint.type == VJoint.R or not vpoint.is_slot_link(vlink.name)): x, y = self.path.path[i][self.ind] else: x, y = self.path.slider_path[i][self.ind] points.append((x * self.zoom, y * -self.zoom)) qpoints = convex_hull(points, as_qpoint=True) pen.setColor( Qt.black if self.monochrome else color_qt(vlink.color)) self.painter.setPen(pen) self.painter.drawPolygon(*qpoints) self.painter.setBrush(Qt.NoBrush) pen.setWidth(self.path_width) for paths, vel, acc in [ (enumerate(self.path.path), self.vel, self.acc), (self.path.slider_path.items(), self.vel_slider, self.acc_slider), ]: for i, path in paths: vpoint = self.vpoints[i] if self.monochrome: color = color_qt('gray') else: color = color_qt(vpoint.color) pen.setColor(color) self.painter.setPen(pen) self.draw_curve(path) x, y = path[self.ind] zoom = 1. for vec, color in [(vel[i], Qt.blue), (acc[i], Qt.red)]: if self.ind >= len(vec): break vx, vy = vec[self.ind] if isnan(vx) or isnan(vy): break zoom /= self.factor r = hypot(vx, vy) * zoom if isclose(r, 0): break th = atan2(vy, vx) pen.setColor(color) self.painter.setPen(pen) self.draw_arrow(x, y, x + r * cos(th), y + r * sin(th)) self.draw_point(i, x, y, vpoint.grounded(), vpoint.color) self.painter.end()
def drawBorder(self): p = self._painter bw = float(self._border_width) br = self._border_radius p.setBrush(Qt.transparent) border_pen = QPen() border_pen.setWidth(int(bw)) border_pen.setColor(self._border_color) p.setPen(border_pen) # deal with orientation if self._orientation == Qt.Horizontal: rect = QRectF(bw / 2, bw / 2, self.width() - bw, self.height() - bw) else: # must be Qt.Vertical rect = QRectF(bw / 2, bw / 2, self.height() - bw, self.width() - bw) p.drawRoundedRect(rect, br, br)
def init_line_items(self): """ 初始化线段 :return: """ last_pos = self.start_port.center_pos for p in self.center_points: pos = p.center_pos line_item = PMGGraphicsLineItem(QLineF(last_pos, pos)) self.bind_line_item_signals(line_item) pen = QPen() pen.setColor(self.color) pen.setWidth(5) line_item.setPen(pen) self.canvas.addItem(line_item) last_pos = pos self.line_items.append(line_item) line_item = PMGGraphicsLineItem( QLineF(last_pos, self.end_port.center_pos)) self.bind_line_item_signals(line_item) self.canvas.addItem(line_item) self.line_items.append(line_item)
class QScale(QFrame): """ A bar-shaped indicator for scalar value. Configurable features include indicator type (bar/pointer), scale tick marks and orientation (horizontal/vertical). Parameters ---------- parent : QWidget The parent widget for the Scale """ def __init__(self, parent=None): super(QScale, self).__init__(parent) self._value = 1 self._lower_limit = -5 self._upper_limit = 5 self.position = None # unit: pixel self._bg_color = QColor('darkgray') self._bg_size_rate = 0.8 # from 0 to 1 self._indicator_color = QColor('black') self._pointer_width_rate = 0.05 self._barIndicator = False self._num_divisions = 10 self._show_ticks = True self._tick_pen = QPen() self._tick_color = QColor('black') self._tick_width = 0 self._tick_size_rate = 0.1 # from 0 to 1 self._painter = QPainter() self._painter_rotation = None self._painter_translation_y = None self._painter_translation_x = None self._painter_scale_x = None self._flip_traslation_y = None self._flip_scale_y = None self._widget_width = self.width() self._widget_height = self.height() self._orientation = Qt.Horizontal self._inverted_appearance = False self._flip_scale = False self._scale_height = 35 self._origin_at_zero = False self._origin_position = 0 self.set_position() def adjust_transformation(self): """ This method sets parameters for the widget transformations (needed to for orientation, flipping and appearance inversion). """ self.setMaximumSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX) # Unset fixed size if self._orientation == Qt.Horizontal: self._widget_width = self.width() self._widget_height = self.height() self._painter_translation_y = 0 self._painter_rotation = 0 self.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Fixed) self.setFixedHeight(self._scale_height) elif self._orientation == Qt.Vertical: # Invert dimensions for paintEvent() self._widget_width = self.height() self._widget_height = self.width() self._painter_translation_y = self._widget_width self._painter_rotation = -90 self.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Expanding) self.setFixedWidth(self._scale_height) if self._inverted_appearance: self._painter_translation_x = self._widget_width self._painter_scale_x = -1 else: self._painter_translation_x = 0 self._painter_scale_x = 1 if self._flip_scale: self._flip_traslation_y = self._widget_height self._flip_scale_y = -1 else: self._flip_traslation_y = 0 self._flip_scale_y = 1 def set_tick_pen(self): """ Define pen style for drawing scale tick marks. """ self._tick_pen.setColor(self._tick_color) self._tick_pen.setWidth(self._tick_width) def draw_ticks(self): """ Draw tick marks on the scale. """ if not self._show_ticks: return self.set_tick_pen() self._painter.setPen(self._tick_pen) division_size = self._widget_width / self._num_divisions tick_y0 = self._widget_height tick_yf = (1 - self._tick_size_rate)*self._widget_height for i in range(self._num_divisions+1): x = i*division_size self._painter.drawLine(x, tick_y0, x, tick_yf) # x1, y1, x2, y2 def draw_bar(self): """ Draw a bar as indicator of current value. """ self.set_origin() self.set_position() if self.position < 0 or self.position > self._widget_width: return self._painter.setPen(Qt.transparent) self._painter.setBrush(self._indicator_color) bar_width = self.position - self._origin_position bar_height = self._bg_size_rate * self._widget_height self._painter.drawRect(self._origin_position, 0, bar_width, bar_height) def draw_pointer(self): """ Draw a pointer as indicator of current value. """ self.set_position() if self.position < 0 or self.position > self._widget_width: return self._painter.setPen(Qt.transparent) self._painter.setBrush(self._indicator_color) pointer_width = self._pointer_width_rate * self._widget_width pointer_height = self._bg_size_rate * self._widget_height points = [ QPoint(self.position, 0), QPoint(self.position + 0.5*pointer_width, 0.5*pointer_height), QPoint(self.position, pointer_height), QPoint(self.position - 0.5*pointer_width, 0.5*pointer_height) ] self._painter.drawPolygon(QPolygon(points)) def draw_indicator(self): """ Draw the selected indicator for current value. """ if self._barIndicator: self.draw_bar() else: self.draw_pointer() def draw_background(self): """ Draw the background of the scale. """ self._painter.setPen(Qt.transparent) self._painter.setBrush(self._bg_color) bg_width = self._widget_width bg_height = self._bg_size_rate * self._widget_height self._painter.drawRect(0, 0, bg_width, bg_height) def paintEvent(self, event): """ Paint events are sent to widgets that need to update themselves, for instance when part of a widget is exposed because a covering widget was moved. Parameters ---------- event : QPaintEvent """ self.adjust_transformation() self._painter.begin(self) self._painter.translate(0, self._painter_translation_y) # Draw vertically if needed self._painter.rotate(self._painter_rotation) self._painter.translate(self._painter_translation_x, 0) # Invert appearance if needed self._painter.scale(self._painter_scale_x, 1) self._painter.translate(0, self._flip_traslation_y) # Invert scale if needed self._painter.scale(1, self._flip_scale_y) self._painter.setRenderHint(QPainter.Antialiasing) self.draw_background() self.draw_ticks() self.draw_indicator() self._painter.end() def calculate_position_for_value(self, value): """ Calculate the position (pixel) in which the pointer should be drawn for a given value. """ if value < self._lower_limit or value > self._upper_limit or \ self._upper_limit - self._lower_limit == 0: proportion = -1 # Invalid else: proportion = (value - self._lower_limit) / (self._upper_limit - self._lower_limit) position = int(proportion * self._widget_width) return position def set_origin(self): """ Set the position (pixel) in which the origin should be drawn. """ if self._origin_at_zero: self._origin_position = self.calculate_position_for_value(0) else: self._origin_position = 0 def set_position(self): """ Set the position (pixel) in which the pointer should be drawn. """ self.position = self.calculate_position_for_value(self._value) def update_indicator(self): """ Update the position and the drawing of indicator. """ self.set_position() self.repaint() def set_value(self, value): """ Set a new current value for the indicator. """ self._value = value self.update_indicator() def set_upper_limit(self, new_limit): """ Set the scale upper limit. Parameters ---------- new_limit : float The upper limit of the scale. """ self._upper_limit = new_limit def set_lower_limit(self, new_limit): """ Set the scale lower limit. Parameters ---------- new_limit : float The lower limit of the scale. """ self._lower_limit = new_limit def get_show_ticks(self): return self._show_ticks def set_show_ticks(self, checked): if self._show_ticks != bool(checked): self._show_ticks = checked self.repaint() def get_orientation(self): return self._orientation def set_orientation(self, orientation): self._orientation = orientation self.adjust_transformation() self.repaint() def get_flip_scale(self): return self._flip_scale def set_flip_scale(self, checked): self._flip_scale = bool(checked) self.adjust_transformation() self.repaint() def get_inverted_appearance(self): return self._inverted_appearance def set_inverted_appearance(self, inverted): self._inverted_appearance = inverted self.adjust_transformation() self.repaint() def get_bar_indicator(self): return self._barIndicator def set_bar_indicator(self, checked): if self._barIndicator != bool(checked): self._barIndicator = checked self.repaint() def get_background_color(self): return self._bg_color def set_background_color(self, color): self._bg_color = color self.repaint() def get_indicator_color(self): return self._indicator_color def set_indicator_color(self, color): self._indicator_color = color self.repaint() def get_tick_color(self): return self._tick_color def set_tick_color(self, color): self._tick_color = color self.repaint() def get_background_size_rate(self): return self._bg_size_rate def set_background_size_rate(self, rate): if rate >= 0 and rate <=1 and self._bg_size_rate != rate: self._bg_size_rate = rate self.repaint() def get_tick_size_rate(self): return self._tick_size_rate def set_tick_size_rate(self, rate): if rate >= 0 and rate <=1 and self._tick_size_rate != rate: self._tick_size_rate = rate self.repaint() def get_num_divisions(self): return self._num_divisions def set_num_divisions(self, divisions): if isinstance(divisions, int) and divisions > 0 and self._num_divisions != divisions: self._num_divisions = divisions self.repaint() def get_scale_height(self): return self._scale_height def set_scale_height(self, value): self._scale_height = int(value) self.adjust_transformation() self.repaint() def get_origin_at_zero(self): return self._origin_at_zero def set_origin_at_zero(self, checked): if self._origin_at_zero != bool(checked): self._origin_at_zero = checked self.repaint()