def __get_index_at(self, p: QPointF): x = p.x() index = round(x) heights = self.bar_item.opts["height"] if 0 <= index < len(heights) and abs(x - index) <= self.bar_width / 2: height = heights[index] # pylint: disable=unsubscriptable-object if 0 <= p.y() <= height or height <= p.y() <= 0: return index return None
def __get_index_at(self, p: QPointF) -> Optional[int]: index = round(p.y()) widths = self.marg_prob_item.opts["width"] if 0 <= index < len(widths) and abs(p.y() - index) <= self.bar_width / 2: width = widths[index] if 0 <= p.x() <= width: return index return None
def _dotAt(self, pos: QPointF): pw, ph = self.__dots.pixelWidth(), self.__dots.pixelHeight() for s in self.__dots.points(): sx, sy = s.pos().x(), s.pos().y() s2x = s2y = s.size() if self.__dots.opts['pxMode']: s2x *= pw s2y *= ph if sx + s2x > pos.x() > sx - s2x and sy + s2y > pos.y() > sy - s2y: return s return None
def path_link_disabled(basepath): # type: (QPainterPath) -> QPainterPath """ Return a QPainterPath 'styled' to indicate a 'disabled' link. A disabled link is displayed with a single disconnection symbol in the middle (--||--) Parameters ---------- basepath : QPainterPath The base path (a simple curve spine). Returns ------- path : QPainterPath A 'styled' link path """ segmentlen = basepath.length() px = 5 if segmentlen < 10: return QPainterPath(basepath) t = (px / 2) / segmentlen p1, _ = qpainterpath_simple_split(basepath, 0.50 - t) _, p2 = qpainterpath_simple_split(basepath, 0.50 + t) angle = -basepath.angleAtPercent(0.5) + 90 angler = math.radians(angle) normal = QPointF(math.cos(angler), math.sin(angler)) end1 = p1.currentPosition() start2 = QPointF(p2.elementAt(0).x, p2.elementAt(0).y) p1.moveTo(start2.x(), start2.y()) p1.addPath(p2) def QPainterPath_addLine(path, line): # type: (QPainterPath, QLineF) -> None path.moveTo(line.p1()) path.lineTo(line.p2()) QPainterPath_addLine(p1, QLineF(end1 - normal * 3, end1 + normal * 3)) QPainterPath_addLine(p1, QLineF(start2 - normal * 3, start2 + normal * 3)) return p1
def path_link_disabled(basepath): """ Return a QPainterPath 'styled' to indicate a 'disabled' link. A disabled link is displayed with a single disconnection symbol in the middle (--||--) Parameters ---------- basepath : QPainterPath The base path (a simple curve spine). Returns ------- path : QPainterPath A 'styled' link path """ segmentlen = basepath.length() px = 5 if segmentlen < 10: return QPainterPath(basepath) t = (px / 2) / segmentlen p1, _ = qpainterpath_simple_split(basepath, 0.50 - t) _, p2 = qpainterpath_simple_split(basepath, 0.50 + t) angle = -basepath.angleAtPercent(0.5) + 90 angler = math.radians(angle) normal = QPointF(math.cos(angler), math.sin(angler)) end1 = p1.currentPosition() start2 = QPointF(p2.elementAt(0).x, p2.elementAt(0).y) p1.moveTo(start2.x(), start2.y()) p1.addPath(p2) def QPainterPath_addLine(path, line): path.moveTo(line.p1()) path.lineTo(line.p2()) QPainterPath_addLine(p1, QLineF(end1 - normal * 3, end1 + normal * 3)) QPainterPath_addLine(p1, QLineF(start2 - normal * 3, start2 + normal * 3)) return p1
def _update_selection(self, p1: QPointF, p2: QPointF, finished: bool): # When finished, emit selection_changed. if len(self.__selection_rects) == 0: return assert self._max_item_width > 0 rect = QRectF(p1, p2).normalized() if self.__orientation == Qt.Vertical: min_max = rect.y(), rect.y() + rect.height() index = int( (p1.x() + self._max_item_width / 2) / self._max_item_width) else: min_max = rect.x(), rect.x() + rect.width() index = int( (-p1.y() + self._max_item_width / 2) / self._max_item_width) index = min(index, len(self.__selection_rects) - 1) index = self._sorted_group_indices[index] self.__selection_rects[index].selection_range = min_max if not finished: return mask = np.bitwise_and(self.__values >= min_max[0], self.__values <= min_max[1]) if self.__group_values is not None: mask = np.bitwise_and(mask, self.__group_values == index) selection = set(np.flatnonzero(mask)) keys = QApplication.keyboardModifiers() if keys & Qt.ShiftModifier: remove_mask = self.__group_values == index selection |= self.__selection - set(np.flatnonzero(remove_mask)) if self.__selection != selection: self.__selection = selection self.selection_changed.emit(sorted(self.__selection), self._selection_ranges)
def indexAt(self, pos: QPointF) -> Optional[int]: """ Return the index of item at `pos`. """ def brect(item): return item.mapRectToParent(item.boundingRect()) if self.__orientation == Qt.Vertical: y = lambda pos: pos.y() else: y = lambda pos: pos.x() top = lambda idx: brect(items[idx]).top() bottom = lambda idx: brect(items[idx]).bottom() items = self.__textitems if not items: return None idx = bisect.bisect_right(_FuncArray(top, len(items)), y(pos)) - 1 if idx == -1: idx = 0 if top(idx) <= y(pos) <= bottom(idx): return idx else: return None
class SquareGraphicsItem(QGraphicsRectItem): """Square Graphics Item. Square component to draw as components for the non-interactive Pythagoras tree. Parameters ---------- tree_node : TreeNode The tree node the square represents. brush : QColor, optional The brush to be used as the backgound brush. pen : QPen, optional The pen to be used for the border. """ def __init__(self, tree_node, parent=None, **kwargs): self.tree_node = tree_node self.tree_node.graphics_item = self center, length, angle = tree_node.square self._center_point = center self.center = QPointF(*center) self.length = length self.angle = angle super().__init__(self._get_rect_attributes(), parent) self.setTransformOriginPoint(self.boundingRect().center()) self.setRotation(degrees(angle)) self.setBrush(kwargs.get('brush', QColor('#297A1F'))) self.setPen(kwargs.get('pen', QPen(QColor('#000')))) self.setAcceptHoverEvents(True) self.setZValue(kwargs.get('zvalue', 0)) self.z_step = Z_STEP # calculate the correct z values based on the parent if self.tree_node.parent != TreeAdapter.ROOT_PARENT: p = self.tree_node.parent # override root z step num_children = len(p.children) own_index = [1 if c.label == self.tree_node.label else 0 for c in p.children].index(1) self.z_step = int(p.graphics_item.z_step / num_children) base_z = p.graphics_item.zValue() self.setZValue(base_z + own_index * self.z_step) def _get_rect_attributes(self): """Get the rectangle attributes requrired to draw item. Compute the QRectF that a QGraphicsRect needs to be rendered with the data passed down in the constructor. """ height = width = self.length x = self.center.x() - self.length / 2 y = self.center.y() - self.length / 2 return QRectF(x, y, height, width)
class SquareGraphicsItem(QGraphicsRectItem): """Square Graphics Item. Square component to draw as components for the non-interactive Pythagoras tree. Parameters ---------- tree_node : TreeNode The tree node the square represents. brush : QColor, optional The brush to be used as the backgound brush. pen : QPen, optional The pen to be used for the border. """ def __init__(self, tree_node, parent=None, **kwargs): self.tree_node = tree_node self.tree_node.graphics_item = self center, length, angle = tree_node.square self._center_point = center self.center = QPointF(*center) self.length = length self.angle = angle super().__init__(self._get_rect_attributes(), parent) self.setTransformOriginPoint(self.boundingRect().center()) self.setRotation(degrees(angle)) self.setBrush(kwargs.get('brush', QColor('#297A1F'))) self.setPen(kwargs.get('pen', QPen(QColor('#000')))) self.setAcceptHoverEvents(True) self.setZValue(kwargs.get('zvalue', 0)) self.z_step = Z_STEP # calculate the correct z values based on the parent if self.tree_node.parent != TreeAdapter.ROOT_PARENT: p = self.tree_node.parent # override root z step num_children = len(p.children) own_index = [ 1 if c.label == self.tree_node.label else 0 for c in p.children ].index(1) self.z_step = int(p.graphics_item.z_step / num_children) base_z = p.graphics_item.zValue() self.setZValue(base_z + own_index * self.z_step) def _get_rect_attributes(self): """Get the rectangle attributes requrired to draw item. Compute the QRectF that a QGraphicsRect needs to be rendered with the data passed down in the constructor. """ height = width = self.length x = self.center.x() - self.length / 2 y = self.center.y() - self.length / 2 return QRectF(x, y, height, width)