def setPos(self, pos: QPointF, connect=False): super(QGraphicsBlockItem, self).setPos(pos) for type, c in iter(self._connections.items()): otherConnect, otherId = c.connect if otherId is not None: if type in [ConnectionType.TOP, ConnectionType.LEFT] and not connect: c.connect = None otherConnect.connect = None otherConnect.parent.updateSize() elif c.type is ConnectionType.BOTTOM: otherConnect.parent.setPos(self.pos() + QPointF(0, self.pixmap().height() - 5), True) elif c.type is ConnectionType.BOTTOMIN: otherConnect.parent.setPos(self.pos() + QPointF(17, 33), True) elif c.type is ConnectionType.RIGHT: otherConnect.parent.setPos(self.pos() + QPointF(self.pixmap().width() - 5, 0), True)
def testquadToSquare(self): q1 = QPolygonF() q1.append(QPointF(10.0, 10.0)) q1.append(QPointF(20.0, 10.0)) q1.append(QPointF(10.0, -10.0)) q1.append(QPointF(20.0, -10.0)) t1 = QTransform() r1 = QTransform.quadToSquare(q1, t1) r2 = QTransform.quadToSquare(q1) self.assertTrue(r1) self.assertTrue(r2) self.assertEqual(t1, r2)
def calculate_bounding_rect(self): """ Calculate the bounding rectangle of the component based on what nodes it owns. """ x_sorted = sorted([node.cx for node in self.nodes]) y_sorted = sorted([node.cy for node in self.nodes]) x_min = x_sorted[0] x_max = x_sorted[-1] y_min = y_sorted[0] y_max = y_sorted[-1] top_left_p = QPointF(x_min - 10, y_min - 10) bottom_right_p = QPointF(x_max + 10, y_max + 10) self.bounding_rect = QRectF(top_left_p, bottom_right_p)
def __generate_curve(self, mean, sd, ascending, descending): if ascending and descending: return [ QPointF(x, 0) for x in np.linspace( self.__xmin, self.__xmax, 10, endpoint=True) ] points = list() for x in np.linspace(self.__xmin, self.__xmax, 400): if ascending and x > mean: points.append(QPointF(x, 1)) elif descending and x < mean: points.append(QPointF(x, 1)) else: points.append(QPointF(x, gaussian(x, mean, sd))) return points
def drawGradient(self, qp): gradient = QLinearGradient(QPointF(200,15), QPointF(600,60)) gradient.setColorAt(0,Qt.blue) gradient.setColorAt(0.25,Qt.cyan) gradient.setColorAt(0.5,Qt.green) gradient.setColorAt(0.75,Qt.yellow) gradient.setColorAt(1,Qt.red) qp.setBrush(gradient) qp.drawRect(200, 15, 600, 60) qp.setFont(QFont('Arial', 8)) qp.setBrush(Qt.black) qp.drawText(200, 0, 205, 15, Qt.AlignLeft, "0") qp.drawText(395, 0, 405, 15, Qt.AlignLeft, "0.5") qp.drawText(595, 0, 600, 15, Qt.AlignLeft, "1")
def paintEvent(self, ev): """ Manually implemented paint event :param ev: the QT paint event :return: """ h = self.height() w = self.width() p = QPainter(self) p.setClipRect(ev.region().boundingRect()) pen = QPen(QColor(0, 0, 0)) pen.setWidth(4) ls = QFontMetricsF(p.font()).lineSpacing() for idx, t in enumerate(sorted(list(self._loadData.keys()))): y = 10 + idx * ls pen.setColor(ThreadToColor.singleton.get(t)) p.setPen(pen) p.drawLine(QLineF(15, y, 15 + 15, y)) pen.setColor(QColor(0, 0, 0)) p.setPen(pen) p.drawText(QPointF(35, y), t) if len(self._loadData) > 0: right = max([ polygon[polygon.count() - 1].x() for _, polygon in self._loadData.items() ]) else: right = 0.0 p.translate(w - 10 - right * 20, h - 10) p.scale( 20, -(h - 20) ) # x direction: 20 pixels per second, y direction: spread between 10 and h-10 topleft = p.transform().inverted()[0].map(QPointF(10, 10)) pen.setWidthF(0) pen.setCosmetic(True) left = topleft.x() p.setRenderHint(QPainter.Antialiasing, True) p.setPen(pen) p.drawLine(QLineF(left, 0, right, 0)) p.drawLine(QLineF(left, 0, left, 1)) idx = 0 for t, polygon in self._loadData.items(): pen.setColor(ThreadToColor.singleton.get(t)) p.setPen(pen) p.drawPolyline(polygon) p.end()
def updateSceneRect(self, factor: float) -> QRectF: """Updates the associated scene's bounding rectangle. To make it possible to pan the view, the scene's bounding rectangle must be larger than the viewport. Scaling the view means that the scene in its entirety is scaled, including the scene's bounding rectangle, so it must be scaled along with the view. Currently, the view can be panned such that the editing grid can be freely moved around, but within the bounds of the viewport regardless of its size or zoom level, similar to Aseprite. Args: factor: The scaling factor the scene should be sized with respect to. Returns the updated scene bounding rectangle. """ # TODO: make configurable via Property margin = QSize(10, 10) # Between edge of grid and viewport editAreaRect = self.editor().editArea.rect() editAreaSize = editAreaRect.size().toSize() # Make the scene 2x larger than the viewport, minus the editing grid. This # allows us to pan the grid up to the edges of the viewport (minus margin), # but no further. Also ensure the scene is at least big enough to encompass # the entire grid. sceneSize = self.maximumViewportSize() * 2 * (1 / factor) sceneSize = sceneSize - editAreaSize - margin sceneSize = sceneSize.expandedTo(editAreaSize + margin) newSceneRect = QRectF(QPointF(0, 0), sceneSize) newSceneRect.moveCenter(editAreaRect.center()) self.setSceneRect(newSceneRect) return newSceneRect
def updatePath(self): axeSize = self.size yZero = self.yZero try: X = [] for item in self.fixedPoints: X.extend([item.B.x() + item.x(), item.C.x() + item.x()]) X = np.array(X) Y = np.array( [-(item.A.y() + item.y()) for item in self.fixedPoints]) + yZero T = displacementSpline(X, Y, self.xCoords, clippingInterval=[-self.scene().axeSize, 0], period=self.period) self.spline = [ QPointF(x, y + yZero) for x, y in zip(self.xCoords, -T) ] # scene coord. # build path polygon = QPolygonF(self.spline) qpp = QPainterPath() qpp.addPolygon(polygon) # stroke path stroker = QPainterPathStroker() stroker.setWidth(self.strokeWidth) mboundingPath = stroker.createStroke(qpp) self.setPath(mboundingPath) except ValueError: pass
def request_relayout(self): node_coords, edges = self._layout_graph() self._edges = edges categorize_edges(self.disasm, edges) if not node_coords: print("Failed to get node_coords") return # layout nodes for block in self.blocks: x, y = node_coords[block.addr] block.setPos(x, y) scene = self.scene() # remove exiting arrows for arrow in self._arrows: scene.removeItem(arrow) self._arrows.clear() for edge in self._edges: arrow = QGraphArrow(edge) self._arrows.append(arrow) scene.addItem(arrow) arrow.setPos(QPointF(*edge.coordinates[0]))
def updateShape(self): p1 = QPointF(0, 0) p2 = QPointF(self.width(), self.height()) ctrlPt = QPointF(abs(self.width() * self.curveScale), 0) path = QPainterPath(p1) path.cubicTo(p1 + ctrlPt, p2 - ctrlPt, p2) # Compute offset on x and y axis halfThickness = self._thickness / 2.0 v = QVector2D(p2 - p1).normalized() offset = QPointF(halfThickness * -v.y(), halfThickness * v.x()) self._path = QPainterPath(path.toReversed()) self._path.translate(-offset) path.translate(offset) self._path.connectPath(path)
def __init__(self, x, y, color=Qt.white, fillColor=None, persistent=False, rect=None, parentItem=None): super().__init__(parent=parentItem) self.color = color self.setAcceptHoverEvents(True) self.persistent = persistent self.rect = rect if self.rect is not None: self.xmin, self.xmax, self.ymin, self.ymax = rect.left( ), rect.right(), rect.top(), rect.bottom() x = min(max(x, self.xmin), self.xmax) y = min(max(y, self.ymin), self.ymax) self.setPos(QPointF(x, y)) self.clicked = False self.setPen(QPen(color, 2)) # filling brush if fillColor is not None: self.setBrush(QBrush(fillColor)) qpp = QPainterPath() # coordinates are relative to activePoint qpp.addEllipse(-4, -4, 8, 8) self.setPath(qpp)
def createScatterChart(data): chart = QtCharts.QChart() # chart.legend().hide() chart.setTitle("Spline chart (market shares)") series0 = QtCharts.QScatterSeries() series0.setName("height / weight") series0.setMarkerShape(QtCharts.QScatterSeries.MarkerShapeCircle) series0.setMarkerSize(5.0) #series0.append([0, 6, 6, 4]) pointsList = list( map(lambda hw: QPointF(hw[0], hw[1]), zip(data[0], data[1]))) series0.append(pointsList) chartView = QtCharts.QChartView(chart) chartView.setRenderHint(QPainter.Antialiasing) chart.addSeries(series0) chart.setTitle("Nba Players active as of 2018 height/weight") chart.createDefaultAxes() chart.setDropShadowEnabled(False) chart.axes(Qt.Vertical)[0].setTitleText("Weight") chart.axes(Qt.Horizontal)[0].setTitleText("Height") return chartView
def place_new_node_by_shortcut(self): # Shift+P point_in_viewport = None selected_NIs = self.selected_node_instances() if len(selected_NIs) > 0: x = selected_NIs[-1].pos().x() + 150 y = selected_NIs[-1].pos().y() self.node_place_pos = QPointF(x, y) point_in_viewport = self.mapFromScene(QPoint(x, y)) else: # place in center viewport_x = self.viewport().width() / 2 viewport_y = self.viewport().height() / 2 point_in_viewport = QPointF(viewport_x, viewport_y).toPoint() self.node_place_pos = self.mapToScene(point_in_viewport) self.node_choice_widget.reset_list() self.show_node_choice_widget(point_in_viewport)
def __init__(self, parent=None, shareWidget=None, size=None, use_frame_buffer=constants.use_frame_buffer): super(SceneViewerWidget, self).__init__(shareWidget=shareWidget) self.glWidth = self.width() self.glHeight = self.height() self.setAcceptDrops(True) self.setMouseTracking(True) self.setAutoBufferSwap(False) self.parent = parent self.movement_scale = 0.1 self.rotation_scale = 0.1 self.zoom_factor = 0.1 self._full_screen = False self.lastMousePosition = QPointF() self.statusBar = None self.clickRayCollision = None self.clickRayStart = np.array([0, 0, 0]) self.clickRayEnd = np.array([0, 0, 0]) self.enable_mouse_interaction = True self.use_frame_buffer = use_frame_buffer self.graphics_context = None self.size = size self.initialized = False
def containsNewCity(self): w, h = self.width(), self.height() bounding_rect = QRectF(5, 5, w - 10, h - 10) r = self.new_city.get_radius() city_rect = QRectF(self.new_city.pos - QPointF(r, r), QtCore.QSize(2 * r, 2 * r)) return bounding_rect.contains(city_rect)
def __init__(self, center: QPointF): super(BezierGraphicsItem, self).__init__() self.setCursor(Qt.ArrowCursor) self.setZValue(-1) self.setFlags(QGraphicsItem.ItemIsMovable | QGraphicsItem.ItemIsSelectable | QGraphicsItem.ItemIsFocusable) self.setFlag(QGraphicsItem.ItemSendsGeometryChanges) self._m_radius = float(0) self._m_centerPos = center self._m_textPos = QPointF(center.x() - 7, center.y() - 30) self._m_pointList = BezierPointItemList() self._m_pen_isSelected = QPen() self._m_pen_noSelected = QPen() self._m_noSelectedThickness = 2 self._m_isSelectedThickness = 2 self._m_pen_noSelectedColor = QColor(Qt.gray) self._m_pen_isSelectedColor = QColor(Qt.blue) self._m_pen_isSelected.setColor(self._m_pen_isSelectedColor) self._m_pen_noSelected.setColor(self._m_pen_noSelectedColor) self._m_pen_isSelected.setWidth(self._m_isSelectedThickness) self._m_pen_noSelected.setWidth(self._m_noSelectedThickness) self._m_graphicsType = GraphicsType.NoneType self.setPen(self._m_pen_noSelected)
def mouseMoveEvent(self, event): """pass event along to scenes before changing the own state""" #cam_pos = self.graphics_context.camera.get_world_position() #pos_2d = [event.x(),event.y()] #ray_direction = self.get_ray_from_pixel(pos_2d) cam_pos, cam_ray = self.getRayFromClick(event.x(), event.y()) cam_pos = cam_pos[:3] cam_ray = cam_ray[:3] self.mouse_move.emit(event, self.lastMousePosition, cam_pos, cam_ray) modifiers = QApplication.keyboardModifiers() newPosition = QPointF(event.x(), event.y()) diff = newPosition - self.lastMousePosition self.lastMousePosition = newPosition if event.buttons() & Qt.MiddleButton and modifiers != Qt.ShiftModifier: # set rotation self.graphics_context.camera.updateRotationMatrix( self.graphics_context.camera.pitch + diff.y() * self.rotation_scale, self.graphics_context.camera.yaw + diff.x() * self.rotation_scale) self.showMessageOnStatusBar( "rotation x: " + str(self.graphics_context.camera.yaw) + ", rotation y: " + str(self.graphics_context.camera.pitch)) elif event.buttons( ) & Qt.MiddleButton and modifiers == Qt.ShiftModifier: # set position self.graphics_context.camera.moveHorizontally( -diff.x() * self.movement_scale * 2) self.graphics_context.camera.position[1] -= diff.y( ) * self.movement_scale * 2 #/(10*self.zoom_factor)
def _draw_row(self, painter, offset, row_y): if not self.data: return # Row build row_offset = " {:04X} ".format(offset) row_raw_hex = self.data[offset:offset + self.row_width].hex() if len(row_raw_hex) < self.row_width * 2: row_raw_hex += ' ' * (self.row_width * 2 - len(row_raw_hex)) row_hex = ' '.join([row_raw_hex[i:i+2] for i in range(0, len(row_raw_hex), 2)]) row_raw_ascii = self.data[offset:offset + self.row_width].decode("ascii", "replace").replace(u"\ufffd", ".") row_ascii = remove_control_chars(row_raw_ascii) row = row_offset + " " + row_hex + " " + row_ascii # Paint self.layout.clearLayout() self.layout.setText(row) self.layout.beginLayout() line = self.layout.createLine() line.setLineWidth(1000) line.setLeadingIncluded(True) self.layout.endLayout() self.layout.draw(painter, QPointF(0.0, row_y))
def do_update_geometry(self, guide_path): """See base class.""" super().do_update_geometry(guide_path) center = guide_path.pointAtPercent(0.5) self._filter_icon.setPos( center - 0.5 * QPointF(self._filter_icon_extent, self._filter_icon_extent))
def __init__(self, device): super(MainWindow, self).__init__() self.series = QtCharts.QLineSeries() self.chart = QtCharts.QChart() self.chart.addSeries(self.series) self.axisX = QtCharts.QValueAxis() self.axisX.setRange(0, sampleCount) self.axisX.setLabelFormat("%g") self.axisX.setTitleText("Samples") self.axisY = QtCharts.QValueAxis() self.axisY.setRange(-1, 1) self.axisY.setTitleText("Audio level") self.chart.setAxisX(self.axisX, self.series) self.chart.setAxisY(self.axisY, self.series) self.chart.legend().hide() self.chart.setTitle("Data from the microphone ({})".format(device.deviceName())) formatAudio = QAudioFormat() formatAudio.setSampleRate(8000) formatAudio.setChannelCount(1) formatAudio.setSampleSize(8) formatAudio.setCodec("audio/pcm") formatAudio.setByteOrder(QAudioFormat.LittleEndian) formatAudio.setSampleType(QAudioFormat.UnSignedInt) self.audioInput = QAudioInput(device, formatAudio, self) self.ioDevice = self.audioInput.start() self.ioDevice.readyRead.connect(self._readyRead) self.chartView = QtCharts.QChartView(self.chart) self.setCentralWidget(self.chartView) self.buffer = [QPointF(x, 0) for x in range(sampleCount)] self.series.append(self.buffer)
def paint(self, painter, option, widget=None): if Design.flow_style == 'dark std': color = QColor( '#2E688C' ) if self.parent_port_instance.type_ == 'data' else QColor( '#3880ad') if option.state & QStyle.State_MouseOver: color = color.lighter() brush = QBrush(QColor(color)) painter.setBrush(brush) painter.setPen(Qt.NoPen) elif Design.flow_style == 'dark tron': color = '' if self.parent_port_instance.type_ == 'exec': color = '#FFFFFF' elif self.parent_port_instance.type_ == 'data': color = self.parent_node_instance.parent_node.color pen = QPen(color) pen.setWidth(2) painter.setPen(pen) if len(self.parent_port_instance.connected_port_instances) > 0 or \ option.state & QStyle.State_MouseOver: # also fill when mouse hovers c = self.parent_node_instance.parent_node.color r = c.red() g = c.green() b = c.blue() brush = QBrush(QColor(r, g, b, 100)) painter.setBrush(brush) else: painter.setBrush(Qt.NoBrush) painter.drawEllipse(QPointF(0, 0), self.width / 2, self.height / 2)
def __init__(self, label, indices, pos, length, height, label_width, frame_width, color, parent=None): super(TimeLine, self).__init__(parent) self._pos = pos self._length = length self._height = height self.label = label self._label_width = label_width self._indices = indices self.frame_width = frame_width size = QSizeF() size.setHeight(self._height) size.setWidth(self._length) self._bounding_rect = QRectF() self._bounding_rect.setX(self._pos.x()) self._bounding_rect.setY(self._pos.y()) self._bounding_rect.setSize(size) self._tpos = QPointF(pos) self._tpos.setY(pos.y() + self._height) self.color = QColor() self.color.setRed(color[0] * 255) self.color.setGreen(color[1] * 255) self.color.setBlue(color[2] * 255) self.color.setAlpha(255)
def paint_detail(self, painter, month_flag, day_flag): x0 = 0.0 + (self.width() - self.height()) / self.height() y0 = 0.0 x, y = self.convert_center(0.0, 0.0) painter.setPen(QPen(Qt.white, 2, Qt.SolidLine)) painter.drawEllipse(QPointF(x, y), self.radius * self.height() / 2, self.radius * self.height() / 2) processed_data = self.process_detail_data(self.data, self.city, self.radius, month_flag, day_flag) count_of_steps = len(processed_data) if month_flag and not day_flag: labels = processed_data['day'] time_period = 'day' elif day_flag: labels = processed_data['hour'] time_period = 'hour' else: labels = processed_data['month_name'] time_period = 'month' for step in processed_data[time_period]: self.paint_arc_for_month(painter, processed_data, x0, y0, step, count_of_steps, time_period) self.paint_spacing_lines(painter, x, y, count_of_steps) self.paint_labels(painter, x0, y0, self.radius, labels)
def plot(serie, signal): """Calculates and plot PSD - Power Spectral Density. Downsamples the calculated PSD so reasonable number of points is displayed. Parameters ---------- serie : `QLineSeries` Line serie. signal : `[float]` Input signal. Returns ------- min : `float` PSD subplot minimum value. max : `float` PSD subplot maximum value. """ N = len(signal) if N < 10: return 0, 0 # as input is real only, fft is symmetric; rfft is enough psd = np.abs(np.fft.rfft(np.array(signal) * self.coefficient))**2 (psd, frequencies) = downsample(psd, N) points = [QPointF(frequencies[r], psd[r]) for r in range(len(psd))] serie.replace(points) return min(psd), max(psd)
def _radius_from_point_and_angle(self, point, angle): line = QLineF() line.setP1(point) line.setAngle(angle) normal = line.normalVector() normal.setLength(self.magic_number / 2) return QPointF(normal.dx(), normal.dy())
def load_item_position_from_config(item, config): background_size = item.scene().sceneRect() x = float(config["item_scene_pos_x"]) y = float(config["item_scene_pos_y"]) pos_x = round(background_size.width() * x, 0) pos_y = round(background_size.height() * y, 0) item.setPos(QPointF(pos_x, pos_y))
def paste(self): data = {} try: data = json.loads(QGuiApplication.clipboard().text()) except Exception as e: return self.clear_selection() # calculate offset positions = [] for d in data['drawings']: positions.append({'x': d['pos x'], 'y': d['pos y']}) for n in data['nodes']: positions.append({'x': n['position x'], 'y': n['position y']}) offset_for_middle_pos = QPointF(0, 0) if len(positions) > 0: rect = QRectF(positions[0]['x'], positions[0]['y'], 0, 0) for p in positions: x = p['x'] y = p['y'] if x < rect.left(): rect.setLeft(x) if x > rect.right(): rect.setRight(x) if y < rect.top(): rect.setTop(y) if y > rect.bottom(): rect.setBottom(y) offset_for_middle_pos = self.last_mouse_move_pos - rect.center() self.undo_stack.push(Paste_Command(self, data, offset_for_middle_pos))
def paint(self, painter: QPainter, option: QStyleOptionGraphicsItem, widget: QWidget = None): painter.setRenderHint(QPainter.SmoothPixmapTransform) for layer_view in self.layer_views: if layer_view.visible and layer_view.image_view is not None: painter.setOpacity(layer_view.opacity) image_view_origin = layer_view.image_view.spatial.origin painter.drawImage(QPointF(image_view_origin[1], image_view_origin[0]), layer_view.displayed_image)
def draw_NI_extended_background(painter, c, w, h, bounding_rect, title_rect): """ :param painter: painter from paint event :param c: NodeInstance's theme color :param w: width :param h: height :param bounding_rect: NodeInstance's bounding rect :param title_rect: NI's title label's bounding rect """ background_color = QColor(31, 31, 36, 150) body_gradient = QRadialGradient( QPointF(bounding_rect.topLeft().x() + w, bounding_rect.topLeft().y() - h), pythagoras(2 * h, 2 * w)) body_gradient.setColorAt( 0, QColor(c.red() / 10 + 100, c.green() / 10 + 100, c.blue() / 10 + 100, 100)) body_gradient.setColorAt(0.7, background_color) body_gradient.setColorAt(1, background_color) painter.setBrush(body_gradient) painter.setBrush(QColor(28, 28, 28, 170)) pen = QPen(c.darker()) pen.setWidth(1) painter.setPen(pen) body_path = NIPainter_Ghostly.get_extended_body_path(5, w, h) painter.drawPath(body_path)
def _set_renderer(self, renderer): self._svg_item.setSharedRenderer(renderer) size = renderer.defaultSize() scale = self._extent / max(size.width(), size.height()) self._svg_item.setScale(scale) self._svg_item.setPos(self.rect().center() - 0.5 * scale * QPointF(size.width(), size.height()))