Esempio n. 1
0
    def build_bonus_fields(self):
        for bonus_field in self._bonus_fields:
            brush = bonus_field["Brush"]
            pen = bonus_field["Pen"]
            bonus_fields = []

            for coords in bonus_field["Coords"]:
                label = bonus_field["Name"]
                if coords == Coords.central():
                    label = '✸'
                square = self._board_squares[coords]
                square.setZValue(2)
                bonus_fields.append(square)
                field_name = QGraphicsSimpleTextItem(label)
                font = field_name.font()
                font.setPointSize(10)
                if coords == Coords.central():
                    font.setPointSize(20)
                fm = QFontMetrics(font)
                field_name.setZValue(2.1)
                field_name.setFont(font)
                x = coords.x * SQUARE_SIZE + (SQUARE_SIZE - fm.width(label)) / 2
                y = coords.y * SQUARE_SIZE + (SQUARE_SIZE - fm.height()) / 2
                field_name.setPos(x, y)
                field_name.setBrush(bonus_field["Label brush"])

                self._labels[(x, y)] = field_name
                self.scene.addItem(field_name)

            paint_graphic_items(bonus_fields, pen, brush)
Esempio n. 2
0
 def createLabel(self) -> QGraphicsSimpleTextItem:
     """
     Returns:
         the label item
     """
     label = QGraphicsSimpleTextItem("%d" % (self._id_num))
     label.setFont(_FONT)
     label.setZValue(styles.ZPATHHELIX)
     label.setParentItem(self)
     return label
Esempio n. 3
0
    def createLabel(self):
        """Summary

        Returns:
            TYPE: Description
        """
        label = QGraphicsSimpleTextItem("%d" % (self._id_num))
        label.setFont(_FONT)
        label.setZValue(styles.ZPATHHELIX)
        label.setParentItem(self)
        return label
Esempio n. 4
0
    def createLabel(self):
        """Summary

        Returns:
            TYPE: Description
        """
        label = QGraphicsSimpleTextItem("%d" % (self._id_num))
        label.setFont(_FONT)
        label.setZValue(styles.ZPATHHELIX)
        label.setParentItem(self)
        return label
Esempio n. 5
0
    def createLabel(self) -> QGraphicsSimpleTextItem:
        """Creates a text label to display the ID number. Font and Z are set
        in gridstyles.

        Returns:
            the label
        """
        label = QGraphicsSimpleTextItem("%d" % self.idNum())
        label.setFont(_FONT)
        label.setZValue(_ZVALUE)
        label.setParentItem(self)
        return label
Esempio n. 6
0
class BasicNode(QGraphicsItemGroup):
    def __init__(self, model, manager, text_color=Qt.black):
        bg_color = model.get_bg_color()
        super(BasicNode, self).__init__()
        self.model = model
        text = model.get_display_text()
        self.manager = manager
        self.setFlag(QGraphicsItem.ItemIsSelectable, True)
        self.setFlag(QGraphicsItem.ItemIsFocusable, True)

        self.text_graph = QGraphicsSimpleTextItem(text)
        self.text_graph.setBrush(text_color)
        bound = self.text_graph.boundingRect()
        r = QPointF(bound.width() / 2, bound.height() / 2)
        text_center = self.text_graph.pos() + r
        self.text_graph.setPos(-text_center)
        self.addToGroup(self.text_graph)

        self.box_graph = BoxOutline(bg_color)
        empty_space = QPointF(UNIT, UNIT)
        newr = (empty_space + r)
        self.box_graph.rect = QRectF(-newr, newr)
        self.addToGroup(self.box_graph)
        self.text_graph.setZValue(1.0)
        self.box_graph.setZValue(0.0)

        self.children = []

    def itemChange(self, change, value):
        if change == QGraphicsItem.ItemSelectedChange:
            self.manager.selection_changed(self, value)
            return value
        else:
            return super(BasicNode, self).itemChange(change, value)

    def get_width(self):
        return self.boundingRect().width()

    def set_left_pos(self, pos):
        pos += QPoint(self.get_width() / 2.0, 0)
        self.setPos(pos)

    def left_pos(self):
        return self.pos() - QPointF(self.get_width() / 2.0, 0)

    def center_pos(self):
        return self.pos()

    def right_pos(self):
        return self.pos() + QPointF(self.get_width() / 2.0, 0)

    """
Esempio n. 7
0
class BasicNode(QGraphicsItemGroup):
    def __init__(self, model, manager, text_color=Qt.black):
        bg_color = model.get_bg_color()
        super(BasicNode, self).__init__()
        self.model = model
        text = model.get_display_text()
        self.manager = manager
        self.setFlag(QGraphicsItem.ItemIsSelectable, True)
        self.setFlag(QGraphicsItem.ItemIsFocusable, True)

        self.text_graph = QGraphicsSimpleTextItem(text)
        self.text_graph.setBrush(text_color)
        bound = self.text_graph.boundingRect()
        r = QPointF(bound.width() / 2, bound.height() / 2)
        text_center = self.text_graph.pos() + r
        self.text_graph.setPos(-text_center)
        self.addToGroup(self.text_graph)

        self.box_graph = BoxOutline(bg_color)
        empty_space = QPointF(UNIT, UNIT)
        newr = (empty_space + r)
        self.box_graph.rect = QRectF(-newr, newr)
        self.addToGroup(self.box_graph)
        self.text_graph.setZValue(1.0)
        self.box_graph.setZValue(0.0)

        self.children = []

    def itemChange(self, change, value):
        if change == QGraphicsItem.ItemSelectedChange:
            self.manager.selection_changed(self, value)
            return value
        else:
            return super(BasicNode, self).itemChange(change, value)

    def get_width(self):
        return self.boundingRect().width()

    def set_left_pos(self, pos):
        pos += QPoint(self.get_width() / 2.0, 0)
        self.setPos(pos)

    def left_pos(self):
        return self.pos() - QPointF(self.get_width() / 2.0, 0)

    def center_pos(self):
        return self.pos()

    def right_pos(self):
        return self.pos() + QPointF(self.get_width() / 2.0, 0)

    """
Esempio n. 8
0
    def init_ui(self):

        scene = QGraphicsScene()
        scene.setBackgroundBrush(QColor(100, 100, 100))
        scene.setItemIndexMethod(QGraphicsScene.BspTreeIndex)

        scene.setSceneRect(scene.itemsBoundingRect())

        self.setDragMode(QGraphicsView.RubberBandDrag)
        self.setViewportUpdateMode(QGraphicsView.FullViewportUpdate)
        self.setRenderHints(QPainter.Antialiasing | QPainter.TextAntialiasing)

        self.frame_item = QGraphicsPixmapItem()

        self.text_item_offset = 0
        self.rect_item_array = []
        self.text_item_array = []
        for i in range(0, 5):
            rect_item = QGraphicsRectItem()
            rect_item.setVisible(False)
            rect_item.setZValue(20.0)
            rect_item.setPen(QPen(Qt.red, 5))
            rect_item.setRect(20, 20, 20, 20)
            scene.addItem(rect_item)
            self.rect_item_array.append(rect_item)
            text_item = QGraphicsSimpleTextItem("")
            text_item.setBrush(QBrush(Qt.red))
            text_item.setZValue(20.0)
            text_item.setPos(10, 50)
            text_item.setFont(QFont("黑体", 32))
            text_item.setVisible(False)
            scene.addItem(text_item)
            self.text_item_array.append(text_item)

        scene.addItem(self.frame_item)

        self.curr_factor = 1.0

        self.setScene(scene)
