Пример #1
0
def draw_snake_spinner(painter, rect, angle, light, dark):
    painter.setRenderHint(QPainter.Antialiasing)

    if rect.width() > rect.height():
        delta = (rect.width() - rect.height()) // 2
        rect = rect.adjusted(delta, 0, -delta, 0)
    elif rect.height() > rect.width():
        delta = (rect.height() - rect.width()) // 2
        rect = rect.adjusted(0, delta, 0, -delta)
    disc_width = max(3, min(rect.width() // 10, 8))

    drawing_rect = QRect(rect.x() + disc_width,
                         rect.y() + disc_width,
                         rect.width() - 2 * disc_width,
                         rect.height() - 2 * disc_width)

    gap = 60  # degrees
    gradient = QConicalGradient(drawing_rect.center(), angle - gap // 2)
    gradient.setColorAt((360 - gap // 2) / 360.0, light)
    gradient.setColorAt(0, dark)

    pen = QPen(QBrush(gradient), disc_width)
    pen.setCapStyle(Qt.RoundCap)
    painter.setPen(pen)
    painter.drawArc(drawing_rect, angle * 16, (360 - gap) * 16)
Пример #2
0
def draw_snake_spinner(painter, rect, angle, light, dark):
    painter.setRenderHint(QPainter.Antialiasing)

    if rect.width() > rect.height():
        delta = (rect.width() - rect.height()) // 2
        rect = rect.adjusted(delta, 0, -delta, 0)
    elif rect.height() > rect.width():
        delta = (rect.height() - rect.width()) // 2
        rect = rect.adjusted(0, delta, 0, -delta)
    disc_width = max(4, rect.width() // 10)

    drawing_rect = QRect(rect.x() + disc_width, rect.y() + disc_width, rect.width() - 2 * disc_width, rect.height() - 2 *disc_width)
    try:
        angle_for_width = math.degrees(math.atan2(1.3 * disc_width, drawing_rect.width()))
    except ZeroDivisionError:
        angle_for_width = 5

    gradient = QConicalGradient(drawing_rect.center(), angle - angle_for_width)
    gradient.setColorAt(1, light)
    gradient.setColorAt(0, dark)

    painter.setPen(QPen(light, disc_width))
    painter.drawArc(drawing_rect, 0, 360 * 16)
    pen = QPen(QBrush(gradient), disc_width)
    pen.setCapStyle(Qt.RoundCap)
    painter.setPen(pen)
    painter.drawArc(drawing_rect, angle * 16, (360 - 2 * angle_for_width) * 16)
Пример #3
0
def draw_snake_spinner(painter, rect, angle, light, dark):
    painter.setRenderHint(QPainter.Antialiasing)

    if rect.width() > rect.height():
        delta = (rect.width() - rect.height()) // 2
        rect = rect.adjusted(delta, 0, -delta, 0)
    elif rect.height() > rect.width():
        delta = (rect.height() - rect.width()) // 2
        rect = rect.adjusted(0, delta, 0, -delta)
    disc_width = max(4, rect.width() // 10)

    drawing_rect = QRect(rect.x() + disc_width, rect.y() + disc_width, rect.width() - 2 * disc_width, rect.height() - 2 *disc_width)
    try:
        angle_for_width = math.degrees(math.atan2(1.3 * disc_width, drawing_rect.width()))
    except ZeroDivisionError:
        angle_for_width = 5

    gradient = QConicalGradient(drawing_rect.center(), angle - angle_for_width)
    gradient.setColorAt(1, light)
    gradient.setColorAt(0, dark)

    painter.setPen(QPen(light, disc_width))
    painter.drawArc(drawing_rect, 0, 360 * 16)
    pen = QPen(QBrush(gradient), disc_width)
    pen.setCapStyle(Qt.RoundCap)
    painter.setPen(pen)
    painter.drawArc(drawing_rect, angle * 16, (360 - 2 * angle_for_width) * 16)
Пример #4
0
def draw_snake_spinner(painter, rect, angle, light, dark):
    painter.setRenderHint(QPainter.Antialiasing)

    if rect.width() > rect.height():
        delta = (rect.width() - rect.height()) // 2
        rect = rect.adjusted(delta, 0, -delta, 0)
    elif rect.height() > rect.width():
        delta = (rect.height() - rect.width()) // 2
        rect = rect.adjusted(0, delta, 0, -delta)
    disc_width = max(3, min(rect.width() // 10, 8))

    drawing_rect = QRect(rect.x() + disc_width, rect.y() + disc_width, rect.width() - 2 * disc_width, rect.height() - 2 *disc_width)

    gap = 60  # degrees
    gradient = QConicalGradient(drawing_rect.center(), angle - gap // 2)
    gradient.setColorAt((360 - gap//2)/360.0, light)
    gradient.setColorAt(0, dark)

    pen = QPen(QBrush(gradient), disc_width)
    pen.setCapStyle(Qt.RoundCap)
    painter.setPen(pen)
    painter.drawArc(drawing_rect, angle * 16, (360 - gap) * 16)
    def draw(self, event, qp):
        #         self.angle += 0.04
        #         self._set_current_angle_in_radians(self.angle)

        #--------------------------------------------------------------------
        # Draw X axis
        #--------------------------------------------------------------------
        pen = QPen(QColor(120, 120, 120))
        pen.setWidth(2)
        pen.setCapStyle(Qt.RoundCap)
        qp.setPen(pen)
        qp.drawLine(0, self.x_axis_y_coordinate,
                    self.width() - self.x_axis_offset_from_right,
                    self.x_axis_y_coordinate)

        #--------------------------------------------------------------------
        # Draw rectangle that will have the vector's shadow
        #--------------------------------------------------------------------
        pen = QPen(QColor(100, 100, 100))
        pen.setWidth(2)
        pen.setCapStyle(Qt.RoundCap)
        qp.setPen(pen)
        qp.setOpacity(0.2)
        qp.drawRect(
            self.width() - self.x_axis_offset_from_right -
            self.pen_width // 2 - 2, self.x_axis_y_coordinate -
            self.amplitude - self.pen_width // 2 - 2, self.pen_width + 2,
            self.amplitude * 2 + self.pen_width + 2)
        qp.setOpacity(1)

        #--------------------------------------------------------------------
        # Draw vector shadow, if enabled
        #--------------------------------------------------------------------
        if self.draw_shadow:
            pen = QPen(QColor(220, 20, 20))
            pen.setWidth(2)
            pen.setCapStyle(Qt.RoundCap)
            qp.setPen(pen)
            qp.setBrush(QColor(220, 20, 20))
            qp.setOpacity(1)
            qp.drawRect(
                self.width() - self.x_axis_offset_from_right -
                self.pen_width // 2,
                self.x_axis_y_coordinate - self.current_height, self.pen_width,
                self.current_height)
            qp.setOpacity(1)

        #--------------------------------------------------------------------
        # Draw rotating vector, if enabled
        #--------------------------------------------------------------------
        if self.draw_rotating_vector:
            vector_origin = Point()
            vector_origin.x = self.width(
            ) - self.x_axis_offset_from_right + 20 + self.amplitude
            vector_origin.y = self.x_axis_y_coordinate

            vector_width = self.amplitude * math.cos(
                self.current_angle_in_radians)
            vector_height = self.amplitude * math.sin(
                self.current_angle_in_radians)

            vector_tip = Point()
            vector_tip.x = vector_origin.x + vector_width
            vector_tip.y = vector_origin.y - vector_height

            #----------------------------------------------------
            # Draw vector axis and tracing circle
            pen = QPen(QColor(120, 120, 120))
            pen.setWidth(2)
            pen.setCapStyle(Qt.RoundCap)
            qp.setPen(pen)
            qp.setBrush(QColor(220, 20, 20))
            qp.setOpacity(0.1)
            qp.drawEllipse(vector_origin.x - self.amplitude,
                           vector_origin.y - self.amplitude,
                           2 * self.amplitude, 2 * self.amplitude)

            qp.setOpacity(0.3)
            # vector's x axis
            qp.drawLine(vector_origin.x - self.amplitude - 10, vector_origin.y,
                        vector_origin.x + self.amplitude + 10, vector_origin.y)
            # vector's y axis
            qp.drawLine(vector_origin.x, vector_origin.y - self.amplitude - 10,
                        vector_origin.x, vector_origin.y + self.amplitude + 10)

            qp.setOpacity(1)

            #----------------------------------------------------
            # Draw vector itself.
            pen = QPen(QColor(220, 20, 20))
            pen.setWidth(self.pen_width)
            pen.setCapStyle(Qt.RoundCap)
            qp.setPen(pen)
            qp.setBrush(QColor(220, 20, 20))
            qp.setOpacity(1)
            qp.drawLine(vector_origin.x, vector_origin.y, vector_tip.x,
                        vector_tip.y)
            qp.setOpacity(1)

            #----------------------------------------------------
            # Draw vector tip projection
            pen = QPen(QColor(20, 20, 20))
            pen.setWidth(self.pen_width)
            pen.setStyle(Qt.DotLine)
            qp.setPen(pen)
            qp.setOpacity(0.2)
            qp.drawLine(vector_tip.x, vector_tip.y,
                        self.width() - self.x_axis_offset_from_right,
                        self.x_axis_y_coordinate - vector_height)
            qp.setOpacity(1)

        #--------------------------------------------------------------------
        # Draw background
        #--------------------------------------------------------------------
        font = QFont()
        font.setPixelSize(30)
        pen = QPen(QColor(100, 100, 100))
        qp.setPen(pen)
        qp.setBrush(Qt.green)
        qp.setFont(font)
        qp.setOpacity(0.2)
        for p in self.bkTextPoints + self.timeTextPoints:
            #             qp.rotate(45)
            qp.drawText(p.x, p.y, p.text)
            #             qp.drawEllipse(p.x, p.y, 50, 30)
            #             qp.rotate(-45)

            #--------------------------------------------------
            # If time isn't paused, shift all background objects left
            if not self.time_paused:
                p.x -= self.time_x_increment
                if p.x <= -150:
                    p.x = 2000

        qp.setOpacity(1)

        #--------------------------------------------------------------------
        # Draw points
        #--------------------------------------------------------------------
        #         pen = QPen(QColor(120, 60, 60))
        pen = QPen(QColor(220, 20, 20))
        pen.setWidth(self.pen_width)
        pen.setCapStyle(Qt.RoundCap)
        qp.setPen(pen)
        #         qp.setBrush(QBrush(Qt.black))

        if not self.time_paused:
            # Copy height of each point to the point on its left (older point)
            for i in reversed(range(len(self.ordinates) - 1)):
                self.ordinates[i + 1] = self.ordinates[i]

        #print("Using current height of " + str(self.current_height))
        self.ordinates[
            0] = -self.current_height  # set height of "current" (rightmost) sample

        for i in range(len(self.ordinates) - 1):
            qp.drawLine(
                self.width() - self.x_axis_offset_from_right -
                i * self.time_x_increment,
                self.ordinates[i] + self.x_axis_y_coordinate,
                self.width() - self.x_axis_offset_from_right -
                (i + 1) * self.time_x_increment,
                self.ordinates[i + 1] + self.x_axis_y_coordinate)
Пример #6
0
class PaintBoard(QLabel):
    signal_right_mouse = pyqtSignal(int)
    signal_draw = pyqtSignal()

    def __init__(self, parent=None):
        super().__init__(parent)
        self.__parent = parent
        self.__board = QPixmap(QSize(440, 440))
        self.__board.fill(Qt.transparent)
        self.__board_old = self.__board.copy()
        self.__board_old_old = self.__board.copy()
        self.__board_before_dots = self.__board.copy()
        self.__thickness = 10  # 默认画笔粗细为10px
        self.__penColor = QColor(0, 0, 0, 128)
        self.__painter = QPainter()
        self.__pen = QPen(self.__penColor, self.__thickness)
        self.__pen_seg = QPen(QColor(0, 0, 0, 128))
        self.__brush = QBrush(QColor(0, 0, 0, 128))
        self.__pen.setCapStyle(Qt.RoundCap)
        #self.__painter.setPen(self.__pen)
        self.__lastPos = QPoint(0, 0)  # 上一次鼠标位置
        self.__currentPos = QPoint(0, 0)  # 当前的鼠标位置
        self.__points = []  # dots模式的点集
        self.__mouse_pressed = False
        self.__can_undo = False
        self.__has_seg = False
        self.__mode = 1
        self.__ERASE = 0
        self.__LINE = 1
        self.__RECT = 2
        self.__CIRCLE = 3
        self.__DOTS = 4
        self.__transparent = False
        self.__trans_board = self.__board.copy()
        self.__trans_board.fill(Qt.transparent)

    @staticmethod
    def dist(p1, p2):
        return math.hypot(p1.x() - p2.x(), p1.y() - p2.y())

    # Each time paintEvent is called it clean the space where it is going to draw.
    # So it does not save memory of the previous drawings,
    # A simple solution is to first paint a QPixmap to store what you have painted.
    # And then paint the widget with that QPixmap.

    def set_trans(self, trans):
        self.__transparent = trans
        self.update()

    def is_trans(self):
        return self.__transparent

    def paintEvent(self, paint_event):  # 把board绘制到界面上
        self.__painter.begin(self)
        if not self.__transparent:
            self.__painter.drawPixmap(0, 0, self.__board)
        else:
            self.__painter.drawPixmap(0, 0, self.__trans_board)  #结果图关闭mask
        self.__painter.end()

    def mousePressEvent(self, mouse_event):
        if mouse_event.button() == Qt.LeftButton:
            self.__mouse_pressed = True
            self.__board_old_old = self.__board_old.copy()
            self.__board_old = self.__board.copy()
            self.__currentPos = mouse_event.pos()
            self.__lastPos = self.__currentPos
            if self.__mode == self.__DOTS:
                if len(self.__points) == 0:
                    self.__board_before_dots = self.__board.copy()
                    self.__parent.childAt(740, 0).setEnabled(False)
                    self.__parent.childAt(840, 0).setEnabled(False)
                    self.__parent.childAt(370, 0).setEnabled(False)
                    self.__parent.childAt(300, 610).setEnabled(False)
                if len(self.__points) > 0:
                    print(
                        self.dist(
                            self.__points[0],
                            QPoint(self.__currentPos.x(),
                                   self.__currentPos.y())))
                if len(self.__points) > 2 and \
                        self.dist(self.__points[0], QPoint(self.__currentPos.x(), self.__currentPos.y())) < 5:
                    self.__board = self.__board_before_dots.copy()
                    self.__painter.begin(self.__board)
                    if self.__ERASE:
                        self.__painter.setCompositionMode(
                            QPainter.CompositionMode_Clear)
                    else:
                        self.__painter.setCompositionMode(
                            QPainter.CompositionMode_Source)
                    self.__painter.setPen(Qt.NoPen)
                    self.__painter.setBrush(self.__brush)
                    self.__painter.drawPolygon(QPolygon(self.__points))
                    self.signal_draw.emit()
                    self.__painter.end()
                    self.__points.clear()
                    self.__parent.childAt(740, 0).setEnabled(True)
                    self.__parent.childAt(840, 0).setEnabled(True)
                    self.__parent.childAt(370, 0).setEnabled(True)
                    self.__parent.childAt(300, 610).setEnabled(True)
                    self.update()
                else:
                    self.__points.append(
                        QPoint(self.__currentPos.x(), self.__currentPos.y()))
            if not (self.__mode == self.__DOTS and len(self.__points) == 1):
                self.__can_undo = True
                self.__parent.childAt(70, 610).setEnabled(True)
            else:
                self.__can_undo = False
                self.__parent.childAt(70, 610).setEnabled(False)

    def mouseMoveEvent(self, mouse_event):  # 把线绘制到board上
        self.__currentPos = mouse_event.pos()
        if self.__mode != self.__LINE:
            if len(self.__points) > 0:
                self.__board = self.__board_old.copy()
            elif not self.__mode == self.__DOTS:
                if self.__mouse_pressed:
                    self.__board = self.__board_old.copy()
        self.__painter.begin(self.__board)
        self.__painter.setPen(self.__pen)
        if self.__ERASE:
            self.__painter.setCompositionMode(QPainter.CompositionMode_Clear)
        else:
            self.__painter.setCompositionMode(QPainter.CompositionMode_Source)
        if self.__mode == self.__LINE:
            if self.__mouse_pressed:
                self.__painter.drawLine(self.__lastPos, self.__currentPos)
                self.signal_draw.emit()
        elif self.__mode == self.__RECT:
            self.__painter.setPen(Qt.NoPen)
            self.__painter.setBrush(self.__brush)
            if self.__mouse_pressed:
                self.__painter.drawRect(
                    self.__lastPos.x(), self.__lastPos.y(),
                    (self.__currentPos.x() - self.__lastPos.x()),
                    (self.__currentPos.y() - self.__lastPos.y()))
                self.signal_draw.emit()
        elif self.__mode == self.__CIRCLE:
            self.__painter.setPen(Qt.NoPen)
            self.__painter.setBrush(self.__brush)
            if self.__mouse_pressed:
                self.__painter.drawEllipse(
                    self.__lastPos.x(), self.__lastPos.y(),
                    (self.__currentPos.x() - self.__lastPos.x()),
                    (self.__currentPos.y() - self.__lastPos.y()))
                self.signal_draw.emit()
        elif self.__mode == self.__DOTS:
            if len(self.__points) > 0:
                self.__painter.setCompositionMode(
                    QPainter.CompositionMode_Source)
                self.__painter.setPen(QPen(self.__pen_seg.color(), 1))
                self.__painter.drawLine(self.__points[-1], self.__currentPos)
                self.signal_draw.emit()

        self.__painter.end()
        if self.__mode == self.__LINE:
            self.__lastPos = self.__currentPos
        self.update()  # 触发paintEvent

    def mouseDoubleClickEvent(self, mouse_event):
        if mouse_event.button() == Qt.LeftButton:
            if not self.__mode == self.__DOTS:
                if self.__has_seg:
                    x = mouse_event.pos().x()
                    y = mouse_event.pos().y()
                    value = self.segment[y][x]  # 注意这里x和y要反过来
                    self.__painter.begin(self.__board)
                    self.paint_segment(value, x, y)
                    self.__painter.end()
                    self.signal_draw.emit()
                    self.update()  # 触发paintEvent

    def mouseReleaseEvent(self, mouse_event):
        if mouse_event.button() == Qt.LeftButton:
            self.__mouse_pressed = False
        if mouse_event.button() == Qt.RightButton:
            self.signal_right_mouse.emit(1 - self.__ERASE)
        return

    def undo(self):
        if self.__can_undo:
            if self.__mode != self.__DOTS:
                self.__board = self.__board_old.copy()
            else:
                if len(self.__points) == 0:
                    self.__board = self.__board_before_dots.copy()
                else:
                    self.__points.pop()
                    self.__board = self.__board_old_old.copy()
                    self.__board_old = self.__board_old_old.copy()
            self.signal_draw.emit()
            self.update()
            self.__can_undo = False
            self.__parent.childAt(70, 610).setEnabled(False)

    def update_segment(self, seg):
        self.segment = seg
        self.__parent.childAt(1040, 0).setEnabled(False)
        self.__has_seg = True

    def set_board(self, x, y):
        self.__board = self.__board.scaled(x, y)

    def update_board(self, board):
        self.__board = board
        self.update()

    def paint_segment(self, value, x, y):
        has_painted = np.zeros(self.segment.shape, dtype=np.uint8)
        point_stack = [(x, y)]
        while len(point_stack) > 0:
            point = point_stack.pop()
            x = point[0]
            y = point[1]
            self.__painter.setPen(self.__pen_seg)
            if self.__ERASE:
                self.__painter.setCompositionMode(
                    QPainter.CompositionMode_Clear)
            else:
                self.__painter.setCompositionMode(
                    QPainter.CompositionMode_Source)
            self.__painter.drawPoint(x, y)
            has_painted[y][x] = 1
            if x + 1 < self.segment.shape[1] and has_painted[y][
                    x + 1] == 0 and value == self.segment[y][x + 1]:
                point_stack.append((x + 1, y))
            if x - 1 >= 0 and has_painted[y][
                    x - 1] == 0 and value == self.segment[y][x - 1]:
                point_stack.append((x - 1, y))
            if y + 1 < self.segment.shape[0] and has_painted[
                    y + 1][x] == 0 and value == self.segment[y + 1][x]:
                point_stack.append((x, y + 1))
            if y - 1 >= 0 and has_painted[
                    y - 1][x] == 0 and value == self.segment[y - 1][x]:
                point_stack.append((x, y - 1))

    def Thanos(self, label):
        if len(label) == 0:
            return False
        image = self.__board.copy()
        image.fill(Qt.transparent)
        pixels = image.toImage()
        s = pixels.bits().asstring(pixels.width() * pixels.height() * 4)
        arr = np.fromstring(s, dtype=np.uint8).reshape(
            (pixels.height(), pixels.width(), 4))
        np.set_printoptions(threshold=sys.maxsize)
        mask = arr[..., 3]
        for l in label:
            mask[self.segment == l] = 255
        expand_mask(mask, 5)
        #Image.fromarray(np.uint8(mask)).save('mask_10.jpg')
        return mask

    def set_seg(self):
        self.__has_seg = False

    def set_pen(self, value):
        self.__pen.setWidth(value)

    def pen_black(self):
        self.__pen.setColor(QColor(0, 0, 0, 128))

    def pen_white(self):
        self.__pen.setColor(QColor(255, 255, 255, 128))

    def geo_black(self):
        self.__pen_seg.setColor(QColor(0, 0, 0, 128))
        self.__brush = QBrush(QColor(0, 0, 0, 128))

    def geo_white(self):
        self.__pen_seg.setColor(QColor(255, 255, 255, 128))
        self.__brush = QBrush(QColor(255, 255, 255, 128))

    def switch_mode(self):
        self.__ERASE = 1 - self.__ERASE

    def set_mode(self, mode):
        self.__ERASE = mode

    def tool_pen(self):
        self.__mode = self.__LINE

    def tool_rect(self):
        self.__mode = self.__RECT

    def tool_circle(self):
        self.__mode = self.__CIRCLE

    def tool_dots(self):
        self.__mode = self.__DOTS

    def clear_board(self):
        self.__board.fill(Qt.transparent)
        self.__board_old = self.__board.copy()
        self.__board_before_dots = self.__board.copy()
        self.__board_old_old = self.__board.copy()
        self.__parent.childAt(70, 610).setEnabled(False)
        self.signal_draw.emit()
        self.update()

    def save(self):
        # save_path = QFileDialog.getSaveFileName(self, 'Save Your Paint', '.\\', '*.jpg')
        save_path = 'D:/test.png', '*.png'
        print(save_path)
        if save_path[0] == "":
            print("Save cancel")
            return
        image = self.__board
        pixels = image.toImage()
        s = pixels.bits().asstring(pixels.width() * pixels.height() * 4)
        arr = np.fromstring(s, dtype=np.uint8).reshape(
            (pixels.height(), pixels.width(), 4))
        np.set_printoptions(threshold=sys.maxsize)
        mask = arr[..., 3]
        print(mask)
        # qimage2numpy(pixels)
        # Pixels can only be accessed through QPainter functions or by converting the QPixmap to a QImage.
        image.save(save_path[0])

    def get_mask(self):
        image = self.__board
        pixels = image.toImage()
        s = pixels.bits().asstring(pixels.width() * pixels.height() * 4)
        arr = np.fromstring(s, dtype=np.uint8).reshape(
            (pixels.height(), pixels.width(), 4))
        np.set_printoptions(threshold=sys.maxsize)
        mask = arr[..., 3]  # 取alpha通道,就是不透明度
        mask[mask > 0] = 255
        return mask

    def get_board(self):
        return self.__board.copy()

    def test(self):
        # self.pix = QPixmap("road.jpg")
        self.__painter.begin(self.__board)
        for i in range(301):
            for j in range(301):
                self.__painter.drawPoint(i, j)
        self.__painter.end()
        self.update()