def paintEvent(self, event): """Using a QPainter under 'self', so just change QPen or QBrush before painting. """ self.painter = QPainter() self.painter.begin(self) self.painter.fillRect(event.rect(), QBrush(Qt.white)) self.painter.translate(self.ox, self.oy) #Draw origin lines. pen = QPen(Qt.gray) pen.setWidth(1) 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)) #Draw tick. Indexing = lambda v: int(v/self.zoom - (v/self.zoom)%5) for x in range(Indexing(x_l), Indexing(x_r)+1, 5): self.painter.drawLine( QPointF(x*self.zoom, 0), QPointF(x*self.zoom, -10 if x%10==0 else -5) ) for y in range(Indexing(y_b), Indexing(y_t)+1, 5): self.painter.drawLine( QPointF(0, y*self.zoom), QPointF(10 if y%10==0 else 5, y*self.zoom) ) """Please to call the "end" method when ending paint event.
def drawSolution( self, func: str, args: Sequence[str], target: str, pos: Union[Tuple[VPoint, ...], Dict[int, Tuple[float, float]]] ): """Draw the solution triangle.""" points, color = self.solutionPolygon(func, args, target, pos) color.setAlpha(150) pen = QPen(color) pen.setWidth(self.joint_size) self.painter.setPen(pen) def draw_arrow(index: int, text: str): """Draw arrow.""" self.__draw_arrow( points[-1].x(), points[-1].y(), points[index].x(), points[index].y(), text=text ) draw_arrow(0, args[1]) if func == 'PLLP': draw_arrow(1, args[2]) color.setAlpha(30) self.painter.setBrush(QBrush(color)) self.painter.drawPolygon(QPolygonF(points)) self.painter.setBrush(Qt.NoBrush)
def draw_point(self, i: int, cx, cy, fix: bool, color: Tuple[int, int, int]): """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 fix: bottom = y + 20 width = 10 # Draw a triangle below. self.painter.drawPolygon(QPointF(x, y), QPointF(x - width, bottom), QPointF(x + width, bottom)) r = self.joint_size * 2 else: r = self.joint_size self.painter.drawEllipse(QPointF(x, y), r, r) if not self.show_point_mark: return pen.setColor(Qt.darkGray) pen.setWidth(2) self.painter.setPen(pen) text = f"[{i}]" if type(i) is str else f"[Point{i}]" if self.show_dimension: text += f":({cx:.02f}, {cy:.02f})" self.painter.drawText(QPointF(x, y) + QPointF(6, -6), text)
def __drawSlvsRanges(self): """Draw solving range.""" pen = QPen() self.painter.setFont(QFont("Arial", self.fontSize + 5)) pen.setWidth(5) for i, (tag, rect) in enumerate(self.ranges.items()): range_color = QColor(colorNum(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(cx, cy, rect.width() * self.zoom, rect.height() * self.zoom)) else: self.painter.drawEllipse(QPointF(cx, cy), 3, 3) range_color.setAlpha(255) pen.setColor(range_color) self.painter.setPen(pen) self.painter.drawText(QPointF(cx + 6, cy - 6), tag) self.painter.setBrush(Qt.NoBrush)
def drawPoint(self, i: int, cx, cy, fix: bool, color: QColor ): """Draw a joint.""" pen = QPen(color) pen.setWidth(2) self.painter.setPen(pen) x = cx*self.zoom y = cy*-self.zoom if fix: bottom = y + 20 width = 10 #Draw a triangle below. self.painter.drawPolygon( QPointF(x, y), QPointF(x - width, bottom), QPointF(x + width, bottom) ) self.painter.drawEllipse(QPointF(x, y), width, width) else: self.painter.drawEllipse(QPointF(x, y), 5, 5) if not self.showPointMark: return pen.setColor(Qt.darkGray) pen.setWidth(2) self.painter.setPen(pen) self.painter.setFont(QFont("Arial", self.fontSize)) text = "[{}]".format(i) if type(i)==str else "[Point{}]".format(i) if self.showDimension: text += ":({:.02f}, {:.02f})".format(cx, cy) self.painter.drawText(QPointF(x+6, y-6), text)
def __drawLink(self, vlink: VLink): """Draw a link.""" points = [] for i in vlink.points: vpoint = self.Points[i] if vpoint.type == 1 or vpoint.type == 2: coordinate = vpoint.c[0 if (vlink.name == vpoint.links[0]) else 1] x = coordinate[0] * self.zoom y = coordinate[1] * -self.zoom else: x = vpoint.cx * self.zoom y = vpoint.cy * -self.zoom points.append((x, y)) pen = QPen(vlink.color) pen.setWidth(self.linkWidth) self.painter.setPen(pen) brush = QColor(226, 219, 190) brush.setAlphaF(self.transparency) self.painter.setBrush(brush) #Rearrange: Put the nearest point to the next position. qpoints = convex_hull(points) if qpoints: self.painter.drawPolygon(*qpoints) self.painter.setBrush(Qt.NoBrush) if ((not self.showPointMark) or (vlink.name == 'ground') or (not qpoints)): return pen.setColor(Qt.darkGray) self.painter.setPen(pen) cenX = sum(p[0] for p in points) / len(points) cenY = sum(p[1] for p in points) / len(points) self.painter.drawText(QPointF(cenX, cenY), '[{}]'.format(vlink.name))
def drawLink(self, name: str, points: Tuple[int]): """Draw linkage function. The link color will be the default color. """ color = colorQt('Blue') pen = QPen(color) pen.setWidth(self.linkWidth) self.painter.setPen(pen) brush = QColor(226, 219, 190) brush.setAlphaF(0.70) self.painter.setBrush(brush) qpoints = tuple( QPointF(self.Point[i][0] * self.zoom, self.Point[i][1] * -self.zoom) for i in points if self.Point[i] and not isnan(self.Point[i][0])) if len(qpoints) == len(points): self.painter.drawPolygon(*qpoints) self.painter.setBrush(Qt.NoBrush) if self.showPointMark and name != 'ground' and qpoints: pen.setColor(Qt.darkGray) self.painter.setPen(pen) self.painter.setFont(QFont('Arial', self.fontSize)) text = "[{}]".format(name) cenX = sum(self.Point[i][0] for i in points if self.Point[i]) cenY = sum(self.Point[i][1] for i in points if self.Point[i]) cenX *= self.zoom / len(points) cenY *= -self.zoom / len(points) self.painter.drawText(QPointF(cenX, cenY), text)
def __drawPath(self): """Draw paths. Recording first.""" pen = QPen() if self.autoPathShow and self.rightInput(): """Replace to auto preview path.""" exprs = self.getTriangle(self.Points) self.Path.path = expr_path( exprs, {n: 'P{}'.format(n) for n in range(len(self.Points))}, self.Points, self.pathInterval()) if self.solutionShow: for expr in exprs: self._BaseCanvas__drawSolution(expr[0], expr[1:-1], expr[-1], self.Points) if hasattr(self, 'path_record'): paths = self.path_record else: paths = self.Path.path for i, path in enumerate(paths): if ((self.Path.show != i) and (self.Path.show != -1) or (len(path) <= 1)): continue try: color = self.Points[i].color except: color = colorQt('Green') pen.setColor(color) pen.setWidth(self.pathWidth) self.painter.setPen(pen) if self.Path.curve: self._BaseCanvas__drawCurve(path) else: self._BaseCanvas__drawDot(path)
def __draw_path(self): """Draw paths. Recording first.""" paths = self.path_record or self.path.path or self.path_preview if len(self.vpoints) != len(paths): return if paths is self.path_preview: o_path = chain(enumerate(self.path_preview), self.slider_path_preview.items()) else: o_path = enumerate(paths) pen = QPen() for i, path in o_path: 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_link(self, name: str, points: List[int]): """Draw link function. The link color will be the default color. """ color = color_qt('Blue') pen = QPen(color) pen.setWidth(self.link_width) self.painter.setPen(pen) brush = QColor(226, 219, 190) 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 != 'ground') and qpoints: pen.setColor(Qt.darkGray) self.painter.setPen(pen) self.painter.setFont(QFont('Arial', self.font_size)) text = f"[{name}]" 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), text)
def drawSolution(self, func: str, args: Tuple[str], target: str): """Draw the solution triangle.""" params = [args[0], args[-1]] params.append(target) if func == 'PLLP': color = QColor(121, 171, 252) else: color = QColor(249, 84, 216) color.setAlpha(255) pen = QPen() pen.setColor(color) pen.setWidth(self.r) self.painter.setPen(pen) for n in (0, 1): x, y = self.pos[int(params[-1].replace('P', ''))] x2, y2 = self.pos[int(params[n].replace('P', ''))] self.drawArrow( x*self.zoom, y*-self.zoom, x2*self.zoom, y2*-self.zoom ) color.setAlpha(30) self.painter.setBrush(QBrush(color)) qpoints = [] for name in params: x, y = self.pos[int(name.replace('P', ''))] qpoints.append(QPointF(x*self.zoom, y*-self.zoom)) self.painter.drawPolygon(*qpoints)
def __draw_path(self): """Draw paths. Recording first.""" paths = self.path_record or self.Path.path or self.pathpreview if len(self.vpoints) != len(paths): return if paths == self.pathpreview: o_path = chain(enumerate(self.pathpreview), self.sliderpathpreview.items()) else: o_path = enumerate(paths) pen = QPen() for i, path in o_path: if (self.Path.show != i) and (self.Path.show != -1): continue if self.vpoints[i].color: color = self.vpoints[i].color else: color = color_qt('Green') pen.setColor(color) pen.setWidth(self.path_width) self.painter.setPen(pen) if self.Path.curve: self.drawCurve(path) else: self.drawDot(path)
def drawTargetPath(self): """Draw solving path.""" pen = QPen() pen.setWidth(self.pathWidth) for i, name in enumerate(sorted(self.targetPath)): path = self.targetPath[name] Pen, Dot, Brush = colorPath(i) pen.setColor(Pen) self.painter.setPen(pen) self.painter.setBrush(Brush) if len(path)>1: pointPath = QPainterPath() for i, (x, y) in enumerate(path): x *= self.zoom y *= -self.zoom self.painter.drawEllipse(QPointF(x, y), 4, 4) if i==0: self.painter.drawText(QPointF(x+6, y-6), name) pointPath.moveTo(x, y) else: x2, y2 = path[i-1] self.drawArrow(x, y, x2*self.zoom, y2*-self.zoom) pointPath.lineTo(QPointF(x, y)) self.painter.drawPath(pointPath) for x, y in path: pen.setColor(Dot) self.painter.setPen(pen) self.painter.drawEllipse( QPointF(x*self.zoom, y*-self.zoom), 3, 3 ) elif len(path)==1: x = path[0][0]*self.zoom y = path[0][1]*-self.zoom self.painter.drawText(QPointF(x+6, y-6), name) pen.setColor(Dot) self.painter.setPen(pen) self.painter.drawEllipse(QPointF(x, y), 3, 3) self.painter.setBrush(Qt.NoBrush)
def graph(G: Graph, width: int, engine: [str, Dict[int, Tuple[float, float]]], node_mode: bool = False, except_node: int = None) -> QIcon: """Draw a linkage graph.""" try: pos = engine_picker(G, engine, node_mode) except EngineError as e: raise e width_ = -inf for x, y in pos.values(): if abs(x) > width_: width_ = x if abs(y) > width_: width_ = y width_ *= 2 * 1.2 image = QImage(QSize(width_, width_), QImage.Format_ARGB32_Premultiplied) image.fill(Qt.transparent) painter = QPainter(image) painter.translate(image.width() / 2, image.height() / 2) pen = QPen() r = width_ / 50 pen.setWidth(r) painter.setPen(pen) if node_mode: for l1, l2 in G.edges: painter.drawLine(QPointF(pos[l1][0], -pos[l1][1]), QPointF(pos[l2][0], -pos[l2][1])) else: painter.setBrush(QBrush(QColor(226, 219, 190, 150))) for link in G.nodes: if link == except_node: continue #Distance sorted function from canvas painter.drawPolygon(*convex_hull([(pos[n][0], -pos[n][1]) for n, edge in edges_view(G) if link in edge])) for k, (x, y) in pos.items(): if node_mode: color = colorNum(len(list(G.neighbors(k))) - 1) else: if except_node in tuple(G.edges)[k]: color = colorQt('Green') else: color = colorQt('Blue') pen.setColor(color) painter.setPen(pen) painter.setBrush(QBrush(color)) painter.drawEllipse(QPointF(x, -y), r, r) painter.end() icon = QIcon(QPixmap.fromImage(image).scaledToWidth(width)) return icon
def paintEvent(self, event): """Using a QPainter under 'self', so just change QPen or QBrush before painting. """ 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) img_origin: QPointF = self.background_offset * self.zoom self.painter.drawImage( QRectF(img_origin, QSizeF( rect.width() * self.background_scale * self.zoom, 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. 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): """Draw tick.""" return int(v / self.zoom - v / self.zoom % 5) for x in range(indexing(x_l), indexing(x_r) + 1, 5): self.painter.drawLine( QPointF(x, 0) * self.zoom, QPointF(x * self.zoom, -10 if x % 10 == 0 else -5) ) for y in range(indexing(y_b), indexing(y_t) + 1, 5): self.painter.drawLine( QPointF(0, y) * self.zoom, QPointF(10 if y % 10 == 0 else 5, y * self.zoom) )
def __draw_path(self): """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 __draw_path(self): """Draw a path. A simple function than main canvas. """ pen = QPen() for i, path in enumerate(self.Path.path): color = color_qt('Green') if self.exp_symbol[i] in self.mechanism['Target']: color = color_qt('Dark-Orange') pen.setColor(color) pen.setWidth(self.path_width) self.painter.setPen(pen) self.drawCurve(path)
def draw_slvs_ranges(self): """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.painter.drawEllipse(QPointF(cx, cy), 3, 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 __drawSolution(self, func: str, args: Tuple[str], target: str, pos: TypeVar('Coords', Tuple[VPoint], Dict[int, Tuple[float, float]])): """Draw the solution triangle.""" if func == 'PLLP': color = QColor(121, 171, 252) params = [args[0], args[-1]] elif func == 'PLAP': color = QColor(249, 84, 216) params = [args[0]] elif func == 'PLPP': color = QColor(94, 255, 185) params = [args[0]] params.append(target) pen = QPen() pen.setColor(color) pen.setWidth(RADIUS) self.painter.setPen(pen) def drawArrow(n: int) -> bool: """Draw arrow and return True if done.""" try: x, y = pos[int(params[-1].replace('P', ''))] x2, y2 = pos[int(params[n].replace('P', ''))] except ValueError: return False else: self.__drawArrow(x * self.zoom, y * -self.zoom, x2 * self.zoom, y2 * -self.zoom) return True if not drawArrow(0): return if func == 'PLLP': if not drawArrow(1): return color.setAlpha(30) self.painter.setBrush(QBrush(color)) qpoints = [] for name in params: x, y = pos[int(name.replace('P', ''))] qpoints.append(QPointF(x * self.zoom, y * -self.zoom)) self.painter.drawPolygon(*qpoints) self.painter.setBrush(Qt.NoBrush)
def drawPath(self): """Draw paths. Recording first.""" pen = QPen() if hasattr(self, 'PathRecord'): Path = self.PathRecord else: Path = self.Path.path for i, path in enumerate(Path): if self.Path.show != i and self.Path.show != -1: continue if len(set(path)) > 1: try: color = self.Point[i].color except: color = colorQt('Green') pen.setColor(color) pen.setWidth(self.pathWidth) self.painter.setPen(pen) if self.Path.curve: self.drawCurve(path) else: self.drawDot(path)
def to_graph(graph: Graph, width: int, engine: Union[str, Dict[int, Tuple[float, float]]], node_mode: bool = False, except_node: int = None) -> QIcon: """Draw a generalized chain graph.""" pos: Pos = engine_picker(graph, engine, node_mode) width_bound = -float('inf') for x, y in pos.values(): if abs(x) > width_bound: width_bound = x if abs(y) > width_bound: width_bound = y width_bound *= 2.2 image = QImage(QSize(int(width_bound), int(width_bound)), QImage.Format_ARGB32_Premultiplied) image.fill(Qt.transparent) painter = QPainter(image) painter.translate(image.width() / 2, image.height() / 2) pen = QPen() r = width_bound / 50 pen.setWidth(int(r)) painter.setPen(pen) # Draw edges. if node_mode: for l1, l2 in graph.edges: if except_node in {l1, l2}: pen.setColor(color_qt('Gray')) else: pen.setColor(color_qt('Black')) painter.setPen(pen) painter.drawLine(QPointF(pos[l1][0], -pos[l1][1]), QPointF(pos[l2][0], -pos[l2][1])) else: painter.setBrush(QBrush(QColor(226, 219, 190, 150))) for link in graph.nodes: if link == except_node: pen.setColor(color_qt('Gray')) else: pen.setColor(color_qt('Black')) painter.setPen(pen) painter.drawPolygon(*convex_hull([(pos[n][0], -pos[n][1]) for n, edge in edges_view(graph) if link in edge], as_qpoint=True)) # Draw nodes. for k, (x, y) in pos.items(): if node_mode: color = color_num(len(list(graph.neighbors(k))) - 1) if k == except_node: color.setAlpha(150) else: if except_node in dict(edges_view(graph))[k]: color = color_qt('Green') else: color = color_qt('Blue') pen.setColor(color) painter.setPen(pen) painter.setBrush(QBrush(color)) painter.drawEllipse(QPointF(x, -y), r, r) painter.end() icon = QIcon(QPixmap.fromImage(image).scaledToWidth(width)) return icon
def __draw_point(self, i: int, vpoint: VPoint): """Draw a point.""" if vpoint.type in {VJoint.P, VJoint.RP}: pen = QPen(QColor(*vpoint.color)) pen.setWidth(2) # Draw slot point and pin point. for j, (cx, cy) in enumerate(vpoint.c): if not vpoint.links: grounded = False else: grounded = vpoint.links[j] == 'ground' # Slot point. if j == 0 or vpoint.type == VJoint.P: pen.setColor(Qt.black if self.monochrome else QColor( *vpoint.color)) self.painter.setPen(pen) cp = QPointF(cx, -cy) * self.zoom jr = self.joint_size * (2 if j == 0 else 1) rp = QPointF(jr, -jr) self.painter.drawRect(QRectF(cp + rp, cp - rp)) if self.show_point_mark: pen.setColor(Qt.darkGray) self.painter.setPen(pen) text = f"[Point{i}]" if self.show_dimension: text += f":({cx:.02f}, {cy:.02f})" self.painter.drawText(cp + rp, text) else: self.draw_point(i, cx, cy, grounded, vpoint.color) # Slider line pen.setColor(QColor(*vpoint.color).darker()) self.painter.setPen(pen) qline_m = QLineF( QPointF(vpoint.c[1][0], -vpoint.c[1][1]) * self.zoom, QPointF(vpoint.c[0][0], -vpoint.c[0][1]) * self.zoom) nv = qline_m.normalVector() nv.setLength(self.joint_size) nv.setPoints(nv.p2(), nv.p1()) qline_1 = nv.normalVector() qline_1.setLength(qline_m.length()) self.painter.drawLine(qline_1) nv.setLength(nv.length() * 2) nv.setPoints(nv.p2(), nv.p1()) qline_2 = nv.normalVector() qline_2.setLength(qline_m.length()) qline_2.setAngle(qline_2.angle() + 180) self.painter.drawLine(qline_2) else: self.draw_point(i, vpoint.cx, vpoint.cy, vpoint.grounded(), vpoint.color) # For selects function. if self.select_mode == SelectMode.Joint and (i in self.selections): pen = QPen(QColor(161, 16, 239)) pen.setWidth(3) self.painter.setPen(pen) self.painter.drawRect(vpoint.cx * self.zoom - 12, vpoint.cy * -self.zoom - 12, 24, 24)
def __draw_link(self, vlink: VLink): """Draw a link.""" if vlink.name == 'ground' 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 QColor( 226, 219, 190) 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): """Drawing functions.""" width = self.width() height = self.height() if self.width_old is None: self.width_old = width if self.height_old is None: self.height_old = height if self.width_old != width or self.height_old != height: self.ox += (width - self.width_old) / 2 self.oy += (height - self.height_old) / 2 # 'self' is the instance of 'DynamicCanvas'. BaseCanvas.paintEvent(self, event) # Draw links except ground. for vlink in self.vlinks[1:]: self.__draw_link(vlink) # Draw path. if self.path.show != -2: self.__draw_path() # Draw solving path. if self.show_target_path: self.painter.setFont(QFont("Arial", self.font_size + 5)) self.draw_slvs_ranges() self.draw_target_path() self.painter.setFont(QFont("Arial", self.font_size)) # Draw points. for i, vpoint in enumerate(self.vpoints): self.__draw_point(i, vpoint) # Draw solutions. if self.select_mode == SelectMode.Solution: for i, expr in enumerate(self.exprs): func = expr[0] params = expr[1:-1] target = expr[-1] self.draw_solution(func, params, target, self.vpoints) if i in self.selections: pos, _ = self.solution_polygon(func, params, target, self.vpoints) pen = QPen() pen.setWidth(self.link_width + 3) pen.setColor(QColor(161, 16, 239)) self.painter.setPen(pen) self.painter.drawPolygon(QPolygonF(pos)) # Draw a colored frame for free move mode. if self.free_move != FreeMode.NoFreeMove: pen = QPen() if self.free_move == FreeMode.Translate: pen.setColor(QColor(161, 16, 229)) elif self.free_move == FreeMode.Rotate: pen.setColor(QColor(219, 162, 6)) elif self.free_move == FreeMode.Reflect: pen.setColor(QColor(79, 249, 193)) pen.setWidth(8) self.painter.setPen(pen) self.__draw_frame() # Rectangular selection if self.selector.picking: pen = QPen(Qt.gray) pen.setWidth(1) self.painter.setPen(pen) self.painter.drawRect(self.selector.to_rect(self.zoom)) # Show FPS self.fps_updated.emit() self.painter.end() # Record the widget size. self.width_old = width self.height_old = height
def __drawPoint(self, i: int, vpoint: VPoint): """Draw a point.""" if vpoint.type == 1 or vpoint.type == 2: #Draw slider silder_points = vpoint.c for j, (cx, cy) in enumerate(silder_points): if vpoint.type == 1: if j == 0: self._BaseCanvas__drawPoint( i, cx, cy, vpoint.links[j] == 'ground', vpoint.color) else: pen = QPen(vpoint.color) pen.setWidth(2) self.painter.setPen(pen) r = 5 self.painter.drawRect( QRectF( QPointF(cx * self.zoom + r, cy * -self.zoom + r), QPointF(cx * self.zoom - r, cy * -self.zoom - r))) elif vpoint.type == 2: if j == 0: self._BaseCanvas__drawPoint( i, cx, cy, vpoint.links[j] == 'ground', vpoint.color) else: #Turn off point mark. showPointMark = self.showPointMark self.showPointMark = False self._BaseCanvas__drawPoint( i, cx, cy, vpoint.links[j] == 'ground', vpoint.color) self.showPointMark = showPointMark pen = QPen(vpoint.color.darker()) pen.setWidth(2) self.painter.setPen(pen) x_all = tuple(cx for cx, cy in silder_points) if x_all: p_left = silder_points[x_all.index(min(x_all))] p_right = silder_points[x_all.index(max(x_all))] if p_left == p_right: y_all = tuple(cy for cx, cy in silder_points) p_left = silder_points[y_all.index(min(y_all))] p_right = silder_points[y_all.index(max(y_all))] self.painter.drawLine( QPointF(p_left[0] * self.zoom, p_left[1] * -self.zoom), QPointF(p_right[0] * self.zoom, p_right[1] * -self.zoom)) else: self._BaseCanvas__drawPoint(i, vpoint.cx, vpoint.cy, vpoint.grounded(), vpoint.color) #For selects function. if i in self.pointsSelection: pen = QPen(QColor(161, 16, 239)) pen.setWidth(3) self.painter.setPen(pen) self.painter.drawRect(vpoint.cx * self.zoom - 12, vpoint.cy * -self.zoom - 12, 24, 24)
def paintEvent(self, event): """Drawing functions.""" width = self.width() height = self.height() if ((self.width_old is not None) and ((self.width_old != width) or (self.height_old != height))): self.ox += (width - self.width_old) / 2 self.oy += (height - self.height_old) / 2 super(DynamicCanvas, self).paintEvent(event) self.painter.setFont(QFont('Arial', self.fontSize)) if self.freemove != FreeMode.NoFreeMove: #Draw a colored frame for free move mode. pen = QPen() if self.freemove == FreeMode.Translate: pen.setColor(QColor(161, 105, 229)) elif self.freemove == FreeMode.Rotate: pen.setColor(QColor(219, 162, 6)) elif self.freemove == FreeMode.Reflect: pen.setColor(QColor(79, 249, 193)) pen.setWidth(8) self.painter.setPen(pen) self.__drawFrame() #Draw links except ground. for vlink in self.Links[1:]: self.__drawLink(vlink) #Draw path. if self.Path.show != -2: self.__drawPath() #Draw solving path. if self.showTargetPath: self.__drawSlvsRanges() self._BaseCanvas__drawTargetPath() #Draw points. for i, vpoint in enumerate(self.Points): self.__drawPoint(i, vpoint) #Rectangular selection if self.Selector.RectangularSelection: pen = QPen(Qt.gray) pen.setWidth(1) self.painter.setPen(pen) self.painter.drawRect( QRectF(QPointF(self.Selector.x, self.Selector.y), QPointF(self.Selector.sx, self.Selector.sy))) self.painter.end() #Record the widget size. self.width_old = width self.height_old = height
def paintEvent(self, event): """Drawing functions.""" width = self.width() height = self.height() if self.width_old != width or self.height_old != height: self.ox += (width - self.width_old) / 2 self.oy += (height - self.height_old) / 2 super(DynamicCanvas, self).paintEvent(event) self.painter.setFont(QFont('Arial', self.fontSize)) if self.freemove: #Draw a colored frame for free move mode. pen = QPen() if self.freemove == 1: pen.setColor(QColor(161, 105, 229)) elif self.freemove == 2: pen.setColor(QColor(219, 162, 6)) elif self.freemove == 3: pen.setColor(QColor(79, 249, 193)) pen.setWidth(8) self.painter.setPen(pen) self.drawFrame() if self.Selector.RectangularSelection: pen = QPen(Qt.gray) pen.setWidth(1) self.painter.setPen(pen) self.painter.drawRect( QRectF(QPointF(self.Selector.x, self.Selector.y), QPointF(self.Selector.sx, self.Selector.sy))) #Draw links. for vlink in self.Link[1:]: self.drawLink(vlink) #Draw path. if self.Path.show > -2: self.drawPath() #Draw solving path. if self.showTargetPath: self.drawSlvsRanges() self.drawTargetPath() #Draw points. for i, vpoint in enumerate(self.Point): self.drawPoint(i, vpoint) self.painter.end() self.width_old = width self.height_old = height
def paintEvent(self, event): """Draw the structure.""" width = self.width() height = self.height() if self.pos: x_right, x_left, y_top, y_bottom = self.__zoom_to_fit_limit() x_diff = x_left - x_right y_diff = y_top - y_bottom x_diff = x_diff if x_diff else 1 y_diff = y_diff if y_diff else 1 if width / x_diff < height / y_diff: factor = width / x_diff else: factor = height / y_diff self.zoom = factor * 0.95 self.ox = width / 2 - (x_left + x_right) / 2 * self.zoom self.oy = height / 2 + (y_top + y_bottom) / 2 * self.zoom else: sq_w = 240 self.zoom = (width / sq_w) if (width <= height) else (height / sq_w) self.ox = width / 2 self.oy = height / 2 super(PreviewCanvas, self).paintEvent(event) pen = QPen() pen.setWidth(self.joint_size) self.painter.setPen(pen) self.painter.setBrush(QBrush(QColor(226, 219, 190, 150))) # Links for link in self.G.nodes: if link == self.grounded: continue points = [] # Points that is belong with the link. for num, edge in edges_view(self.G): if link in edge: if num in self.same: num = self.same[num] x, y = self.pos[num] points.append((x * self.zoom, y * -self.zoom)) # Customize points. for name, link_ in self.cus.items(): if link == link_: x, y = self.pos[int(name.replace('P', ''))] points.append((x * self.zoom, y * -self.zoom)) self.painter.drawPolygon(*convex_hull(points, as_qpoint=True)) # Nodes for node, (x, y) in self.pos.items(): if node in self.same: continue x *= self.zoom y *= -self.zoom if node in (self.Driver, self.Target): if node == self.Driver: pen.setColor(color_qt('Red')) elif node == self.Target: pen.setColor(color_qt('Yellow')) self.painter.setPen(pen) self.painter.drawEllipse(QPointF(x, y), self.joint_size, self.joint_size) if self.getStatus(node): color = color_qt('Dark-Magenta') else: color = color_qt('Green') pen.setColor(color) self.painter.setPen(pen) self.painter.setBrush(QBrush(color)) self.painter.drawEllipse(QPointF(x, y), self.joint_size, self.joint_size) pen.setColor(color_qt('Black')) self.painter.setPen(pen) # Solutions if self.showSolutions: solutions = self.get_solutions() if solutions: for expr in solutions.split(';'): self.drawSolution( io.str_before(expr, '['), io.str_between(expr, '[', ']').split(','), io.str_between(expr, '(', ')'), self.pos ) # Text of node. pen.setColor(Qt.black) self.painter.setPen(pen) for node, (x, y) in self.pos.items(): if node in self.same: continue x *= self.zoom x += 2 * self.joint_size y *= -self.zoom y -= 2 * self.joint_size self.painter.drawText(QPointF(x, y), f'P{node}') self.painter.end()
def paintEvent(self, event): """Draw the structure.""" width = self.width() height = self.height() if self.pos: x_right, x_left, y_top, y_bottom = self.__zoom_to_fit_limit() x_diff = x_left - x_right y_diff = y_top - y_bottom x_diff = x_diff if x_diff else 1 y_diff = y_diff if y_diff else 1 if width / x_diff < height / y_diff: factor = width / x_diff else: factor = height / y_diff self.zoom = factor * 0.75 self.ox = width / 2 - (x_left + x_right) / 2 * self.zoom self.oy = height / 2 + (y_top + y_bottom) / 2 * self.zoom else: if width <= height: self.zoom = width / PreviewCanvas.view_size else: self.zoom = height / PreviewCanvas.view_size self.ox = width / 2 self.oy = height / 2 super(PreviewCanvas, self).paintEvent(event) pen = QPen() pen.setWidth(self.joint_size) self.painter.setPen(pen) if self.monochrome: color = QColor(Qt.darkGray) else: color = QColor(226, 219, 190) color.setAlpha(150) self.painter.setBrush(QBrush(color)) # Links for link in self.G.nodes: if link == self.grounded: continue points = [] # Points that is belong with the link. for num, edge in edges_view(self.G): if link in edge: if num in self.same: num = self.same[num] x, y = self.pos[num] points.append((x * self.zoom, y * -self.zoom)) # Customize points. for name, link_ in self.cus.items(): if link == link_: x, y = self.pos[name] points.append((x * self.zoom, y * -self.zoom)) self.painter.drawPolygon(*convex_hull(points, as_qpoint=True)) # Nodes for node, (x, y) in self.pos.items(): if node in self.same: continue x *= self.zoom y *= -self.zoom if self.monochrome: color = Qt.black elif node in self.driver: color = color_qt('Red') elif node in self.target: color = color_qt('Orange') elif self.get_status(node): color = color_qt('Green') else: color = color_qt('Blue') pen.setColor(color) self.painter.setPen(pen) self.painter.setBrush(QBrush(color)) self.painter.drawEllipse(QPointF(x, y), self.joint_size, self.joint_size) pen.setColor(Qt.black) self.painter.setPen(pen) # Text of node. pen.setColor(Qt.black) self.painter.setPen(pen) for node, (x, y) in self.pos.items(): if node in self.same: continue x *= self.zoom x += 2 * self.joint_size y *= -self.zoom y -= 2 * self.joint_size self.painter.drawText(QPointF(x, y), f'P{node}') self.painter.end()
def drawTargetPath(self): """Draw solving path.""" pen = QPen() pen.setWidth(self.path_width) for i, name in enumerate(sorted(self.target_path)): path = self.target_path[name] road, dot, brush = target_path_style(i) pen.setColor(road) self.painter.setPen(pen) self.painter.setBrush(brush) if len(path) == 1: x, y = path[0] p = QPointF(x, -y) * self.zoom self.painter.drawText(p + QPointF(6, -6), name) pen.setColor(dot) self.painter.setPen(pen) self.painter.drawEllipse(p, self.joint_size, self.joint_size) else: painter_path = QPainterPath() for j, (x, y) in enumerate(path): p = QPointF(x, -y) * self.zoom self.painter.drawEllipse(p, self.joint_size, self.joint_size) if j == 0: self.painter.drawText(p + QPointF(6, -6), name) painter_path.moveTo(p) else: x2, y2 = path[j - 1] self.__draw_arrow(x, -y, x2, -y2, zoom=True) painter_path.lineTo(p) pen.setColor(road) self.painter.setPen(pen) self.painter.drawPath(painter_path) for x, y in path: pen.setColor(dot) self.painter.setPen(pen) p = QPointF(x, -y) * self.zoom self.painter.drawEllipse(p, self.joint_size, self.joint_size) self.painter.setBrush(Qt.NoBrush)