Esempio n. 9
0
    def init_ui(self):

        scene = QGraphicsScene()
        scene.setBackgroundBrush(QColor(100, 100, 100))
        scene.setItemIndexMethod(QGraphicsScene.BspTreeIndex)

        scene.setSceneRect(scene.itemsBoundingRect())

        self.setDragMode(QGraphicsView.RubberBandDrag)
        self.setViewportUpdateMode(QGraphicsView.FullViewportUpdate)
        self.setRenderHints(QPainter.Antialiasing | QPainter.TextAntialiasing)

        self.frame_item = QGraphicsPixmapItem()

        self.text_item_offset = 0
        self.rect_item_array = []
        self.text_item_array = []
        for i in range(0, 5):
            rect_item = QGraphicsRectItem()
            rect_item.setVisible(False)
            rect_item.setZValue(20.0)
            rect_item.setPen(QPen(Qt.red, 5))
            rect_item.setRect(20, 20, 20, 20)
            scene.addItem(rect_item)
            self.rect_item_array.append(rect_item)
            text_item = QGraphicsSimpleTextItem("")
            text_item.setBrush(QBrush(Qt.red))
            text_item.setZValue(20.0)
            text_item.setPos(10, 50)
            text_item.setFont(QFont("黑体", 24))
            text_item.setVisible(False)
            scene.addItem(text_item)
            self.text_item_array.append(text_item)

        scene.addItem(self.frame_item)

        self.curr_factor = 1.0

        self.setScene(scene)
Esempio n. 10
0
class NodeItem(QGraphicsItem):  # 面向图形界面, 负责控制显示效果
    MIN_SIZE, MAX_SIZE = 10, 100

    press_callback = EMPTY_FUNC
    release_callback = EMPTY_FUNC
    double_click_callback = EMPTY_FUNC
    move_callback = EMPTY_FUNC

    def __init__(self, node_id):
        super().__init__()

        self.setZValue(2)
        self.setAcceptHoverEvents(True)
        self.setFlag(QGraphicsItem.ItemIsMovable)  # 可以移动
        self.setFlag(QGraphicsItem.ItemSendsGeometryChanges)
        self.setCacheMode(QGraphicsItem.DeviceCoordinateCache)

        # 面向UINet 负责增添逻辑操作
        self.node_id = node_id
        self.hover = False
        self.cached_size = None
        self.bounding_rect = QRectF()  # XXX 在重绘时会被更新,重绘前可能会节点可能会被覆盖显示

        # self.call_backs = CallTable()
        self.text_item = QGraphicsSimpleTextItem(self)
        self.text_item.setZValue(3)

        # 面向图形界面, 负责控制显示效果
        self.style = {
            'name': f' {node_id}',
            'color': Qt.white,
            'shape': 'Pie',  # ('Pie', 'Rect', QPixmap)
            'size': 0.5,  # 0~1 的中间值
            'text': '',
            'text_color': Qt.black,
            'show_text': False,
        }

    def type(self) -> int:
        return QGraphicsItem.UserType + abs(hash(NodeItem))

    def boundingRect(self):
        return self.bounding_rect

    def shape(self):
        path = QPainterPath()
        path.addRect(self.bounding_rect)
        return path

    def paint(self, painter, option, widget=None) -> None:
        # 绘制尺寸
        size = threshold(0.0, self.style['size'], 1.0)
        size = size * (self.MAX_SIZE - self.MIN_SIZE) + self.MIN_SIZE
        if size != self.cached_size:
            self.bounding_rect = QRectF(-size / 2, -size / 2, size, size)
            self.cached_size = size
        # 绘制图标或颜色和形状
        if isinstance(self.style['shape'], QPixmap):
            pixmap = self.style['shape']
            painter.drawPixmap(self.bounding_rect, pixmap,
                               QRectF(pixmap.rect()))
        elif self.style['shape'] == 'Pie':
            painter.setBrush(self.style['color'])
            painter.drawEllipse(self.bounding_rect)  # or drawRect
        elif self.style['shape'] == 'Rect':
            painter.setBrush(self.style['color'])
            painter.drawRect(self.bounding_rect)  # or drawRect
        else:
            raise ValueError('未知shape类型', self.style['shape'])
        # 绘制说明
        text = f"{self.style['name']}\n"
        if self.style['show_text'] or self.hover:
            text += str(self.style['text'])

        self.text_item.setPen(self.style['text_color'])
        self.text_item.setText(text)
        self.text_item.show()

    # ------------------------------------------------------------------------------------------------------------------
    def itemChange(self, change, value):
        if change == QGraphicsItem.ItemPositionHasChanged:
            self.style['pos'] = self.pos()  # 更新位置变化
            self.move_callback(self.node_id)
        return super().itemChange(change, value)

    def mousePressEvent(self, event):
        self.press_callback(self.node_id)
        return super().mousePressEvent(event)

    def mouseReleaseEvent(self, event):
        self.release_callback(self.node_id)
        return super().mouseReleaseEvent(event)

    def mouseDoubleClickEvent(self, event):
        self.double_click_callback(self.node_id)
        return super().mouseDoubleClickEvent(event)

    def hoverEnterEvent(self, event):
        self.hover = True
        return super().hoverEnterEvent(event)

    def hoverLeaveEvent(self, event):
        self.hover = False
        return super().hoverLeaveEvent(event)

    # ------------------------------------------------------------------------------------------------------------------
    def setStyle(self, style) -> None:
        for key in self.style:
            if key in style:
                self.style[key] = style[key]
        self.update()

    def checkPos(self, x, y):
        pos = QPointF(x, y)
        if self.pos() != pos:
            self.setPos(pos)
Esempio n. 11
0
 def createLabel(self):
     label = QGraphicsSimpleTextItem("%d" % self._virtual_helix.number())
     label.setFont(_FONT)
     label.setZValue(_ZVALUE)
     label.setParentItem(self)
     return label
Esempio n. 12
0
 def createLabel(self):
     label = QGraphicsSimpleTextItem("%d" % self._virtual_helix.number())
     label.setFont(_FONT)
     label.setZValue(styles.ZPATHHELIX)
     label.setParentItem(self)
     return label
