def build_paths(self): """ """ geo = self.geometry() radius = 30 shadow = self.offset_shadow x0, y0 = geo.x(), geo.y() width, height = geo.width() - shadow, geo.height() - shadow left, top = 0, 0 right, bottom = width, height self.round_rect_path = QPainterPath() self.round_rect_path.moveTo(right, top + radius) self.round_rect_path.arcTo(right - radius, top, radius, radius, 0.0, 90.0) self.round_rect_path.lineTo(left + radius, top) self.round_rect_path.arcTo(left, top, radius, radius, 90.0, 90.0) self.round_rect_path.lineTo(left, bottom - radius) self.round_rect_path.arcTo(left, bottom - radius, radius, radius, 180.0, 90.0) self.round_rect_path.lineTo(right - radius, bottom) self.round_rect_path.arcTo(right - radius, bottom - radius, radius, radius, 270.0, 90.0) self.round_rect_path.closeSubpath() # Top path header = 36 offset = 2 left, top = offset, offset right = width - (offset) self.top_rect_path = QPainterPath() self.top_rect_path.lineTo(right, top + radius) self.top_rect_path.moveTo(right, top + radius) self.top_rect_path.arcTo(right - radius, top, radius, radius, 0.0, 90.0) self.top_rect_path.lineTo(left + radius, top) self.top_rect_path.arcTo(left, top, radius, radius, 90.0, 90.0) self.top_rect_path.lineTo(left, top + header) self.top_rect_path.lineTo(right, top + header)
def __init__(self, connection, parent): super().__init__() self._connection = connection self._source_ui = self._find_ui(parent, connection.source.connector) self._sink_ui = self._find_ui(parent, connection.sink.connector) self.avoid_conn = None self._duplicate_is = None self._duplicate_of = None self._switch_direction_count = 1 self.path = QPainterPath() self.stroker_path = QPainterPath() self.stroker = QPainterPathStroker() self.stroker.setWidth(8) self.update_endpoints() self.setZValue(-10) self.arrow = QGraphicsPolygonItem() self._set_default_appearance() self.setFlag(self.ItemIsFocusable) self._ports_item = Connection_Ports_Item() self._ports_item.setParentItem(self) self._timer = QTimer(self.scene()) self._timer.setSingleShot(True) self._timer.setSingleShot(True) self._timer.timeout.connect(self._start_hover) self._hover_pos = 0, 0 self.set_show_connection_ports_on_hover(False)
def setData( self, x, height, width=0.8, bottom=None, *, align="center", fillcolor=None, edgecolor=None, ) -> None: # assume vertical cbook._check_in_list(["center", "edge"], align=align) y = bottom if y is None: y = 0 x, height, width, y = np.broadcast_arrays(np.atleast_1d(x), height, width, y) if align == "center": try: left = x - width / 2 except TypeError as e: raise TypeError( f"the dtypes of parameters x ({x.dtype}) " f"and width ({width.dtype}) " f"are incompatible" ) from e elif align == "edge": left = x else: raise RuntimeError(f"unknown align mode {align}") bottom = y # prepare to draw if edgecolor is None: edgecolor = (128, 128, 128) # getConfigOption("foreground") pen = mkPen(edgecolor) if fillcolor is None: fillcolor = (128, 128, 128) brush = mkBrush(fillcolor) self.qpicture = QPicture() self.path = QPainterPath() p = QPainter(self.qpicture) p.setPen(pen) p.setBrush(brush) # draw rects = zip(left, bottom, width, height) for l, b, w, h in rects: rect = QRectF(l, b, w, h) p.drawRect(rect) self.path.addRect(rect) p.end() self.prepareGeometryChange()
def __drawVertical(self, widget, option, painter, size, width): # drop between y_pos = option.rect.topLeft().y() if option.rect.height() == 0: # create indicators l_indicator = self.createTriangle(size, attrs.EAST) l_indicator.translate(QPoint(size + (width / 2), y_pos)) r_indicator = self.createTriangle(size, attrs.WEST) r_indicator.translate( QPoint(widget.width() - size - (width / 2), y_pos)) # draw painter.drawPolygon(l_indicator) painter.drawPolygon(r_indicator) painter.drawLine( QPoint(size + (width / 2), y_pos), QPoint(widget.width() - size - (width / 2), y_pos)) # set fill color background_color = QColor(*iColor["rgba_gray_1"]) brush = QBrush(background_color) path = QPainterPath() path.addPolygon(l_indicator) path.addPolygon(r_indicator) painter.fillPath(path, brush) # drop on else: indicator_rect = QRect((width / 2), y_pos, widget.width() - (width / 2), option.rect.height()) painter.drawRoundedRect(indicator_rect, 1, 1)
def paintEvent(self, event): painter = QPainter(self) painter.setClipRegion(event.region()) if ( self.testPaintAttribute(self.BackingStore) and self.__data.backingStore is not None ): bs = self.__data.backingStore if QT_MAJOR_VERSION >= 5: pixelRatio = bs.devicePixelRatio() else: pixelRatio = 1.0 if bs.size() != self.size() * pixelRatio: bs = QwtPainter.backingStore(self, self.size()) if self.testAttribute(Qt.WA_StyledBackground): p = QPainter(bs) qwtFillBackground(p, self) self.drawCanvas(p, True) else: p = QPainter() if self.__data.borderRadius <= 0.0: # print('**DEBUG: QwtPlotCanvas.paintEvent') QwtPainter.fillPixmap(self, bs) p.begin(bs) self.drawCanvas(p, False) else: p.begin(bs) qwtFillBackground(p, self) self.drawCanvas(p, True) if self.frameWidth() > 0: self.drawBorder(p) p.end() painter.drawPixmap(0, 0, self.__data.backingStore) else: if self.testAttribute(Qt.WA_StyledBackground): if self.testAttribute(Qt.WA_OpaquePaintEvent): qwtFillBackground(painter, self) self.drawCanvas(painter, True) else: self.drawCanvas(painter, False) else: if self.testAttribute(Qt.WA_OpaquePaintEvent): if self.autoFillBackground(): qwtFillBackground(painter, self) qwtDrawBackground(painter, self) else: if self.borderRadius() > 0.0: clipPath = QPainterPath() clipPath.addRect(self.rect()) clipPath = clipPath.subtracted(self.borderPath(self.rect())) painter.save() painter.setClipPath(clipPath, Qt.IntersectClip) qwtFillBackground(painter, self) qwtDrawBackground(painter, self) painter.restore() self.drawCanvas(painter, False) if self.frameWidth() > 0: self.drawBorder(painter) if self.hasFocus() and self.focusIndicator() == self.CanvasFocusIndicator: self.drawFocusIndicator(painter)
def borderPath(self, rect): """ Calculate the painter path for a styled or rounded border When the canvas has no styled background or rounded borders the painter path is empty. :param QRect rect: Bounding rectangle of the canvas :return: Painter path, that can be used for clipping """ if self.testAttribute(Qt.WA_StyledBackground): recorder = QwtStyleSheetRecorder(rect.size()) painter = QPainter(recorder) opt = QStyleOption() opt.initFrom(self) opt.rect = rect self.style().drawPrimitive(QStyle.PE_Widget, opt, painter, self) painter.end() if not recorder.background.path.isEmpty(): return recorder.background.path if len(recorder.border.rectList) > 0: return qwtCombinePathList(rect, recorder.border.pathlist) elif self.__data.borderRadius > 0.0: fw2 = self.frameWidth() * 0.5 r = QRectF(rect).adjusted(fw2, fw2, -fw2, -fw2) path = QPainterPath() path.addRoundedRect(r, self.__data.borderRadius, self.__data.borderRadius) return path return QPainterPath()
def _makePath(self): self._path = QPainterPath() self._path.moveTo(self._xData[0], self._yData[0]) for k, idx in enumerate(self._xData): d = self._yData[k] self._path.lineTo(idx, d)
def __drawHorizontal(self, widget, option, painter, size, width): x_pos = option.rect.topLeft().x() if option.rect.width() == 0: # create indicators top_indicator = self.createTriangle(size, attrs.NORTH) top_indicator.translate(QPoint(x_pos, size + (width / 2))) bot_indicator = self.createTriangle(size, attrs.SOUTH) bot_indicator.translate( QPoint(x_pos, option.rect.height() - size - (width / 2))) # draw painter.drawPolygon(top_indicator) painter.drawPolygon(bot_indicator) painter.drawLine( QPoint(x_pos, size + (width / 2)), QPoint(x_pos, option.rect.height() - size + (width / 2))) # set fill color background_color = QColor(*iColor["rgba_gray_1"]) brush = QBrush(background_color) path = QPainterPath() path.addPolygon(top_indicator) path.addPolygon(bot_indicator) painter.fillPath(path, brush) # drop on else: painter.drawRoundedRect(option.rect, 1, 1)
def cubic_path(geom): source, sink = geom.source, geom.sink c1, c2 = geom.points_c1_c2() # cubic spline cubic = QPainterPath(source) cubic.cubicTo(c1, c2, sink) return cubic
def draw_icon(self, painter): path = QPainterPath(QPointF(0, 0)) path.lineTo(1, 1) path.lineTo(0.005, 1) path.lineTo(0.5, 0.5) path.lineTo(0, 0.9) path.closeSubpath() painter.drawPath(path) painter.drawEllipse(QPointF(0.5, 0.5), 0.05, 0.05)
def update_endpoints(self): self.x1, self.y1 = self._get_endpoint(self._source_ui) self.x2, self.y2 = self._get_endpoint(self._sink_ui) if self.x1 is None or self.x2 is None: return False self.path = QPainterPath() self.path.moveTo(self.x1, self.y1) self.path.lineTo(self.x2, self.y2) self.setPath(self.path) self._update_avoid() return True
def updatePosition(self, scene): path = QPainterPath() self.prepareGeometryChange() count = len(self._longitudes) if count > 0: x, y = scene.posFromLonLat(self._longitudes, self._latitudes) path.moveTo(x[0], y[0]) for i in iterRange(1, count): path.lineTo(x[i], y[i]) self.setPath(path)
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 draw_icon(self, painter): path = QPainterPath(QPointF(0, 0.3)) path.lineTo(0, 0.9) path.lineTo(1, 0.3) path.lineTo(1, 0.9) path.closeSubpath() painter.drawPath(path)
def draw_icon(self, painter): path = QPainterPath(QPointF(0, 0.3)) path.lineTo(0, 0.9) path.lineTo(1, 0.3) path.lineTo(1, 0.9) path.closeSubpath() painter.drawPath(path) prev_brush = painter.brush() prev_pen = painter.pen() painter.setPen(Qt.NoPen) painter.setBrush(self._arrow_brush) arrow = QPolygonF([ QPointF(0.2, 0), QPointF(0.2, 0.20), QPointF(0.5, 0.40), QPointF(0.8, 0.20), QPointF(0.8, 0) ]) painter.drawPolygon(arrow) painter.setPen(prev_pen) painter.setBrush(prev_brush) painter.drawLine(QPointF(0.2, 0), QPointF(0.5, 0.20)) painter.drawLine(QPointF(0.2, 0.20), QPointF(0.5, 0.40)) painter.drawLine(QPointF(0.5, 0.20), QPointF(0.8, 0)) painter.drawLine(QPointF(0.5, 0.40), QPointF(0.8, 0.20)) painter.drawLine(QPointF(0.5, 0.6), QPointF(0.5, 0.0))
def draw_icon(self, painter): path = QPainterPath(QPointF(0, 0.3)) path.lineTo(0, 0.9) path.lineTo(1, 0.3) path.lineTo(1, 0.9) path.closeSubpath() painter.drawPath(path) painter.drawLine(QPointF(0.5, 0.6), QPointF(0.5, 0.15)) # Draw the arrow end-caps painter.setBrush(QBrush(QColor(0, 0, 0))) top_arrow_point = QPointF(0.65, 0.36) arrow = QPolygonF([ QPointF(-0.09, 0.0), QPointF(-0.005, 0.0), QPointF(-0.005, 0.8), QPointF(0.005, 0.8), QPointF(0.005, 0.0), QPointF(0.09, 0.0), QPointF(0.00, -0.25) ]) t = QTransform() t.rotate(35) top_arrow_r = t.map(arrow) arrow_l = top_arrow_r.translated(top_arrow_point) painter.drawPolygon(arrow_l) painter.setBrush(self._interlock_brush) painter.drawRect(QRectF(0.3, 0, 0.4, 0.15))
def shape(self): if self._shape is None: radius = self.getState()['size'][1] p = QPainterPath() p.moveTo(Point(0, -radius)) p.lineTo(Point(0, radius)) p.moveTo(Point(-radius, 0)) p.lineTo(Point(radius, 0)) p = self.mapToDevice(p) stroker = QPainterPathStroker() stroker.setWidth(10) outline = stroker.createStroke(p) self._shape = self.mapFromDevice(outline) return self._shape
def shape(self) -> QPainterPath: """ Shape Returns ------- value : QPainterPath """ # TODO DEBUG_DRAWING if debug_drawing: path = QPainterPath() path.addRect(self.boundingRect()) return path return ConnectionPainter.get_painter_stroke(self._geometry)
def draw_icon(self, painter): path = QPainterPath(QPointF(0, 0.3)) path.lineTo(0, 0.9) path.lineTo(1, 0.3) path.lineTo(1, 0.9) path.closeSubpath() painter.drawPath(path) painter.drawLine(QPointF(0.5, 0.6), QPointF(0.5, 0.3)) painter.setBrush(self._interlock_brush) painter.drawRect(QRectF(0.2, 0, 0.6, 0.3))
def painterPathForTriangle(): bottomLeft = QPointF(-1.0, -1.0) top = QPointF(0.0, 1.0) bottomRight = QPointF(1.0, -1.0) path = QPainterPath(bottomLeft) path.lineTo(top) path.lineTo(bottomRight) path.closeSubpath() return path
def updatePath(self): p0 = Vec2(self.state.w0, self.state.h0) p1 = Vec2(-self.state.w1, self.state.h0) p2 = Vec2(-self.state.w1, -self.state.h1) p3 = Vec2(self.state.w0, -self.state.h1) p0t = p0.rotate(self.state.rotation) p1t = p1.rotate(self.state.rotation) p2t = p2.rotate(self.state.rotation) p3t = p3.rotate(self.state.rotation) self._path = QPainterPath() self._path.moveTo(p0t.x, p0t.y) self._path.lineTo(p1t.x, p1t.y) self._path.lineTo(p2t.x, p2t.y) self._path.lineTo(p3t.x, p3t.y) self._path.closeSubpath() self.prepareGeometryChange()
def copy(self, other): self.__type = other.__type if other.__type == self.Path: self.__path = QPainterPath(other.__path) elif other.__type == self.Pixmap: self.__pixmapData = copy.deepcopy(other.__pixmapData) elif other.__type == self.Image: self.__imageData = copy.deepcopy(other.__imageData) elif other.__type == self.State: self.__stateData == copy.deepcopy(other.__stateData)
def showTracks(self): # clear self.pathitems self.clearTracks() frame = self.window.imageview.currentIndex if frame<len(self.tracks_by_frame): tracks = self.tracks_by_frame[frame] pen = QPen(Qt.green, .4) pen.setCosmetic(True) pen.setWidth(2) for track_idx in tracks: pathitem = QGraphicsPathItem(self.window.imageview.view) pathitem.setPen(pen) self.window.imageview.view.addItem(pathitem) self.pathitems.append(pathitem) pts = self.txy_pts[self.tracks[track_idx]] x = pts[:, 1]+.5; y = pts[:,2]+.5 path = QPainterPath(QPointF(x[0],y[0])) for i in np.arange(1, len(pts)): path.lineTo(QPointF(x[i],y[i])) pathitem.setPath(path)
def paintEvent(self, event): painter = QPainter(self) painter.setRenderHints(QPainter.Antialiasing) if self.label_width <= 0: return painter.setPen(Qt.NoPen) if self.hover: painter.setBrush( QColor(self.back_color.red() + 30, self.back_color.green() + 30, self.back_color.blue() + 30)) else: painter.setBrush(self.back_color) painter.drawRoundedRect(QRect(0, 0, self.width(), self.height()), self.border_radius, self.border_radius) x1 = QPointF(self.label_width + float(self.height() / 3), float(self.height() * 0.45)) x2 = QPointF( self.label_width + float(self.height() * (0.66 + self.rate) / 2), float(self.height() * 0.55)) x3 = QPointF(self.width() - float(self.height() / 3), float(self.height() * 0.45)) check_path = QPainterPath() check_path.moveTo(x1) check_path.lineTo(x2) check_path.lineTo(x3) pen = QPen(self.text_color, self.drop_thick, Qt.SolidLine) painter.setPen(pen) painter.drawPath(check_path)
def paintEvent(self, event): painter = QPainter(self) painter.setRenderHints(QPainter.Antialiasing) side = min(self.width(), self.height()) painter.scale(side / 32.0, side / 32.0) painter.setPen(Qt.NoPen) if not self.is_pressed: painter.setBrush(self.back_color) else: painter.setBrush( QColor(self.back_color.red() + 30, self.back_color.green() + 30, self.back_color.blue() + 30)) painter.drawRoundedRect(QRect(0, 0, 32, 32), 8, 8) if self.is_checked: check_path = QPainterPath() check_path.moveTo(self.x1) check_path.lineTo(self.x2) check_path.lineTo(self.x3) pen = QPen(self.check_color, self.check_thick, Qt.SolidLine) painter.setPen(pen) painter.drawPath(check_path)
def draw_icon(self, painter): path = QPainterPath(QPointF(0, 0.3)) path.lineTo(0, 0.9) path.lineTo(1, 0.3) path.lineTo(1, 0.9) path.closeSubpath() painter.drawPath(path) painter.drawLine(QPointF(0.4, 0), QPointF(0.5, 0.15)) painter.drawLine(QPointF(0.4, 0.10), QPointF(0.5, 0.25)) painter.drawLine(QPointF(0.5, 0.15), QPointF(0.6, 0)) painter.drawLine(QPointF(0.5, 0.25), QPointF(0.6, 0.10)) painter.drawLine(QPointF(0.5, 0.6), QPointF(0.5, 0.0))
def paintEvent(self, a0: QPaintEvent) -> None: super().paintEvent(a0) painter = QPainter(self) painter.save() painter.setRenderHint(QPainter.Antialiasing) rect = QRectF(self.margin, self.margin, self.width() - self.margin * 2, self.height() - 2 * self.margin) painter.setBrush(Qt.white) painter.setPen(Qt.white) painter.drawRect(rect) painter.restore() painter.save() painter.setRenderHint(QPainter.Antialiasing) pen = QPen() pen.setWidth(3) painter.setPen(pen) path = QPainterPath() height, width = rect.height() + self.margin, rect.width() + self.margin path.moveTo(self.margin, height) path.cubicTo(height * 0.5, width * 0.9, height * 0.9, width * 0.5, height, self.margin) painter.drawPath(path) painter.restore()
def build_paths(self): """ """ geo = self.geometry() radius = 0 shadow = self.offset_shadow x0, y0 = geo.x(), geo.y() width, height = geo.width() - shadow, geo.height() - shadow left, top = 0, 0 right, bottom = width, height self.round_rect_path = QPainterPath() self.round_rect_path.moveTo(right, top + radius) self.round_rect_path.arcTo(right - radius, top, radius, radius, 0.0, 90.0) self.round_rect_path.lineTo(left + radius, top) self.round_rect_path.arcTo(left, top, radius, radius, 90.0, 90.0) self.round_rect_path.lineTo(left, bottom - radius) self.round_rect_path.arcTo(left, bottom - radius, radius, radius, 180.0, 90.0) self.round_rect_path.lineTo(right - radius, bottom) self.round_rect_path.arcTo(right - radius, bottom - radius, radius, radius, 270.0, 90.0) self.round_rect_path.closeSubpath() # Top path header = 36 offset = 2 left, top = offset, offset right = width - (offset) self.top_rect_path = QPainterPath() self.top_rect_path.lineTo(right, top + radius) self.top_rect_path.moveTo(right, top + radius) self.top_rect_path.arcTo(right - radius, top, radius, radius, 0.0, 90.0) self.top_rect_path.lineTo(left + radius, top) self.top_rect_path.arcTo(left, top, radius, radius, 90.0, 90.0) self.top_rect_path.lineTo(left, top + header) self.top_rect_path.lineTo(right, top + header)
def __init__(self, x, y, width=1, height=1, rotation=0, parent=None): """ Constructor. :param x: Initial x position of ROIs center. :param y: Initial y position of ROIs center. :param width: Initial width :param height: Initial height :param rotation: Initial rotation in radians :param parent: Optional parent item. """ super(RectangularRegion, self).__init__(parent) self.setFlags(QGraphicsItem.ItemIsMovable | QGraphicsItem.ItemIsFocusable | QGraphicsItem.ItemSendsGeometryChanges) # self.setHandlesChildEvents(False) # self.setFiltersChildEvents(True) self.__in_move = False self._path = QPainterPath() self.pen = QPen(QBrush(QColor(161, 0, 161, 255)), 1.0, Qt.SolidLine) self.pen.setCosmetic(True) self.brush = QBrush(QColor(255, 255, 255, 40)) self.state = RoiState() self.state.pos = QPointF(x, y) self.state.w0 = width self.state.w1 = width self.state.h0 = height self.state.h1 = height self.state.rotation = rotation self.setPos(self.state.pos) self.updatePath() self._handles = []
def draw_curve(self, path: Sequence[_Coord]) -> None: """Draw path as curve.""" if len(set(path)) < 2: return painter_path = QPainterPath() error = False for i, (x, y) in enumerate(path): if isnan(x): error = True self.painter.drawPath(painter_path) painter_path = QPainterPath() else: p = QPointF(x, -y) * self.zoom if i == 0: painter_path.moveTo(p) self.draw_circle(p, 2) continue if error: painter_path.moveTo(p) error = False else: painter_path.lineTo(p) self.painter.drawPath(painter_path)
def get_painter_stroke(geom: ConnectionGeometry) -> QPainterPath: """ Get painter stroke Parameters ---------- geom : ConnectionGeometry Returns ------- value : QPainterPath """ cubic = cubic_path(geom) source = geom.source result = QPainterPath(source) segments = 20 for i in range(segments): ratio = float(i + 1) / segments result.lineTo(cubic.pointAtPercent(ratio)) stroker = QPainterPathStroker() stroker.setWidth(10.0) return stroker.createStroke(result)
def drawTriangle(self, qp): """Draw triangle. Parameters ---------- qp: QPainter object """ width = self.rect().width() height = self.rect().height() col = QColor(135, 206, 235) qp.setPen(QPen(col, 1)) qp.setBrush(col) path = QPainterPath() height = 10 path.moveTo(0, height) path.lineTo(width, height) path.lineTo(width, 0) path.closeSubpath() qp.drawPath(path)
class FadingTipBox(FadingDialog): """ """ def __init__(self, parent, opacity, duration, easing_curve, tour=None): super(FadingTipBox, self).__init__(parent, opacity, duration, easing_curve) self.holder = self.anim # needed for qt to work self.parent = parent self.tour = tour self.frames = None self.color_top = QColor.fromRgb(230, 230, 230) self.color_back = QColor.fromRgb(255, 255, 255) self.offset_shadow = 0 self.fixed_width = 300 self.key_pressed = None self.setAttribute(Qt.WA_TranslucentBackground) self.setWindowFlags(Qt.Dialog | Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint) self.setModal(False) # Widgets def toolbutton(icon): bt = QToolButton() bt.setAutoRaise(True) bt.setIcon(icon) return bt self.button_close = toolbutton(ima.icon("tour.close")) self.button_home = toolbutton(ima.icon("tour.home")) self.button_previous = toolbutton(ima.icon("tour.previous")) self.button_end = toolbutton(ima.icon("tour.end")) self.button_next = toolbutton(ima.icon("tour.next")) self.button_run = QPushButton(_('Run code')) self.button_disable = None self.button_current = QToolButton() self.label_image = QLabel() self.label_title = QLabel() self.combo_title = QComboBox() self.label_current = QLabel() self.label_content = QLabel() self.label_content.setMinimumWidth(self.fixed_width) self.label_content.setMaximumWidth(self.fixed_width) self.label_current.setAlignment(Qt.AlignCenter) self.label_content.setWordWrap(True) self.widgets = [self.label_content, self.label_title, self.label_current, self.combo_title, self.button_close, self.button_run, self.button_next, self.button_previous, self.button_end, self.button_home, self.button_current] arrow = get_image_path('hide.png') self.stylesheet = '''QComboBox { padding-left: 5px; background-color: rgbs(230,230,230,100%); border-width: 0px; border-radius: 0px; min-height:20px; max-height:20px; } QComboBox::drop-down { subcontrol-origin: padding; subcontrol-position: top left; border-width: 0px; } QComboBox::down-arrow { image: url(''' + arrow + '''); } ''' # Windows fix, slashes should be always in unix-style self.stylesheet = self.stylesheet.replace('\\', '/') self.setFocusPolicy(Qt.StrongFocus) for widget in self.widgets: widget.setFocusPolicy(Qt.NoFocus) widget.setStyleSheet(self.stylesheet) layout_top = QHBoxLayout() layout_top.addWidget(self.combo_title) layout_top.addStretch() layout_top.addWidget(self.button_close) layout_top.addSpacerItem(QSpacerItem(self.offset_shadow, self.offset_shadow)) layout_content = QHBoxLayout() layout_content.addWidget(self.label_content) layout_content.addWidget(self.label_image) layout_content.addSpacerItem(QSpacerItem(5, 5)) layout_run = QHBoxLayout() layout_run.addStretch() layout_run.addWidget(self.button_run) layout_run.addStretch() layout_run.addSpacerItem(QSpacerItem(self.offset_shadow, self.offset_shadow)) layout_navigation = QHBoxLayout() layout_navigation.addWidget(self.button_home) layout_navigation.addWidget(self.button_previous) layout_navigation.addStretch() layout_navigation.addWidget(self.label_current) layout_navigation.addStretch() layout_navigation.addWidget(self.button_next) layout_navigation.addWidget(self.button_end) layout_navigation.addSpacerItem(QSpacerItem(self.offset_shadow, self.offset_shadow)) layout = QVBoxLayout() layout.addLayout(layout_top) layout.addStretch() layout.addSpacerItem(QSpacerItem(15, 15)) layout.addLayout(layout_content) layout.addLayout(layout_run) layout.addStretch() layout.addSpacerItem(QSpacerItem(15, 15)) layout.addLayout(layout_navigation) layout.addSpacerItem(QSpacerItem(self.offset_shadow, self.offset_shadow)) layout.setSizeConstraint(QLayout.SetFixedSize) self.setLayout(layout) self.set_funcs_before_fade_in([self._disable_widgets]) self.set_funcs_after_fade_in([self._enable_widgets, self.setFocus]) self.set_funcs_before_fade_out([self._disable_widgets]) self.setContextMenuPolicy(Qt.CustomContextMenu) # signals and slots # These are defined every time by the AnimatedTour Class def _disable_widgets(self): """ """ for widget in self.widgets: widget.setDisabled(True) def _enable_widgets(self): """ """ self.setWindowFlags(Qt.Dialog | Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint) for widget in self.widgets: widget.setDisabled(False) if self.button_disable == 'previous': self.button_previous.setDisabled(True) self.button_home.setDisabled(True) elif self.button_disable == 'next': self.button_next.setDisabled(True) self.button_end.setDisabled(True) def set_data(self, title, content, current, image, run, frames=None, step=None): """ """ self.label_title.setText(title) self.combo_title.clear() self.combo_title.addItems(frames) self.combo_title.setCurrentIndex(step) # min_content_len = max([len(f) for f in frames]) # self.combo_title.setMinimumContentsLength(min_content_len) # Fix and try to see how it looks with a combo box self.label_current.setText(current) self.button_current.setText(current) self.label_content.setText(content) self.image = image if image is None: self.label_image.setFixedHeight(1) self.label_image.setFixedWidth(1) else: extension = image.split('.')[-1] self.image = QPixmap(get_image_path(image), extension) self.label_image.setPixmap(self.image) self.label_image.setFixedSize(self.image.size()) if run is None: self.button_run.setVisible(False) else: self.button_run.setDisabled(False) self.button_run.setVisible(True) # Refresh layout self.layout().activate() def set_pos(self, x, y): """ """ self.x = x self.y = y self.move(QPoint(x, y)) def build_paths(self): """ """ geo = self.geometry() radius = 0 shadow = self.offset_shadow x0, y0 = geo.x(), geo.y() width, height = geo.width() - shadow, geo.height() - shadow left, top = 0, 0 right, bottom = width, height self.round_rect_path = QPainterPath() self.round_rect_path.moveTo(right, top + radius) self.round_rect_path.arcTo(right-radius, top, radius, radius, 0.0, 90.0) self.round_rect_path.lineTo(left+radius, top) self.round_rect_path.arcTo(left, top, radius, radius, 90.0, 90.0) self.round_rect_path.lineTo(left, bottom-radius) self.round_rect_path.arcTo(left, bottom-radius, radius, radius, 180.0, 90.0) self.round_rect_path.lineTo(right-radius, bottom) self.round_rect_path.arcTo(right-radius, bottom-radius, radius, radius, 270.0, 90.0) self.round_rect_path.closeSubpath() # Top path header = 36 offset = 2 left, top = offset, offset right = width - (offset) self.top_rect_path = QPainterPath() self.top_rect_path.lineTo(right, top + radius) self.top_rect_path.moveTo(right, top + radius) self.top_rect_path.arcTo(right-radius, top, radius, radius, 0.0, 90.0) self.top_rect_path.lineTo(left+radius, top) self.top_rect_path.arcTo(left, top, radius, radius, 90.0, 90.0) self.top_rect_path.lineTo(left, top + header) self.top_rect_path.lineTo(right, top + header) def paintEvent(self, event): """ """ self.build_paths() painter = QPainter(self) painter.setRenderHint(QPainter.Antialiasing) painter.fillPath(self.round_rect_path, self.color_back) painter.fillPath(self.top_rect_path, self.color_top) painter.strokePath(self.round_rect_path, QPen(Qt.gray, 1)) # TODO: Build the pointing arrow? def keyReleaseEvent(self, event): """ """ key = event.key() self.key_pressed = key keys = [Qt.Key_Right, Qt.Key_Left, Qt.Key_Down, Qt.Key_Up, Qt.Key_Escape, Qt.Key_PageUp, Qt.Key_PageDown, Qt.Key_Home, Qt.Key_End, Qt.Key_Menu] if key in keys: if not self.is_fade_running(): self.sig_key_pressed.emit() def mousePressEvent(self, event): """override Qt method""" # Raise the main application window on click self.parent.raise_() self.raise_() if event.button() == Qt.RightButton: pass # clicked_widget = self.childAt(event.x(), event.y()) # if clicked_widget == self.label_current: # self.context_menu_requested(event) def focusOutEvent(self, event): """Override Qt method.""" # To be used so tips do not appear outside spyder self.tour.lost_focus() def context_menu_requested(self, event): """ """ pos = QPoint(event.x(), event.y()) menu = QMenu(self) actions = [] action_title = create_action(self, _('Go to step: '), icon=QIcon()) action_title.setDisabled(True) actions.append(action_title) # actions.append(create_action(self, _(': '), icon=QIcon())) add_actions(menu, actions) menu.popup(self.mapToGlobal(pos)) def reject(self): """Qt method to handle escape key event""" if not self.is_fade_running(): key = Qt.Key_Escape self.key_pressed = key self.sig_key_pressed.emit()
def update_canvas(self): """ """ w, h = self.parent.size().width(), self.parent.size().height() self.path_full = QPainterPath() self.path_subtract = QPainterPath() self.path_decoration = QPainterPath() self.region_mask = QRegion(0, 0, w, h) self.path_full.addRect(0, 0, w, h) # Add the path if self.widgets is not None: for widget in self.widgets: temp_path = QPainterPath() # if widget is not found... find more general way to handle if widget is not None: widget.raise_() widget.show() geo = widget.frameGeometry() width, height = geo.width(), geo.height() point = widget.mapTo(self.parent, QPoint(0, 0)) x, y = point.x(), point.y() temp_path.addRect(QRectF(x, y, width, height)) temp_region = QRegion(x, y, width, height) if self.interaction_on: self.region_mask = self.region_mask.subtracted(temp_region) self.path_subtract = self.path_subtract.united(temp_path) self.path_current = self.path_full.subtracted(self.path_subtract) else: self.path_current = self.path_full if self.decoration is not None: for widget in self.decoration: temp_path = QPainterPath() widget.raise_() widget.show() geo = widget.frameGeometry() width, height = geo.width(), geo.height() point = widget.mapTo(self.parent, QPoint(0, 0)) x, y = point.x(), point.y() temp_path.addRect(QRectF(x, y, width, height)) temp_region_1 = QRegion(x-1, y-1, width+2, height+2) temp_region_2 = QRegion(x+1, y+1, width-2, height-2) temp_region = temp_region_1.subtracted(temp_region_2) if self.interaction_on: self.region_mask = self.region_mask.united(temp_region) self.path_decoration = self.path_decoration.united(temp_path) else: self.path_decoration.addRect(0, 0, 0, 0) # Add a decoration stroke around widget self.setMask(self.region_mask) self.update() self.repaint()
class FadingCanvas(FadingDialog): """The black semi transparent canvas that covers the application""" def __init__(self, parent, opacity, duration, easing_curve, color, tour=None): """Create a black semi transparent canvas that covers the app.""" super(FadingCanvas, self).__init__(parent, opacity, duration, easing_curve) self.parent = parent self.tour = tour self.color = color # Canvas color self.color_decoration = Qt.red # Decoration color self.stroke_decoration = 2 # width in pixels for decoration self.region_mask = None self.region_subtract = None self.region_decoration = None self.widgets = None # The widget to uncover self.decoration = None # The widget to draw decoration self.interaction_on = False self.path_current = None self.path_subtract = None self.path_full = None self.path_decoration = None # widget setup self.setWindowFlags(Qt.Dialog | Qt.FramelessWindowHint) self.setAttribute(Qt.WA_TranslucentBackground) self.setAttribute(Qt.WA_TransparentForMouseEvents) self.setModal(False) self.setFocusPolicy(Qt.NoFocus) self.set_funcs_before_fade_in([self.update_canvas]) self.set_funcs_after_fade_out([lambda: self.update_widgets(None), lambda: self.update_decoration(None)]) def set_interaction(self, value): """ """ self.interaction_on = value def update_canvas(self): """ """ w, h = self.parent.size().width(), self.parent.size().height() self.path_full = QPainterPath() self.path_subtract = QPainterPath() self.path_decoration = QPainterPath() self.region_mask = QRegion(0, 0, w, h) self.path_full.addRect(0, 0, w, h) # Add the path if self.widgets is not None: for widget in self.widgets: temp_path = QPainterPath() # if widget is not found... find more general way to handle if widget is not None: widget.raise_() widget.show() geo = widget.frameGeometry() width, height = geo.width(), geo.height() point = widget.mapTo(self.parent, QPoint(0, 0)) x, y = point.x(), point.y() temp_path.addRect(QRectF(x, y, width, height)) temp_region = QRegion(x, y, width, height) if self.interaction_on: self.region_mask = self.region_mask.subtracted(temp_region) self.path_subtract = self.path_subtract.united(temp_path) self.path_current = self.path_full.subtracted(self.path_subtract) else: self.path_current = self.path_full if self.decoration is not None: for widget in self.decoration: temp_path = QPainterPath() widget.raise_() widget.show() geo = widget.frameGeometry() width, height = geo.width(), geo.height() point = widget.mapTo(self.parent, QPoint(0, 0)) x, y = point.x(), point.y() temp_path.addRect(QRectF(x, y, width, height)) temp_region_1 = QRegion(x-1, y-1, width+2, height+2) temp_region_2 = QRegion(x+1, y+1, width-2, height-2) temp_region = temp_region_1.subtracted(temp_region_2) if self.interaction_on: self.region_mask = self.region_mask.united(temp_region) self.path_decoration = self.path_decoration.united(temp_path) else: self.path_decoration.addRect(0, 0, 0, 0) # Add a decoration stroke around widget self.setMask(self.region_mask) self.update() self.repaint() def update_widgets(self, widgets): """ """ self.widgets = widgets def update_decoration(self, widgets): """ """ self.decoration = widgets def paintEvent(self, event): """Override Qt method""" painter = QPainter(self) painter.setRenderHint(QPainter.Antialiasing) # Decoration painter.fillPath(self.path_current, QBrush(self.color)) painter.strokePath(self.path_decoration, QPen(self.color_decoration, self.stroke_decoration)) # decoration_fill = QColor(self.color_decoration) # decoration_fill.setAlphaF(0.25) # painter.fillPath(self.path_decoration, decoration_fill) def reject(self): """Override Qt method""" if not self.is_fade_running(): key = Qt.Key_Escape self.key_pressed = key self.sig_key_pressed.emit() def mousePressEvent(self, event): """Override Qt method""" pass def focusInEvent(self, event): """Override Qt method.""" # To be used so tips do not appear outside spyder if self.hasFocus(): self.tour.gain_focus() def focusOutEvent(self, event): """Override Qt method.""" # To be used so tips do not appear outside spyder if self.tour.step_current != 0: self.tour.lost_focus()