Esempio n. 13
0
class EdgeItem(QGraphicsItem):
    LINE_WIDTH = 1
    OFFSET = 8  # 方向线偏离中心线的距离
    MIN_ARROW_WIDTH, MAX_ARROW_WIDTH = 1, 8

    double_click_callback = EMPTY_FUNC

    def __init__(self, edge_id):
        super().__init__()
        self.setZValue(1)
        self.setFlag(QGraphicsItem.ItemSendsGeometryChanges)
        self.setAcceptHoverEvents(True)

        self.edge_id = edge_id
        self.text_item = QGraphicsSimpleTextItem('', self)
        self.text_item.setZValue(4)

        self.style = {
            'name': f'Edge{edge_id}',
            'color': Qt.black,
            'width': 0.5,  # 0~1 的中间值
            'line': Qt.SolidLine,
            'show_arrow': False,
            'text': '',
            'text_color': Qt.black,
            'show_text': False,
        }
        self.hover = False

    def type(self):
        return QGraphicsItem.UserType + abs(hash(EdgeItem))

    def boundingRect(self):
        return self.bounding_rect

    def shape(self):
        path = QPainterPath()
        path.addPolygon(self.shape_polygon)
        path.closeSubpath()
        return path

    # -------------------------------------------------------------------------
    def adjust(self, src_p: QPointF, dst_p: QPointF):
        self.angle = getAngle(src_p, dst_p)

        self.src_p = src_p
        self.arrow_p = (src_p + 2 * dst_p) / 3  # 箭头开始位置, 前端2/3处
        self.dst_p = dst_p

        W1 = 1 * self.OFFSET
        W2 = 2 * self.OFFSET
        W3 = 3 * self.OFFSET

        vec = getRightOffsetVector(self.angle)
        self.arrow_polygon = QPolygonF([
            src_p + vec * W1, dst_p + vec * W1, self.arrow_p + vec * W2,
            self.arrow_p + vec * W1
        ])

        self.shape_polygon = QPolygonF(
            [src_p, src_p + vec * W2, dst_p + vec * W2, dst_p])

        self.bounding_rect = QRectF(src_p,
                                    dst_p).normalized()  # normalized 正方向
        self.bounding_rect.adjust(-W3, -W3, W3, W3)

        self.text_p = ((src_p + dst_p) / 2) + vec * W1
        self.text_item.setPos(self.text_p)
        self.prepareGeometryChange()

    # -------------------------------------------------------------------------
    def paint(self, painter, option, widget=None):
        if self.style['show_arrow'] or self.hover:
            width = threshold(0.0, self.style['width'], 1.0)
            width = width * (self.MAX_ARROW_WIDTH -
                             self.MIN_ARROW_WIDTH) + self.MIN_ARROW_WIDTH
            painter.setPen(QPen(self.style['color'], width,
                                self.style['line']))
            painter.setBrush(self.style['color'])
            painter.drawPolygon(self.arrow_polygon)
        else:
            # TODO 定制线类型 虚线或实线
            painter.setPen(QPen(Qt.black, self.LINE_WIDTH))
            painter.drawLine(self.src_p, self.dst_p)

        if (self.style['show_arrow']
                and self.style['show_text']) or self.hover:
            self.text_item.setPen(self.style['text_color'])
            self.text_item.setText(
                f"{self.style['name']}\n{self.style['text']}")
            self.text_item.show()
        else:
            self.text_item.hide()

    # -------------------------------------------------------------------------
    def mouseDoubleClickEvent(self, event):
        self.double_click_callback(self.edge_id)
        super().mouseDoubleClickEvent(event)

    def hoverEnterEvent(self, event):
        self.hover = True
        self.update()
        super().hoverEnterEvent(event)

    def hoverLeaveEvent(self, event):
        self.hover = False
        self.update()
        super().hoverLeaveEvent(event)

    # -------------------------------------------------------------------------
    def setStyle(self, style) -> None:
        for key in self.style:
            try:
                self.style[key] = style[key]
            except KeyError:
                pass
        self.update()
Esempio n. 14
0
 def createLabel(self):
     label = QGraphicsSimpleTextItem("%d" % self._virtual_helix.number())
     label.setFont(self._FONT)
     label.setZValue(self._ZVALUE)
     label.setParentItem(self)
     return label
class ClearanceWidthGraph(BaseGraphic):
    def __init__(self, *args):
        super(ClearanceWidthGraph, self).__init__(*args)
        self.dimension_analysis = self.section_analyzer.dimension_analysis
        self.clearance_analysis = self.section_analyzer.clearance_analysis
        self.min_horizontal_clearance = self.dimension_analysis.min_horizontal_clearance
        self.graph_zero = [None, None]
        self.graph_end = [None, None]
        self.clearance_label = QGraphicsSimpleTextItem()
        self.addToGroup(self.clearance_label)
        self.clearance_label.setZValue(1.0)
        self.init_dimension()

    def init_dimension(self):
        super(ClearanceWidthGraph, self).init_dimension()
        height_start = self.dimension_analysis.bounding_rect[2]
        height_end = self.dimension_analysis.bounding_rect[3]
        self.content_height = (height_end - height_start) * self.height_multiplier
        self.update_graph_size()
        self.create_axis()
        self.create_scale()
        self.add_clearance_graph()

    def create_axis(self):
        bounding_end = abs(self.dimension_analysis.bounding_rect[3])
        bounding_start = abs(self.dimension_analysis.bounding_rect[2])
        pen = QPen()
        pen.setWidthF(0.5)
        # horizontal line
        self.graph_zero[0] = self.position[0] + self.margin - self.line_extend
        self.graph_zero[1] = self.position[1] + bounding_start * self.height_multiplier + self.margin
        self.graph_end[0] = self.graph_zero[0] + self.content_width + self.line_extend
        self.graph_end[1] = self.graph_zero[1]
        line_item_horizontal = QGraphicsLineItem(self.graph_zero[0], self.graph_zero[1], self.graph_end[0], self.graph_end[1])
        line_item_horizontal.setPen(pen)
        self.addToGroup(line_item_horizontal)
        center = (self.graph_zero[0] + self.line_extend), self.graph_zero[1]
        y_top = center[1] - (bounding_start*self.height_multiplier)
        y_bottom = center[1]+(bounding_end*self.height_multiplier)
        line_item_vertical = QGraphicsLineItem(center[0], y_top, center[0], y_bottom)
        line_item_vertical.setPen(pen)
        self.addToGroup(line_item_vertical)
        pen_thin = QPen()
        pen_thin.setWidthF(0.2)
        start_graph = center[1] - 10
        while start_graph > center[1] - bounding_start * self.height_multiplier:
            line_item_horizontal = QGraphicsLineItem(self.graph_zero[0], start_graph, self.graph_end[0], start_graph)
            line_item_horizontal.setPen(pen_thin)
            line_item_horizontal.setZValue(-0.5)
            self.addToGroup(line_item_horizontal)
            start_graph -= 10
        start_graph = center[1] + 10
        while start_graph < center[1] + bounding_end * self.height_multiplier:
            line_item_horizontal = QGraphicsLineItem(self.graph_zero[0], start_graph, self.graph_end[0], start_graph)
            line_item_horizontal.setPen(pen_thin)
            line_item_horizontal.setZValue(-0.5)
            self.addToGroup(line_item_horizontal)
            start_graph += 10

    def create_scale(self):
        section_num = len(self.section_analyzer.section_list)
        section_distance = self.section_analyzer.section_distance
        total_distance = section_num * section_distance
        div = int(Math.integer_division(total_distance, 1.0))
        print(total_distance)
        for i in range(div+1):
            x = self.graph_zero[0] + i * self.length_multiplier + self.line_extend
            y = self.graph_zero[1]
            scale_text = QGraphicsSimpleTextItem("%.2f" % float(i))
            scale_text.setPos(x, y)
            self.addToGroup(scale_text)
        start_to_zero = self.graph_zero[1] - self.position[1]
        step = abs(start_to_zero) // 25
        x = self.graph_zero[0] - 15
        y = self.graph_zero[1]
        for i in range(int(step)-1):
            if i > 0:
                value = i * 25 / 100
                scene_y = y - i * 25
                text = QGraphicsSimpleTextItem("-%.2f" % value)
                text.setPos(x, scene_y)
                self.addToGroup(text)
        start_to_zero = self.position[1] + self.height - self.graph_zero[1]
        step = abs(start_to_zero) // 25
        x = self.graph_zero[0] - 15
        y = self.graph_zero[1]
        for i in range(int(step)-1):
            if i > 0:
                value = i * 25 / 100
                scene_y = y + i * 25
                text = QGraphicsSimpleTextItem("%.2f" % value)
                text.setPos(x, scene_y)
                self.addToGroup(text)

    def add_clearance_graph(self):
        print("-----------------------------------------")
        horizontal_clearance = self.clearance_analysis.horizontal_clearance
        x_init = self.graph_zero[0] + self.line_extend
        y_init = self.graph_zero[1]
        for i in range(len(horizontal_clearance)):
            clearance_points = horizontal_clearance[i]
            x = x_init + i * self.dimension_analysis.section_distance * self.length_multiplier
            left = -self.dimension_analysis.domain_length
            right = self.dimension_analysis.domain_length
            if clearance_points[0]:
                left = clearance_points[0]
            if clearance_points[1]:
                right = clearance_points[1]
            clearance = right - left
            y_top = y_init + left * self.height_multiplier
            y_bottom = y_init + right * self.height_multiplier
            pen_red = QPen()
            red = Color.create_qcolor_from_rgb_tuple(Color.red)
            pen_red.setColor(red)
            pen_green = QPen()
            green = Color.create_qcolor_from_rgb_tuple(Color.green)
            pen_green.setColor(green)
            line = QGraphicsLineItem(x, y_top, x, y_bottom)
            if clearance < self.min_horizontal_clearance:
                line.setPen(pen_red)
            else:
                line.setPen(pen_green)
            self.addToGroup(line)
        pass

    def set_distance_pointer(self, distance):
        horizontal_clearance = self.clearance_analysis.horizontal_clearance
        super(ClearanceWidthGraph, self).set_distance_pointer(distance)
        index = int(distance/self.section_distance)
        clearance = None
        if index < len(horizontal_clearance):
            clearance = horizontal_clearance[index]
        x = self.distance_pointer.line().x1()
        y = self.distance_pointer.line().y1() + (self.distance_pointer.line().y2() - self.distance_pointer.line().y1())/8
        self.clearance_label.setPos(x, y)
        if clearance:
            if clearance[1] and clearance[0]:
                distance = clearance[1] - clearance[0]
                self.clearance_label.setText("clearance = %.2f" % distance)
class BaseGraphic(object):
    def __init__(self, *args):
        super(BaseGraphic, self).__init__()
        self.label = args[3]
        self.parent = args[0]
        self.section_analyzer = self.parent.section_analyzer
        self.width = None
        self.height = None
        self.margin = None
        self.position = args[1], args[2]
        self.content_width = None
        self.content_height = None
        self.distance_pointer = None
        self.distance_label = None
        self.section_num = len(self.section_analyzer.section_list)
        self.section_distance = self.section_analyzer.section_distance
        self.length_multiplier = 100.0
        self.height_multiplier = 100.0
        self.line_extend = 20
        self.margin = 50
        self.material_legend = MaterialLegend(self)
        self._inited = False
        self.items = []
        self.add_title()

    def add_title(self):
        if self.label:
            title = QGraphicsSimpleTextItem(self.label)
            title.setPos(self.position[0] + self.margin, self.position[1] + self.line_extend)
            self.addToGroup(title)

    def addToGroup(self, item):
        self.items.append(item)

    def create_distance_pointer(self):
        self.distance_pointer = QGraphicsLineItem()
        pen = QPen()
        pen.setWidthF(1.0)
        pen.setStyle(Qt.DashDotLine)
        color = Color.create_qcolor_from_rgb_tuple_f((1,0,0))
        pen.setColor(color)
        self.distance_pointer.setPen(pen)
        self.distance_pointer.setZValue(1.0)
        self.addToGroup(self.distance_pointer)
        self.distance_label = QGraphicsSimpleTextItem()
        self.distance_label.setZValue(1.0)
        self.addToGroup(self.distance_label)


    def init_dimension(self):
        section_num = len(self.section_analyzer.section_list)
        section_distance = self.section_analyzer.section_distance
        self.content_width = section_num * section_distance * self.length_multiplier
        self.create_distance_pointer()
        self._inited = True

    def update_graph_size(self):
        if self.content_height and self.content_width:
            self.width = self.content_width + self.margin * 2
            self.height = self.content_height + self.margin * 2
        # bounding_rect.setWidth(self.width)
        # bounding_rect.setHeight(self.height)

    def set_distance_pointer(self, distance):
        if self._inited:
            x1 = self.position[0] + self.margin + distance * self.length_multiplier
            y1 = self.position[1]
            x2 = x1
            y2 = y1 + self.height
            self.distance_pointer.setLine(x1, y1, x2, y2)
            self.distance_label.setText("%.2f" % distance)
            self.distance_label.setPos(x2,y2)
        pass

    @staticmethod
    def set_rect_fill(*args):
        if args[0] == 0: #surface color mode
            rect = args[1]
            color = args[2]
            qcolor = Color.create_qcolor_from_rgb_tuple_f(color)
            brush = QBrush(qcolor)
            rect.setBrush(brush)

    def create_legend(self):
        x = self.position[0] + self.width
        y = self.position[1]
        self.material_legend.create_material_legend(x, y)
        for item in self.material_legend.graphic_items:
            self.addToGroup(item)
Esempio n. 17
0
class CameraView(QGraphicsObject):

    font: QFont = QFont("monospace", 16)
    stick_link_requested = pyqtSignal(StickWidget)
    stick_context_menu = pyqtSignal('PyQt_PyObject', 'PyQt_PyObject')
    stick_widgets_out_of_sync = pyqtSignal('PyQt_PyObject')
    visibility_toggled = pyqtSignal()
    synchronize_clicked = pyqtSignal('PyQt_PyObject')
    previous_photo_clicked = pyqtSignal('PyQt_PyObject')
    next_photo_clicked = pyqtSignal('PyQt_PyObject')
    sync_confirm_clicked = pyqtSignal('PyQt_PyObject')
    sync_cancel_clicked = pyqtSignal('PyQt_PyObject')
    first_photo_clicked = pyqtSignal('PyQt_PyObject')
    enter_pressed = pyqtSignal()

    def __init__(self, scale: float, parent: Optional[QGraphicsItem] = None):
        QGraphicsObject.__init__(self, parent)
        self.current_highlight_color = QColor(0, 0, 0, 0)
        self.current_timer = -1
        self.scaling = scale
        self.pixmap = QGraphicsPixmapItem(self)
        self.stick_widgets: List[StickWidget] = []
        self.link_cam_text = QGraphicsSimpleTextItem("Link camera...", self)
        self.link_cam_text.setZValue(40)
        self.link_cam_text.setVisible(False)
        self.link_cam_text.setFont(CameraView.font)
        self.link_cam_text.setPos(0, 0)
        self.link_cam_text.setPen(QPen(QColor(255, 255, 255, 255)))
        self.link_cam_text.setBrush(QBrush(QColor(255, 255, 255, 255)))

        self.show_add_buttons = False
        self.camera = None

        self.setFlag(QGraphicsItem.ItemSendsGeometryChanges, True)
        self.show_stick_widgets = False
        self.setAcceptHoverEvents(True)
        self.stick_edit_mode = False

        self.original_pixmap = self.pixmap.pixmap()

        self.hovered = False

        self.mode = 0  # TODO make enum Mode
        self.click_handler = None
        self.double_click_handler: Callable[[int, int], None] = None

        self.stick_widget_mode = StickMode.Display

        self.highlight_animation = QPropertyAnimation(self, b"highlight_color")
        self.highlight_animation.setEasingCurve(QEasingCurve.Linear)
        self.highlight_animation.valueChanged.connect(
            self.handle_highlight_color_changed)
        self.highlight_rect = QGraphicsRectItem(self)
        self.highlight_rect.setZValue(4)
        self.highlight_rect.setPen(QPen(QColor(0, 0, 0, 0)))
        self.title_btn = Button('btn_title', '', parent=self)
        self.title_btn.setFlag(QGraphicsItem.ItemIgnoresTransformations, False)
        self.title_btn.setZValue(5)
        self.title_btn.setVisible(False)

        self.sticks_without_width: List[Stick] = []
        self.current_image_name: str = ''
        self.control_widget = ControlWidget(parent=self)
        self.control_widget.setFlag(QGraphicsItem.ItemIgnoresTransformations,
                                    False)
        self.control_widget.setVisible(True)
        self._connect_control_buttons()
        self.image_available = True
        self.blur_eff = QGraphicsBlurEffect()
        self.blur_eff.setBlurRadius(5.0)
        self.blur_eff.setEnabled(False)
        self.pixmap.setGraphicsEffect(self.blur_eff)
        self.overlay_message = QGraphicsSimpleTextItem('not available',
                                                       parent=self)
        font = self.title_btn.font
        font.setPointSize(48)
        self.overlay_message.setFont(font)
        self.overlay_message.setBrush(QBrush(QColor(200, 200, 200, 200)))
        self.overlay_message.setPen(QPen(QColor(0, 0, 0, 200), 2.0))
        self.overlay_message.setVisible(False)
        self.overlay_message.setZValue(6)

        self.stick_box = QGraphicsRectItem(parent=self)
        self.stick_box.setFlag(QGraphicsItem.ItemIsMovable, True)
        self.stick_box.setVisible(False)
        self.stick_box_start_pos = QPoint()

    def _connect_control_buttons(self):
        self.control_widget.synchronize_btn.clicked.connect(
            lambda: self.synchronize_clicked.emit(self))
        self.control_widget.prev_photo_btn.clicked.connect(
            lambda: self.previous_photo_clicked.emit(self))
        self.control_widget.next_photo_btn.clicked.connect(
            lambda: self.next_photo_clicked.emit(self))
        self.control_widget.accept_btn.clicked.connect(
            lambda: self.sync_confirm_clicked.emit(self))
        self.control_widget.cancel_btn.clicked.connect(
            lambda: self.sync_cancel_clicked.emit(self))
        self.control_widget.first_photo_btn.clicked.connect(
            lambda: self.first_photo_clicked.emit(self))

    def paint(self, painter: QPainter,
              option: PyQt5.QtWidgets.QStyleOptionGraphicsItem,
              widget: QWidget):
        if self.pixmap.pixmap().isNull():
            return
        painter.setRenderHint(QPainter.Antialiasing, True)

        if self.show_stick_widgets:
            brush = QBrush(QColor(255, 255, 255, 100))
            painter.fillRect(self.boundingRect(), brush)

        if self.mode and self.hovered:
            pen = QPen(QColor(0, 125, 200, 255))
            pen.setWidth(4)
            painter.setPen(pen)

    def boundingRect(self) -> PyQt5.QtCore.QRectF:
        return self.pixmap.boundingRect().united(
            self.title_btn.boundingRect().translated(self.title_btn.pos()))

    def initialise_with(self, camera: Camera):
        if self.camera is not None:
            self.camera.stick_added.disconnect(self.handle_stick_created)
            self.camera.sticks_added.disconnect(self.handle_sticks_added)
            self.camera.stick_removed.disconnect(self.handle_stick_removed)
            self.camera.sticks_removed.disconnect(self.handle_sticks_removed)
            self.camera.stick_changed.disconnect(self.handle_stick_changed)
        self.camera = camera
        self.prepareGeometryChange()
        self.set_image(camera.rep_image, Path(camera.rep_image_path).name)
        self.title_btn.set_label(self.camera.folder.name)
        self.title_btn.set_height(46)
        self.title_btn.fit_to_contents()
        self.title_btn.set_width(int(self.boundingRect().width()))
        self.title_btn.setPos(0, self.boundingRect().height())
        self.control_widget.title_btn.set_label(self.camera.folder.name)
        self.camera.stick_added.connect(self.handle_stick_created)
        self.camera.sticks_added.connect(self.handle_sticks_added)
        self.camera.stick_removed.connect(self.handle_stick_removed)
        self.camera.sticks_removed.connect(self.handle_sticks_removed)
        self.camera.stick_changed.connect(self.handle_stick_changed)

        self.control_widget.set_font_height(32)
        self.control_widget.set_widget_height(
            self.title_btn.boundingRect().height())
        self.control_widget.set_widget_width(int(self.boundingRect().width()))
        self.control_widget.setPos(0,
                                   self.pixmap.boundingRect().height()
                                   )  #self.boundingRect().height())
        self.control_widget.set_mode('view')
        self.update_stick_widgets()

    def set_image(self,
                  img: Optional[np.ndarray] = None,
                  image_name: Optional[str] = None):
        if img is None:
            self.show_overlay_message('not available')
            return
        self.show_overlay_message(None)
        self.prepareGeometryChange()
        barray = QByteArray(img.tobytes())
        image = QImage(barray, img.shape[1], img.shape[0],
                       QImage.Format_BGR888)
        self.original_pixmap = QPixmap.fromImage(image)
        self.pixmap.setPixmap(self.original_pixmap)
        self.highlight_rect.setRect(self.boundingRect())
        self.current_image_name = image_name

    def update_stick_widgets(self):
        stick_length = 60
        for stick in self.camera.sticks:
            sw = StickWidget(stick, self.camera, self)
            sw.set_mode(self.stick_widget_mode)
            self.connect_stick_widget_signals(sw)
            self.stick_widgets.append(sw)
            stick_length = stick.length_cm
        self.update_stick_box()
        self.scene().update()

    def scale_item(self, factor: float):
        self.prepareGeometryChange()
        pixmap = self.original_pixmap.scaledToHeight(
            int(self.original_pixmap.height() * factor))
        self.pixmap.setPixmap(pixmap)
        self.__update_title()

    def set_show_stick_widgets(self, value: bool):
        for sw in self.stick_widgets:
            sw.setVisible(value)
        self.scene().update()

    def hoverEnterEvent(self, e: QGraphicsSceneHoverEvent):
        self.hovered = True
        self.scene().update(self.sceneBoundingRect())

    def hoverLeaveEvent(self, e: QGraphicsSceneHoverEvent):
        self.hovered = False
        self.scene().update(self.sceneBoundingRect())

    def mousePressEvent(self, e: QGraphicsSceneMouseEvent):
        super().mousePressEvent(e)

    def mouseReleaseEvent(self, e: QGraphicsSceneMouseEvent):
        if self.mode == 1:
            self.click_handler(self.camera)

    def mouseDoubleClickEvent(self, event: QGraphicsSceneMouseEvent):
        if self.stick_widget_mode == StickMode.EditDelete:
            x = event.pos().toPoint().x()
            y = event.pos().toPoint().y()
            stick = self.camera.create_new_sticks(
                [(np.array([[x, y - 50], [x, y + 50]]), 3)],
                self.current_image_name)[
                    0]  #self.dataset.create_new_stick(self.camera)
            self.sticks_without_width.append(stick)

    def set_button_mode(self, click_handler: Callable[[Camera], None],
                        data: str):
        self.mode = 1  # TODO make a proper ENUM
        self.click_handler = lambda c: click_handler(c, data)

    def set_display_mode(self):
        self.mode = 0  # TODO make a proper ENUM
        self.click_handler = None

    def _remove_stick_widgets(self):
        for sw in self.stick_widgets:
            sw.setParentItem(None)
            self.scene().removeItem(sw)
            sw.deleteLater()
        self.stick_widgets.clear()

    def handle_stick_created(self, stick: Stick):
        if stick.camera_id != self.camera.id:
            return
        sw = StickWidget(stick, self.camera, self)
        sw.set_mode(self.stick_widget_mode)
        self.connect_stick_widget_signals(sw)
        self.stick_widgets.append(sw)
        self.stick_widgets_out_of_sync.emit(self)
        self.update()

    def handle_stick_removed(self, stick: Stick):
        if stick.camera_id != self.camera.id:
            return
        stick_widget = next(
            filter(lambda sw: sw.stick.id == stick.id, self.stick_widgets))
        self.disconnect_stick_widget_signals(stick_widget)
        self.stick_widgets.remove(stick_widget)
        stick_widget.setParentItem(None)
        self.scene().removeItem(stick_widget)
        stick_widget.deleteLater()
        self.update()

    def handle_sticks_removed(self, sticks: List[Stick]):
        if sticks[0].camera_id != self.camera.id:
            return
        for stick in sticks:
            to_remove: StickWidget = None
            for sw in self.stick_widgets:
                if sw.stick.id == stick.id:
                    to_remove = sw
                    break
            self.stick_widgets.remove(to_remove)
            to_remove.setParentItem(None)
            if self.scene() is not None:
                self.scene().removeItem(to_remove)
            to_remove.deleteLater()
        self.update()

    def handle_sticks_added(self, sticks: List[Stick]):
        if len(sticks) == 0:
            return
        if sticks[0].camera_id != self.camera.id:
            return
        for stick in sticks:
            sw = StickWidget(stick, self.camera, self)
            sw.set_mode(self.stick_widget_mode)
            self.connect_stick_widget_signals(sw)
            self.stick_widgets.append(sw)
        self.update_stick_box()
        self.stick_widgets_out_of_sync.emit(self)
        self.update()

    def connect_stick_widget_signals(self, stick_widget: StickWidget):
        stick_widget.delete_clicked.connect(
            self.handle_stick_widget_delete_clicked)
        stick_widget.stick_changed.connect(self.handle_stick_widget_changed)
        stick_widget.link_initiated.connect(self.handle_stick_link_initiated)
        stick_widget.right_clicked.connect(
            self.handle_stick_widget_context_menu)

    def disconnect_stick_widget_signals(self, stick_widget: StickWidget):
        stick_widget.delete_clicked.disconnect(
            self.handle_stick_widget_delete_clicked)
        stick_widget.stick_changed.disconnect(self.handle_stick_widget_changed)
        stick_widget.link_initiated.disconnect(
            self.handle_stick_link_initiated)
        stick_widget.right_clicked.disconnect(
            self.handle_stick_widget_context_menu)

    def handle_stick_widget_delete_clicked(self, stick: Stick):
        self.camera.remove_stick(stick)

    def set_stick_widgets_mode(self, mode: StickMode):
        self.stick_widget_mode = mode
        for sw in self.stick_widgets:
            sw.set_mode(mode)
        self.set_stick_edit_mode(mode == StickMode.Edit)

    def handle_stick_widget_changed(self, stick_widget: StickWidget):
        self.camera.stick_changed.emit(stick_widget.stick)

    def handle_stick_changed(self, stick: Stick):
        if stick.camera_id != self.camera.id:
            return
        sw = next(
            filter(lambda _sw: _sw.stick.id == stick.id, self.stick_widgets))
        sw.adjust_line()
        sw.update_tooltip()

    def handle_stick_link_initiated(self, stick_widget: StickWidget):
        self.stick_link_requested.emit(stick_widget)

    def get_top_left(self) -> QPointF:
        return self.sceneBoundingRect().topLeft()

    def get_top_right(self) -> QPointF:
        return self.sceneBoundingRect().topRight()

    def highlight(self, color: Optional[QColor]):
        if color is None:
            self.highlight_animation.stop()
            self.highlight_rect.setVisible(False)
            return
        alpha = color.alpha()
        color.setAlpha(0)
        self.highlight_animation.setStartValue(color)
        self.highlight_animation.setEndValue(color)
        color.setAlpha(alpha)
        self.highlight_animation.setKeyValueAt(0.5, color)
        self.highlight_animation.setDuration(2000)
        self.highlight_animation.setLoopCount(-1)
        self.highlight_rect.setPen(QPen(color))
        self.highlight_rect.setVisible(True)
        self.highlight_animation.start()

    @pyqtProperty(QColor)
    def highlight_color(self) -> QColor:
        return self.current_highlight_color

    @highlight_color.setter
    def highlight_color(self, color: QColor):
        self.current_highlight_color = color

    def handle_highlight_color_changed(self, color: QColor):
        self.highlight_rect.setBrush(QBrush(color))
        self.update()

    def handle_stick_widget_context_menu(self, sender: Dict[str, StickWidget]):
        self.stick_context_menu.emit(sender['stick_widget'], self)

    def show_overlay_message(self, msg: Optional[str]):
        if msg is None:
            self.overlay_message.setVisible(False)
            self.blur_eff.setEnabled(False)
            return
        self.overlay_message.setText(msg)
        self.overlay_message.setPos(
            self.pixmap.boundingRect().center() -
            QPointF(0.5 * self.overlay_message.boundingRect().width(), 0.5 *
                    self.overlay_message.boundingRect().height()))
        self.overlay_message.setVisible(True)
        self.blur_eff.setEnabled(True)

    def show_status_message(self, msg: Optional[str]):
        if msg is None:
            self.control_widget.set_title_text(self.camera.folder.name)
        else:
            self.control_widget.set_title_text(msg)

    def update_stick_box(self):
        left = 9000
        right = 0
        top = 9000
        bottom = -1

        for stick in self.camera.sticks:
            left = min(left, min(stick.top[0], stick.bottom[0]))
            right = max(right, max(stick.top[0], stick.bottom[0]))
            top = min(top, min(stick.top[1], stick.bottom[1]))
            bottom = max(bottom, max(stick.top[1], stick.bottom[1]))
        left -= 100
        right += 100
        top -= 100
        bottom += 100
        self.stick_box.setRect(left, top, right - left, bottom - top)
        pen = QPen(QColor(0, 100, 200, 200))
        pen.setWidth(2)
        pen.setStyle(Qt.DashLine)
        self.stick_box.setPen(pen)

    def set_stick_edit_mode(self, is_edit: bool):
        if is_edit:
            self.update_stick_box()
            self.stick_box_start_pos = self.stick_box.pos()
            for sw in self.stick_widgets:
                sw.setParentItem(self.stick_box)
        else:
            offset = self.stick_box.pos() - self.stick_box_start_pos
            for sw in self.stick_widgets:
                stick = sw.stick
                stick.translate(np.array([int(offset.x()), int(offset.y())]))
                sw.setParentItem(self)
                sw.set_stick(stick)
            self.stick_box.setParentItem(None)
            self.stick_box = QGraphicsRectItem(self)
            self.stick_box.setFlag(QGraphicsItem.ItemIsMovable, True)
            self.stick_box.setVisible(False)
        self.stick_box.setVisible(is_edit)

    def keyPressEvent(self, event: QKeyEvent) -> None:
        pass

    def keyReleaseEvent(self, event: QKeyEvent) -> None:
        if event.key() in [Qt.Key_Right, Qt.Key_Tab, Qt.Key_Space]:
            self.control_widget.next_photo_btn.click_button(True)
        elif event.key() in [Qt.Key_Left]:
            self.control_widget.prev_photo_btn.click_button(True)
        elif event.key() == Qt.Key_S:
            self.enter_pressed.emit()
Esempio n. 18
0
    def mainFunc(self, playing, scriptList, scriptPos):

        if self.inputImg is not None:
            self.outputImg = self.inputImg

            pass_ = 0

            fx = 1.0
            fy = 1.0
            offset_x = 0.0
            offset_y = 0.0
            for i in range(scriptPos):
                widget = scriptList[i][1]
                if widget.objectName() == 'resize':
                    fx *= widget.dblFx.value()
                    fy *= widget.dblFx.value()

                pass_ += widget.pass_
                for item in widget.graphicsItems:
                    try:
                        # ~ print('item.rect() ', item.rect())
                        if fx != 1.0:
                            item.setScale(1 / fx)
                        # ~ if fy != 1.0:
                        # ~ item.setHeight(item.height()/fy)
                        if offset_x:
                            item.setX((item.x() + offset_x) / fx)
                            # ~ item.setX( (item.x() + offset_x)/1.0 )
                            # ~ print('offset_x: ', offset_x, '  fx: ', fx)
                        if offset_y:
                            item.setY((item.y() + offset_y) / fy)
                            # ~ item.setY( (item.y() + offset_y)/1.0 )
                        self.graphicsView.scene().addItem(item)
                        item.setZValue(1)
                    except RuntimeError as e:
                        print(time.time(),
                              'Runtime Error show_graphics_items mainFunc')
                        print(e)

                if widget.objectName() == 'circles':
                    if widget.chkCrop.isChecked():
                        try:
                            circle = widget.graphicsItems[0]
                            # ~ circle = item
                            offset_x = circle.x()
                            offset_x = circle.rect().left()
                            offset_y = circle.y()
                            offset_y = circle.rect().top()
                            # ~ print('offer setter ', offset_x)
                        except IndexError as e:
                            print(e)
            if self.chkShowPass.isChecked():
                # ~ h = self.graphicsView.scene().height()
                # ~ w = self.graphicsView.scene().width()
                h = self.inputImg.shape[0]
                w = self.inputImg.shape[1]

                # ~ sfh = float(h)/float(self.graphicsView.minimumHeight())
                # ~ sfw = float(w)/float(self.graphicsView.minimumWidth())
                # ~ sf = min(sfh,sfw)

                outlineRect = QGraphicsRectItem(0, 0, w, h)
                outlineLine = QGraphicsLineItem(0, h, w, 0)

                font = QFont("DejaVu Sans", 45)

                if pass_ == scriptPos:
                    # the overall result is pass
                    text = 'PASS'
                    pen = QPen(QColor(0, 255, 0), 8)  #green for pass
                    brush = QBrush(QColor(0, 255, 0))

                else:
                    # overall result is fail
                    text = 'FAIL'
                    pen = QPen(QColor(255, 0, 0), 8)  #red for fail
                    brush = QBrush(QColor(255, 0, 0))

                    outlineLine.setPen(pen)
                    self.graphicsView.scene().addItem(outlineLine)
                    outlineLine.setZValue(1)

                outlineRect.setPen(pen)
                self.graphicsView.scene().addItem(outlineRect)
                textItem = QGraphicsSimpleTextItem(text, )
                textItem.setFont(font)
                textItem.setBrush(brush)
                textItem.setPos(w / 10.0, h / 10.0)
                self.graphicsView.scene().addItem(textItem)
                textItem.setZValue(1)
Esempio n. 19
0
class VLineChartView(QChartView):

    bar_hovered = pyqtSignal(bool, str)

    def __init__(self, data: pd.DataFrame):
        super(VLineChartView, self).__init__()
        self._stocks = data
        self._category = self._stocks['trade_date']
        self._chart = QChart()
        self._chart.setAnimationOptions(QChart.SeriesAnimations)
        self._series = QStackedBarSeries()
        # 成交量以万股为单位
        self._vol_multiple = 10000
        self.init_chart()
        self._zero_value = (0, self._chart.axisY().min())
        self._max_value = (len(self._chart.axisX().categories()),
                           self._chart.axisY().max())
        self._zero_point = self._chart.mapToPosition(
            QPointF(self._zero_value[0], self._zero_value[1]))
        self._max_point = self._chart.mapToPosition(
            QPointF(self._max_value[0], self._max_value[1]))
        # 计算x轴单个cate的宽度,用来处理横线不能画到边界
        self._cate_width = (self._max_point.x() - self._zero_point.x()) / len(
            self._category)
        self._series.hovered.connect(self.on_series_hovered)

        x_index_list = np.percentile(range(len(self._category)),
                                     [0, 25, 50, 75, 100])
        self._x_axis_list = [
            QGraphicsSimpleTextItem(self._category[int(index)], self._chart)
            for index in x_index_list
        ]
        [axis.setText(axis.text()[4:]) for axis in self._x_axis_list[1:]]
        self._v_b = QGraphicsSimpleTextItem('B', self._chart)
        self._v_b.setZValue(100)

    def on_series_hovered(self, status, index):
        self.bar_hovered.emit(status, self._category[index])

    def clear_series_value(self):
        self._series.clear()
        self._stocks = None
        self._chart.axisY().setRange(0, 10)
        self._chart.axisX().setCategories(list())

    def add_series_values(self, data: pd.DataFrame, is_init=False):
        self._stocks = data
        bar_red = QBarSet('red')
        bar_red.setColor(Qt.red)
        bar_green = QBarSet('green')
        bar_green.setColor(Qt.green)
        for _, stock in self._stocks.iterrows():
            if stock['open'] < stock['close']:
                bar_red.append(stock['vol'] / self._vol_multiple)
                bar_green.append(0)
            else:
                bar_red.append(0)
                bar_green.append(stock['vol'] / self._vol_multiple)

        self._series.append(bar_red)
        self._series.append(bar_green)

        if not is_init:
            self._stocks = data
            self._category = self._stocks['trade_date']
            axis_x = self._chart.axisX()
            axis_y = self._chart.axisY()
            axis_x.setCategories(self._category)
            max_p = self._stocks[[
                'vol',
            ]].stack().max()
            min_p = self._stocks[[
                'vol',
            ]].stack().min()
            axis_y.setRange(min_p / self._vol_multiple * 0.9,
                            max_p / self._vol_multiple * 1.1)
            self._zero_value = (0, self._chart.axisY().min())
            self._max_value = (len(self._chart.axisX().categories()),
                               self._chart.axisY().max())
            # 计算x轴单个cate的宽度,用来处理横线不能画到边界
            self._cate_width = (self._max_point.x() -
                                self._zero_point.x()) / len(self._category)

    def resizeEvent(self, event):
        super(VLineChartView, self).resizeEvent(event)
        self._zero_point = self._chart.mapToPosition(
            QPointF(self._zero_value[0], self._zero_value[1]))
        self._max_point = self._chart.mapToPosition(
            QPointF(self._max_value[0], self._max_value[1]))
        self._cate_width = (self._max_point.x() - self._zero_point.x()) / len(
            self._category)
        # 绘制自定义X轴
        self._x_axis_list[0].setPos(self._zero_point.x() - self._cate_width,
                                    self._zero_point.y() + 10)
        self._x_axis_list[1].setPos(self._max_point.x() * 0.25,
                                    self._zero_point.y() + 10)
        self._x_axis_list[2].setPos(self._max_point.x() * 0.5,
                                    self._zero_point.y() + 10)
        self._x_axis_list[3].setPos(self._max_point.x() * 0.75,
                                    self._zero_point.y() + 10)
        self._x_axis_list[4].setPos(
            self._max_point.x() - self._x_axis_list[-1].boundingRect().width(),
            self._zero_point.y() + 10)
        # 20180207 这个日期的柱形图上面画一个字母b
        vol = self._stocks[self._stocks['trade_date'] ==
                           '20180207']['vol'] / self._vol_multiple
        print('vol:', vol, ' trade_date:', '20180207')
        pos = self._chart.mapToPosition(
            QPointF(list(self._category).index('20180207'), vol))
        pos = QPointF(pos.x() - self._cate_width / 2,
                      pos.y() - self._v_b.boundingRect().height())
        self._v_b.setPos(pos)

    def max_point(self):
        return QPointF(self._max_point.x() + self._cate_width / 2,
                       self._max_point.y())

    def min_point(self):
        return QPointF(self._zero_point.x() - self._cate_width / 2,
                       self._zero_point.y())

    def init_chart(self):
        self.add_series_values(self._stocks, True)
        self._chart.addSeries(self._series)
        self._chart.createDefaultAxes()
        self._chart.setLocalizeNumbers(True)
        axis_x = self._chart.axisX()
        axis_y = self._chart.axisY()
        axis_x.setGridLineVisible(False)
        axis_y.setGridLineVisible(False)
        axis_y.setLabelFormat("%.2f")
        axis_x.setCategories(self._category)
        axis_x.setLabelsVisible(False)
        max_p = self._stocks[[
            'vol',
        ]].stack().max()
        min_p = self._stocks[[
            'vol',
        ]].stack().min()
        axis_y.setRange(min_p / self._vol_multiple * 0.9,
                        max_p / self._vol_multiple * 1.1)

        # chart的图例
        legend = self._chart.legend()
        legend.hide()
        # 设置图例由Series来决定样式
        # legend.setMarkerShape(QLegend.MarkerShapeFromSeries)

        self.setChart(self._chart)
        self._chart.layout().setContentsMargins(0, 0, 0, 0)
        # 设置内边界的bottom为0
        # margins = self._chart.margins()
        # self._chart.setMargins(QMargins(margins.left(), 0, margins.right(), 0))
        self._chart.setBackgroundRoundness(0)