예제 #1
0
 def mouseMoveEvent(self, event: QGraphicsSceneMouseEvent):
     box = QRectF(self.buttonDownRect)
     pos = event.pos()
     offset = pos - event.buttonDownPos(Qt.LeftButton)
     if self.handleSelected is None:
         box.translate(offset)
         new_box = box
     elif self.handleSelected == 0:
         pos = box.topLeft() + offset
         new_size = box.bottomRight() - pos
         width = max(new_size.x(), 0)
         height = max(new_size.y(), 0)
         left = min(pos.x(), box.right())
         top = min(pos.y(), box.bottom())
         new_box = QRectF(left, top, width, height)
     elif self.handleSelected == 1:
         pos = box.topLeft() + offset
         height = max(box.bottom() - pos.y(), 0)
         top = min(pos.y(), box.bottom())
         new_box = QRectF(box.left(), top, box.width(), height)
     elif self.handleSelected == 2:
         pos = box.topRight() + offset
         top = min(pos.y(), box.bottom())
         width = max(pos.x() - box.left(), 0)
         height = max(box.bottom() - pos.y(), 0)
         new_box = QRectF(box.left(), top, width, height)
     elif self.handleSelected == 3:
         pos = box.topRight() + offset
         width = max(pos.x() - box.left(), 0)
         new_box = QRectF(box.left(), box.top(), width, box.height())
     elif self.handleSelected == 4:
         pos = box.bottomRight() + offset
         new_size = pos - box.topLeft()
         width = max(new_size.x(), 0)
         height = max(new_size.y(), 0)
         new_box = QRectF(box.left(), box.top(), width, height)
     elif self.handleSelected == 5:
         pos = box.bottomRight() + offset
         height = max(pos.y() - box.top(), 0)
         new_box = QRectF(box.left(), box.top(), box.width(), height)
     elif self.handleSelected == 6:
         pos = box.bottomLeft() + offset
         left = min(pos.x(), box.right())
         width = max(box.right() - pos.x(), 0)
         height = max(pos.y() - box.top(), 0)
         new_box = QRectF(left, box.top(), width, height)
     elif self.handleSelected == 7:
         pos = box.bottomLeft() + offset
         left = min(pos.x(), box.right())
         width = max(box.right() - pos.x(), 0)
         new_box = QRectF(left, box.top(), width, box.height())
     new_box = QRectF(round(new_box.left()), round(new_box.top()),
                      round(new_box.width()), round(new_box.height()))
     self.setRect(new_box)
     self.setHandlesPos()
     self.signalHandler.boxChanged.emit(self.tabIndex, self.rowIndex,
                                        new_box)
예제 #2
0
    def draw_NI_extended_background(painter, c, w, h, bounding_rect: QRectF,
                                    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('#212429')
        header_color = c

        header_height = NIPainter.get_header_rect(w, h, title_rect).height()
        rel_header_height = header_height / h
        gradient = QLinearGradient(bounding_rect.topLeft(),
                                   bounding_rect.bottomLeft())
        gradient.setColorAt(0, header_color)
        gradient.setColorAt(rel_header_height, header_color)
        gradient.setColorAt(rel_header_height + 0.0001, background_color)
        gradient.setColorAt(1, background_color)

        painter.setBrush(QBrush(background_color))
        painter.setPen(Qt.NoPen)  # QPen(c.darker()))
        painter.drawRoundedRect(
            QRectF(
                QPointF(bounding_rect.left(),
                        bounding_rect.top() + header_height),
                bounding_rect.bottomRight()), 6, 6)
예제 #3
0
    def anchorPos(self, rect: QtCore.QRectF) -> QtCore.QPointF:
        if isinstance(self.anchor, QtCore.Qt.Corner):
            if self.anchor == QtCore.Qt.TopLeftCorner:
                pos = rect.topLeft()
            elif self.anchor == QtCore.Qt.TopRightCorner:
                pos = rect.topRight()
            elif self.anchor == QtCore.Qt.BottomLeftCorner:
                pos = rect.bottomLeft()
            else:  # BottomRightCorner
                pos = rect.bottomRight()
        else:  # AnchorPoint
            if self.anchor == QtCore.Qt.AnchorTop:
                pos = QtCore.QPointF(rect.center().x(), rect.top())
            elif self.anchor == QtCore.Qt.AnchorLeft:
                pos = QtCore.QPointF(rect.left(), rect.center().y())
            elif self.anchor == QtCore.Qt.AnchorRight:
                pos = QtCore.QPointF(rect.right(), rect.center().y())
            elif self.anchor == QtCore.Qt.AnchorBottom:
                pos = QtCore.QPointF(rect.center().x(), rect.bottom())
            else:
                raise ValueError(
                    "Only Top, Left, Right, Bottom anchors supported.")

        return pos
    def paint(self, painter: QPainter, option: QStyleOptionGraphicsItem, widget: QWidget = None):
        # setup border pen
        pen = painter.pen()
        pen.setWidthF(self.monitor_border_width)
        pen.setCapStyle(Qt.FlatCap)
        painter.setPen(pen)

        # create monitor_rect
        rect_monitor = QRectF(0, 0,
                              self.monitor.screen_width, self.monitor.screen_height)

        # Draw gradient in the background
        gradient = QLinearGradient(rect_monitor.topRight(), rect_monitor.bottomLeft())
        gradient.setColorAt(0.0, self.monitor_color_gradient_top)
        gradient.setColorAt(1.0, self.monitor_color_gradient_bottom)
        painter.fillRect(rect_monitor, gradient)

        # draw monitor label
        self.draw_monitor_label(painter, rect_monitor, self.index)

        # draw borders inside monitor_rect
        border_offset = painter.pen().widthF() / 2
        border_rect = rect_monitor.adjusted(border_offset, border_offset, -border_offset, border_offset)
        painter.drawRect(border_rect)
예제 #5
0
    def getObjectInteraction(self, persons, objects, interaction, d):

        # print("getObjectInteration")
        plt.close('all')

        polylines_object = []
        polylines_interacting = []

        for o in objects:
            obj = Object(o.x / 1000., o.z / 1000., o.angle, o.space)
            # print("OBJETO")
            ##para dibujarlo
            if d:
                plt.figure('ObjectSpace')
                rect = plt.Rectangle((obj.x - 0.25, obj.y - 0.25),
                                     0.5,
                                     0.5,
                                     fill=False)

                plt.gca().add_patch(rect)
                x_aux = obj.x + 0.25 * cos(pi / 2 - obj.th)
                y_aux = obj.y + 0.25 * sin(pi / 2 - obj.th)
                heading = plt.Line2D((obj.x, x_aux), (obj.y, y_aux),
                                     lw=1,
                                     color='k')
                plt.gca().add_line(heading)

            w = 1.0
            # print (obj.x,obj.y)
            ##para calcular el rectangulo
            s = QRectF(QPointF(0, 0), QSizeF(w, obj.sp))

            # if (d):
            #     plt.plot (s.bottomLeft().x(),s.bottomLeft().y(),"go")
            #     plt.plot(s.bottomRight().x(), s.bottomRight().y(), "ro")
            #     plt.plot(s.topRight().x(), s.topRight().y(), "yo")
            #     plt.plot(s.topLeft().x(), s.topLeft().y(), "bo")

            space = QPolygonF()
            space.append(s.topLeft())
            space.append(s.topRight())
            space.append(
                QPointF(s.bottomRight().x() + obj.sp / 4,
                        s.bottomRight().y()))
            space.append(
                QPointF(s.bottomLeft().x() - obj.sp / 4,
                        s.bottomLeft().y()))

            t = QTransform()
            t.translate(-w / 2, 0)
            space = t.map(space)
            t = QTransform()
            t.rotateRadians(-obj.th)
            space = t.map(space)

            t = QTransform()
            t.translate(obj.x, obj.y)
            space = t.map(space)

            # points = []
            # for x in xrange(space.count()-1):
            #     point = space.value(x)
            #     print ("valor", point)
            #     points.append([point.x(),point.y()])
            #     plt.plot(point.x(),point.y(),"go")

            polyline = []

            for x in range(space.count()):
                point = space.value(x)
                if (d):
                    plt.plot(point.x(), point.y(), "go")

                p = SNGPoint2D()
                p.x = point.x()
                p.z = point.y()
                polyline.append([p.x, p.z])

            polylines_object.append(polyline)

            for p in persons:
                pn = Person(p.x, p.z, p.angle)
                # print("PERSONA", persons.index(p)+1)
                if d:
                    body = plt.Circle((pn.x, pn.y), radius=0.3, fill=False)
                    plt.gca().add_patch(body)

                    x_aux = pn.x + 0.30 * cos(pi / 2 - pn.th)
                    y_aux = pn.y + 0.30 * sin(pi / 2 - pn.th)
                    heading = plt.Line2D((pn.x, x_aux), (pn.y, y_aux),
                                         lw=1,
                                         color='k')
                    plt.gca().add_line(heading)
                    plt.axis('equal')

                ##CHECKING THE ORIENTATION
                print("obj.angle", obj.th, "person.angle", pn.th)
                a = abs(obj.th - abs(pn.th - math.pi))
                if a < math.radians(45):
                    checkangle = True
                else:
                    checkangle = False

                ##CHECKING IF THE PERSON IS INSIDE THE POLYGON
                if space.containsPoint(QPointF(pn.x, pn.y),
                                       Qt.OddEvenFill):  # and checkangle:
                    print("DENTROOOOO Y MIRANDO")
                    if not polyline in polylines_interacting:
                        polylines_interacting.append(polyline)

        if d:
            for ps in polylines_interacting:
                #  plt.figure()
                for p in ps:
                    plt.plot(p.x, p.z, "ro")
                    plt.axis('equal')
                    plt.xlabel('X')
                    plt.ylabel('Y')
            plt.show()
        plt.show()

        if (interaction):
            return polylines_interacting
        else:
            return polylines_object
예제 #6
0
class Room:
    def __init__(self, type='genericRoom', p=QPointF(), w=-1, h=-1):
        self.type = type  # corridor, bedroom, kitchen, bathroom, etc
        self.width = w
        self.height = h
        self.initial_point = p
        self.room_qrect = QRectF()
        self.room_qpolygon = QPolygonF()
        self.area = -1
        self.door_position = None
        self.create_room()

    def create_room(self):
        print(
            f'Creating room of type {self.type} with width = {self.width} and height = {self.height}'
        )
        self.room_qrect = QRectF(self.initial_point.x(),
                                 self.initial_point.y(), self.width,
                                 self.height)
        self.room_qpolygon = QPolygonF(self.room_qrect)
        self.area = abs(self.width * self.height)

    def update_room_dimensions(self):
        self.width = self.room_qrect.width()
        self.height = self.room_qrect.height()
        self.area = abs(self.width * self.height)
        self.room_qpolygon = QPolygonF(self.room_qrect)

    def add_door(self, door_location):
        self.door_position = door_location

        # Diferenciar entre parte de arriba y parte de abajo
        dict_location_line = {
            'top':
            QLineF(self.room_qrect.topLeft(), self.room_qrect.topRight()),
            'bottom':
            QLineF(self.room_qrect.bottomLeft(),
                   self.room_qrect.bottomRight()),
            'left':
            QLineF(self.room_qrect.topLeft(), self.room_qrect.bottomLeft()),
            'right':
            QLineF(self.room_qrect.topRight(), self.room_qrect.bottomRight())
        }

        line = dict_location_line[door_location]
        line_lenght = int(line.length())
        step = line_lenght / 100.

        line_points = []
        for t in np.arange(0.25, 0.75, step):
            line_point = line.pointAt(t)
            line_points.append(QPointF(line_point.x(), line_point.y()))

        door = random.choice(line_points)

        room_polygon = {
            'top':
            QPolygonF([
                QPointF(door.x() + 0.5, door.y()),
                self.room_qrect.topRight(),
                self.room_qrect.bottomRight(),
                self.room_qrect.bottomLeft(),
                self.room_qrect.topLeft(),
                QPointF(door.x() - 0.5, door.y())
            ]),
            'bottom':
            QPolygonF([
                QPointF(door.x() + 0.5, door.y()),
                self.room_qrect.bottomRight(),
                self.room_qrect.topRight(),
                self.room_qrect.topLeft(),
                self.room_qrect.bottomLeft(),
                QPointF(door.x() - 0.5, door.y())
            ]),
            'right':
            QPolygonF([
                QPointF(door.x(),
                        door.y() + 0.5),
                self.room_qrect.topRight(),
                self.room_qrect.topLeft(),
                self.room_qrect.bottomLeft(),
                self.room_qrect.bottomRight(),
                QPointF(door.x(),
                        door.y() - 0.5)
            ]),
            'left':
            QPolygonF([
                QPointF(door.x(),
                        door.y() + 0.5),
                self.room_qrect.topLeft(),
                self.room_qrect.topRight(),
                self.room_qrect.bottomRight(),
                self.room_qrect.bottomLeft(),
                QPointF(door.x(),
                        door.y() - 0.5)
            ])
        }

        self.room_qpolygon = room_polygon[door_location]
예제 #7
0
class Apartment:
    def __init__(self, coppelia_, n_rooms):

        self.coppelia = coppelia_

        self.num_rooms = n_rooms
        self.max_rooms_per_side = math.ceil(self.num_rooms / 2)

        self.initial_corridor_width = -1
        self.initial_corridor_height = -1

        self.initial_corridor = QRectF()

        self.fixed_height = random.uniform(4, 6)

        # Almacena los indices de las habitaciones que tendrán a su izquierda un pasillo
        self.dict_corridors_index_per_side = {'bottom': [], 'top': []}
        self.dict_rooms_per_side = {'bottom': [], 'top': []}
        self.dict_rooms_and_corridors_per_side = {'bottom': [], 'top': []}

        # Lista final una vez hechas todas las transformaciones
        self.total_rooms_and_corridors = []

        self.create_initial_corridor()
        self.select_side_corridors()

        self.get_random_rooms()
        self.adjust_rooms()  # to avoid narrow corridors

        self.add_doors()
        self.center_apartment()
        self.add_floor_per_room()
        self.add_walls()

    def create_initial_corridor(self):
        self.initial_corridor_height = random.uniform(1.5, 3)
        self.initial_corridor_width = random.uniform(self.num_rooms * 4 / 2,
                                                     self.num_rooms * 8 / 2)

        self.initial_corridor = QRectF(
            0, 0, self.initial_corridor_width, -self.initial_corridor_height
        )  # - height para que la parte de arriba sea el top
        self.initial_corridor.translate(-self.initial_corridor.center())

    def select_side_corridors(self):
        # -1 sin pasillo, 0 antes de la primera habitacion, 1 antes de la segunda
        corridor_position = np.arange(-1, self.max_rooms_per_side)

        possibles_corridors_per_side = round(self.max_rooms_per_side / 2)

        if possibles_corridors_per_side == 0:
            possibles_corridors_per_side = 1

        self.dict_corridors_index_per_side['top'] = random.sample(
            list(corridor_position), k=possibles_corridors_per_side)
        self.dict_corridors_index_per_side['bottom'] = random.sample(
            list(corridor_position), k=possibles_corridors_per_side)

        while -1 in self.dict_corridors_index_per_side['top']:
            self.dict_corridors_index_per_side['top'].remove(-1)

        while -1 in self.dict_corridors_index_per_side['bottom']:
            self.dict_corridors_index_per_side['bottom'].remove(-1)

        print('posicion pasillo parte superior',
              self.dict_corridors_index_per_side['top'])
        print('posicion pasillo parte inferior',
              self.dict_corridors_index_per_side['bottom'])

    def get_random_rooms(self):

        dict_opposite_side = {'bottom': 'top', 'top': 'bottom'}

        for i in range(0, self.num_rooms):

            random_side = random.choice(['top', 'bottom'])

            if len(self.dict_rooms_per_side[random_side]
                   ) >= self.max_rooms_per_side:
                random_side = dict_opposite_side[random_side]

            # El indice de mi habitacion está en la lista de pasillos por indice luego tengo que añadir un pasillo a
            # su izquierda
            if len(self.dict_rooms_per_side[random_side]
                   ) in self.dict_corridors_index_per_side[random_side]:
                self.add_corridor(random_side, self.initial_corridor_height,
                                  self.fixed_height)

            if len(self.dict_rooms_and_corridors_per_side[random_side]) == 0:

                if random_side == 'bottom':
                    initial_point = self.initial_corridor.bottomLeft()
                else:
                    initial_point = self.initial_corridor.topLeft() + QPointF(
                        0, self.fixed_height)

            else:
                initial_point = self.dict_rooms_and_corridors_per_side[
                    random_side][-1].room_qrect.topRight()

            room = Room(type='genericRoom',
                        p=initial_point,
                        w=random.uniform(4, 8),
                        h=-self.fixed_height)

            self.dict_rooms_and_corridors_per_side[random_side].append(room)
            self.dict_rooms_per_side[random_side].append(room)

        for room_location in ['top', 'bottom']:
            if len(self.dict_rooms_per_side[room_location]
                   ) in self.dict_corridors_index_per_side[room_location]:
                try:
                    if self.dict_rooms_and_corridors_per_side[room_location][
                            -1].type != 'corridor':
                        self.add_corridor(random_side,
                                          self.initial_corridor_height,
                                          self.fixed_height)
                except:
                    print('there isnt rooms in this side of the corridor')

    def add_corridor(self, side, corridor_width, corridor_height):

        if len(self.dict_rooms_and_corridors_per_side[side]) == 0:

            if side == 'bottom':
                initial_point = self.initial_corridor.bottomLeft()
            else:
                initial_point = self.initial_corridor.topLeft() + QPointF(
                    0, self.fixed_height)

        else:
            initial_point = self.dict_rooms_and_corridors_per_side[side][
                -1].room_qrect.topRight()

        corridor = Room(type='corridor',
                        p=initial_point,
                        w=corridor_width,
                        h=-corridor_height)

        self.dict_rooms_and_corridors_per_side[side].append(corridor)

    def adjust_rooms(self):

        if self.num_rooms == 1:
            return

        dict_side_width = {'bottom': 0., 'right': 0., 'top': 0., 'left': 0.}

        for side, rooms in self.dict_rooms_per_side.items():
            print(f' side {side} has {len(rooms)} rooms ')
            for room in rooms:
                r = room.room_qrect
                dict_side_width[side] += r.width()

        diff = abs(dict_side_width['top'] - dict_side_width['bottom'])

        dict_opposite_side = {
            'bottom': 'top',
            'right': 'left',
            'top': 'bottom',
            'left': 'right'
        }

        if dict_side_width['top'] > dict_side_width['bottom']:
            print('top side is longer')
            side_to_modify = 'bottom'
        else:
            print('bottom side is longer')
            side_to_modify = 'top'

        print(f'--- Modifying {side_to_modify} room ---')

        room_to_modify = self.dict_rooms_and_corridors_per_side[
            side_to_modify][-1]
        opposite_room = self.dict_rooms_and_corridors_per_side[
            dict_opposite_side[side_to_modify]][-1]

        my_side_right = room_to_modify.room_qrect.topRight()
        opposite_side_right = opposite_room.room_qrect.topRight()

        if room_to_modify.type == 'corridor':
            print(f' Room of type {room_to_modify.type} ')

            room_to_modify.room_qrect.setTopRight(
                QPointF(opposite_side_right.x(), my_side_right.y()))

            self.dict_rooms_and_corridors_per_side[side_to_modify][
                -1] = room_to_modify
            self.dict_rooms_and_corridors_per_side[side_to_modify][
                -1].update_room_dimensions()

        else:
            if diff < self.initial_corridor_height:
                print('widening room')
                num_corridors_to_add = 0
            else:
                print('widening room and creating corridor')
                num_corridors_to_add = 1

            print(
                f' Room of type {room_to_modify.type}  -- adding {num_corridors_to_add} corridors'
            )

            room_to_modify.room_qrect.setTopRight(
                QPointF(
                    opposite_side_right.x() -
                    num_corridors_to_add * self.initial_corridor_height,
                    my_side_right.y()))
            self.dict_rooms_and_corridors_per_side[side_to_modify][
                -1] = room_to_modify
            self.dict_rooms_and_corridors_per_side[side_to_modify][
                -1].update_room_dimensions()

            if num_corridors_to_add > 0:
                self.add_corridor(side=side_to_modify,
                                  corridor_width=num_corridors_to_add *
                                  self.initial_corridor_height,
                                  corridor_height=self.fixed_height)

    def add_doors(self):
        opposite = {'bottom': 'top', 'top': 'bottom'}

        for current_side, rooms in self.dict_rooms_per_side.items():

            for i, room in enumerate(rooms):

                possibles_door_locations = [opposite[current_side]]

                if i in self.dict_corridors_index_per_side[
                        current_side]:  # Pasillo a la izquierda
                    possibles_door_locations.append('left')

                if i + 1 in self.dict_corridors_index_per_side[current_side]:
                    possibles_door_locations.append('right')

                door_location = random.choice(possibles_door_locations)
                room.add_door(door_location)

    def center_apartment(self):
        union_polygon = QPolygonF()

        for list in self.dict_rooms_and_corridors_per_side.values():
            for room in list:
                union_polygon = union_polygon.united(
                    room.room_qpolygon)  # Para obtener el bounding box
                self.total_rooms_and_corridors.append(room)

        self.initial_corridor.setLeft(union_polygon.boundingRect().left())
        self.initial_corridor.setRight(union_polygon.boundingRect().right())

        self.total_rooms_and_corridors.append(
            Room(type='corridor',
                 p=self.initial_corridor.topLeft(),
                 w=self.initial_corridor.width(),
                 h=self.initial_corridor.height()))

        union_polygon = union_polygon.united(self.initial_corridor)

        initial_center = union_polygon.boundingRect().center()
        union_polygon.translate(-initial_center)

        self.apartment_boundingRect = union_polygon.boundingRect()

        # Desplazo habitaciones y pasillos al centro
        for i, room in enumerate(self.total_rooms_and_corridors):
            room.room_qpolygon.translate(
                -initial_center
            )  # Desplazo los poligonos para que la habitación esté centrada
            room.room_qrect.translate(-initial_center)

    def add_walls(self):

        for i, room in enumerate(self.total_rooms_and_corridors):
            walls = []
            if room.type == 'corridor':
                continue

            polygon = room.room_qpolygon

            prev_point = polygon[0]
            for i, curr_point in enumerate(polygon):
                if i == 0:
                    continue
                walls.append(([prev_point.x(),
                               prev_point.y(),
                               .425], [curr_point.x(),
                                       curr_point.y(), .425]))
                prev_point = curr_point

            room.walls = walls

            wall_thread = WallCreator(data, walls)
            wall_thread.start()

        walls = []

        polygon_br = QPolygonF(self.apartment_boundingRect, closed=True)
        prev_point_br = polygon_br[0]
        for i, curr_point_br in enumerate(polygon_br):
            if i == 0:
                continue

            walls.append(([prev_point_br.x(),
                           prev_point_br.y(),
                           .4], [curr_point_br.x(),
                                 curr_point_br.y(), .4]))
            prev_point_br = curr_point_br

        wall_thread = WallCreator(data, walls)
        wall_thread.start()

    def add_floor(self):  # un suelo conjunto para el apartamento

        fscale_x = self.apartment_boundingRect.width() / 5 + 0.5
        fscale_y = self.apartment_boundingRect.height() / 5 + 0.5

        # Create and scale a floor
        r = self.coppelia.create_model(
            'models/infrastructure/floors/5mX5m wooden floor.ttm', 0, 0, 0, 0)

        self.coppelia.scale_object(r, fscale_x, fscale_y, 1)
        for handle in self.coppelia.get_objects_children(r):
            self.coppelia.scale_object(handle, fscale_x, fscale_y, 1)

    def add_floor_per_room(self):

        for room in self.total_rooms_and_corridors:

            room_boundingRect = room.room_qpolygon.boundingRect()
            room_center = room_boundingRect.center()

            fscale_x = room_boundingRect.width() / 5
            fscale_y = room_boundingRect.height() / 5

            if room.type == 'corridor':
                floor = self.coppelia.create_model(
                    'models/infrastructure/floors/5mX5m wooden floor.ttm',
                    room_center.x(), room_center.y(), 0, 0)
            else:
                floor = self.coppelia.create_model(
                    'models/infrastructure/floors/5mX5m concrete floor.ttm',
                    room_center.x(), room_center.y(), 0, 0)

            self.coppelia.scale_object(floor, fscale_x, fscale_y, 1)
class QSlideNavigationBar(QWidget):
    class ItemLineStyle(Enum):
        ItemNone = 1
        ItemTop = 2
        ItemRight = 3
        ItemBottom = 4
        ItemLeft = 5
        ItemRect = 6

    itemClicked = Signal(int, str)

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

        # -------成员变量定义------------#
        # ==========属性=========#
        self._m_bar_start_color = QColor('#511235')  # type: QColor  # 导航栏起始颜色
        self._m_bar_end_color = QColor('#150507')  # type: QColor  # 导航栏结束颜色
        self._m_bar_radius = 0  # type: int     # 导航栏四个角的圆弧半径
        self._m_item_start_color = QColor(255, 255, 255, 50)  # type: QColor  # item 的起始颜色
        self._m_item_end_color = QColor("black")  # type: QColor  # item 的结束颜色
        self._m_current_hover_index = -1  # type: int    # 当前光标所在的item的index
        self._m_item_hover_start_color = QColor(255, 0, 0, 25)  # type: QColor   # 光标所在的item 的起始颜色
        self._m_item_hover_end_color = QColor(255, 0, 255, 25)  # type: QColor
        self._m_item_text_color = QColor("red")  # type: QColor  # item 的文字颜色
        self._m_item_line_color = QColor("red")  # type: QColor  # item 的线的颜色
        self._m_item_line_width = 5  # type: int     # 线的宽度
        self._m_item_line_style = self.ItemLineStyle.ItemNone  # type: QSlideNavigationBar.ItemLineStyle  # 线的样式类型
        self._m_item_font = QFont('宋体')  # type: QFont   # 字体家族
        self._m_item_font_size = 16  # type: int     # 字体大小
        self._m_item_radius = 0  # type: int     # item 的圆角半径
        self._m_space = 40  # type: int     # 间距大小, item 背景大小
        self._m_orientation = Qt.Horizontal  # type: Qt.Orientation  # 导航栏的方向:横向,纵向
        self._m_enable_key_move = True  # type: bool    # 是否可以使用按键切换item
        self._m_fixed = False  # type: bool    # 大小固定
        self._m_slide_velocity = 10  # type: int     # 滑动速度
        self._m_shake_velocity = 10  # type: int     # 晃动速度

        # ===========内部变量=========#
        self._m_item_maps = {}  # type: map(int, list(str, QRectF)) # 保存的item列表
        self._m_total_text_width = 0  # type: int     # 总的文字的宽度
        self._m_total_text_height = 0  # type: int     # 总的文字的高度
        self._m_current_index = 0  # type: int     # 当前选中的item 的索引
        self._m_start_rect = QRectF()  # type:QRectF  #起始矩形
        self._m_stop_rect = QRectF()  # type: QRectF  # 结束矩形
        self._m_slide_timer = QTimer(self)  # type: QTimer  # 滑动的定时器
        self._m_shake_timer = QTimer(self)  # type: QTimer  # 晃动的定时器
        self._m_forward = False  # type: bool    # 前进

        # ----------执行初始化动作-------------#
        self.setAttribute(Qt.WA_TranslucentBackground)
        self._m_slide_timer.setInterval(self._m_slide_velocity)
        self._m_slide_timer.timeout.connect(self._on_do_slide)
        self._m_shake_timer.setInterval(self._m_shake_velocity)
        self._m_shake_timer.timeout.connect(self._on_do_shake)

        self.setFocusPolicy(Qt.ClickFocus)
        self.setMouseTracking(True)

    # ---------以下是 API 接口----------#
    def add_item(self, item_str: str):
        """
        向导航栏中添加项目(代表一个选项卡),添加之前会查重
        :param item_str:项目名称(显示出来的文字)
        :return:None
        """
        if not item_str:
            return

        for key, value in self._m_item_maps.items():
            if value[0] == item_str:
                return  # 如果存在同名item,则返回

        f = QFont()
        f.setPointSize(self._m_item_font_size)
        fm = QFontMetrics(f)

        text_width = fm.width(item_str)
        text_height = fm.height()
        item_count = len(self._m_item_maps)
        if item_count > 0:
            if self._m_orientation == Qt.Horizontal:
                top_left = QPointF(self._m_total_text_width, 0)
                self._m_total_text_width += text_width + self._m_space
                bottom_right = QPointF(self._m_total_text_width, self._m_total_text_height)
            else:
                top_left = QPointF(0, self._m_total_text_height)
                self._m_total_text_height += text_height + self._m_space
                bottom_right = QPointF(self._m_total_text_width, self._m_total_text_height)

            self._m_item_maps[item_count] = [item_str, QRectF(top_left, bottom_right)]
        else:
            if self._m_orientation == Qt.Horizontal:
                # 水平方向,水平各占1个space, 竖直占1个space
                self._m_total_text_width = text_width + self._m_space
                self._m_total_text_height = text_height + self._m_space
            else:
                # 竖直方向, 水平各占2个space, 竖直占一个space
                self._m_total_text_width = text_width + 2 * self._m_space
                self._m_total_text_height = text_height + self._m_space

            top_left = QPointF(0.0, 0.0)
            bottom_right = QPointF(self._m_total_text_width, self._m_total_text_height)
            self._m_item_maps[item_count] = [item_str, QRectF(top_left, bottom_right)]
        self.setMinimumSize(self._m_total_text_width, self._m_total_text_height)

        if self._m_fixed:
            if self._m_orientation == Qt.Horizontal:
                self.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Fixed)  # 固定高度
            else:
                self.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Preferred)  # 固定宽度
        if len(self._m_item_maps):
            self._m_start_rect = QRectF(self._m_item_maps[0][1])
        self.update()

    def set_items(self, items_list: list):
        """
        一次性设置一组项目, 会清空之前设置的项目
        :param items_list: 项目名称列表
        :return: None
        """
        pass

    def get_items(self):
        pass

    def set_bar_start_color(self, color: QColor):
        """
        设置导航栏背景的起始颜色(渐变色的起始)
        :param color:QColor类型
        :return: None
        """
        if color != self._m_bar_start_color:
            self._m_bar_start_color = color
            self.update()

    def set_bar_end_color(self, color: QColor):
        """
        设置导航栏背景的结束颜色(渐变色的结束)
        :param color: QColor 类型
        :return: None
        """
        if color != self._m_bar_end_color:
            self._m_bar_end_color = color
            self.update()

    def set_item_start_color(self, color: QColor):
        """
        设置项目的背景色的起始颜色(渐变色的起始)
        :param color: QColor 类型
        :return: None
        """
        if color != self._m_item_start_color:
            self._m_item_start_color = color
            self.update()

    def set_item_end_color(self, color: QColor):
        """
        设置项目的背景色的结束颜色(渐变色的结束)
        :param color: QColor 类型
        :return: None
        """
        if color != self._m_item_end_color:
            self._m_item_end_color = color
            self.update()

    def set_item_text_color(self, color: QColor) -> None:
        """
        设置 item 的文字颜色
        :param color: QColor 类型
        :return:  None
        """
        if color != self._m_item_text_color:
            self._m_item_text_color = color
            self.update()

    def set_item_line_color(self, color: QColor) -> None:
        """
        设置 item 的线的颜色
        :param color: QColor 类型
        :return:  None
        """
        if color != self._m_item_line_color:
            self._m_item_line_color = color
            self.update()

    def set_bar_radius(self, radius: int):
        """
        设置导航栏四个角的圆弧半径
        :param radius: int 类型
        :return: None
        """
        if radius >= 0 and radius != self._m_bar_radius:
            self._m_bar_radius = radius
            self.update()

    def set_item_radius(self, radius: int):
        """
        设置项目的四个角的圆弧半径
        :param radius: int 类型
        :return: None
        """
        if radius >= 0 and radius != self._m_item_radius:
            self._m_item_radius = radius
            self.update()

    def set_space(self, space: int):
        """
        设置 item 所占的空间大小
        :param space: int 类型
        :return: None
        """
        if space >= 0 and space != self._m_space:
            self._m_space = space
            self.update()

    def set_item_line_width(self, width: int):
        """
        设置项目周围的线宽度
        :param width: int 类型
        :return: None
        """
        if width >= 0 and width != self._m_item_line_width:
            self._m_item_line_width = width
            self.update()

    def set_item_line_style(self, style: ItemLineStyle):
        """
        设置项目周围的线的类型:不显示,上方,下方,左方, 右方, 矩形
        :param style: 枚举类型
        :return: None
        """
        if style != self._m_item_line_style:
            self._m_item_line_style = style
            self.update()

    def set_orientation(self, orientation: Qt.Orientation):
        """
        设置导航栏是横向还是纵向
        :param orientation: Qt.Orientation 类型
        :return: None
        """
        if orientation != self._m_orientation:
            self._m_orientation = orientation
            self.update()

    def set_fixed(self, fixed: bool):
        """
        设置导航栏尺寸固定,不随窗口大小进行缩放
        :param fixed:  bool 类型
        :return:  None
        """
        if fixed != self._m_fixed:
            self._m_fixed = fixed
            self.update()

    def get_current_item_index(self):
        """
        返回当前选中项目的索引号
        :return: int类型,索引号
        """
        return self._m_current_index

    # -----------以下是槽函数--------------#
    def on_set_enable_key_move(self, enable: bool):
        """
        设置可以使用按键来切换导航项目
        :param enable: bool 类型
        :return: None
        """
        if enable != self._m_enable_key_move:
            self._m_enable_key_move = enable

    def on_move_to_first_item(self):
        """
        切换到第一个项目
        :return: None
        """
        self.on_move_to_index(0)

    def on_move_to_last_item(self):
        """
        切换到最后一个项目
        :return: None
        """
        self.on_move_to_index(len(self._m_item_maps) - 1)

    def on_move_to_previous_item(self):
        """
        切换到上一个项目
        :return: None
        """
        if self._m_current_index == 0:
            return
        self.on_move_to_index(self._m_current_index - 1)

    def on_move_to_next_item(self):
        """
        切换到下一个项目
        :return: None
        """
        if self._m_current_index == len(self._m_item_maps) - 1:
            return

        self.on_move_to_index(self._m_current_index + 1)

    def on_move_to_index(self, index: int):
        """
        切换到指定索引的项目
        :param index: int, 项目的索引号
        :return: None
        """
        if (index >= 0) and (index < len(self._m_item_maps)) and (index != self._m_current_index):
            self.itemClicked.emit(index, self._m_item_maps[index][0])
            if self._m_current_index == -1:
                self._m_start_rect = QRectF(self._m_item_maps[index][1])

            self._m_forward = index > self._m_current_index
            self._m_current_index = index
            self._m_stop_rect = QRectF(self._m_item_maps[index][1])
            self._m_slide_timer.start()

    def on_move_to_name(self, name: str):
        """
        切换到指定名称的项目
        :param name: 项目的名称,str类型
        :return: None
        """
        for key, value in self._m_item_maps.items():
            if value[0] == name:
                target_index = key
                if target_index == self._m_current_index:
                    return
                self.on_move_to_index(target_index)
                break

    def on_move_to_position(self, point: QPointF):
        """
        切换到指定位置的项目
        :param point: 位置坐标,QPointF类型
        :return: None
        """
        for key, value in self._m_item_maps.items():
            if value[1].contains(point):
                target_index = key
                if target_index == self._m_current_index:
                    return
                self.on_move_to_index(target_index)
                break

    def on_set_current_item_index(self, index: int):
        """
        将当前选中项目切换到指定索引的项目
        :param index: 索引号, int
        :return: NOne
        """
        self.on_move_to_index(index)

    # ------------以下是私有槽函数---------#
    def _on_do_slide(self):
        """
        完成滑动动作
        :return: None
        """
        if self._m_space <= 0 or self._m_start_rect == self._m_stop_rect:
            self.update()
            self._m_slide_timer.stop()
            return
        if self._m_orientation == Qt.Horizontal:
            dx = self._m_space / 2.0
            dy = 0
        else:
            dx = 0
            dy = self._m_space / 2.0

        if self._m_forward:
            self._m_start_rect.adjust(dx, dy, dx, dy)
            if ((self._m_orientation == Qt.Horizontal) and
                (self._m_start_rect.topLeft().x() >= self._m_stop_rect.topLeft().x())) or \
                    ((self._m_orientation == Qt.Vertical) and
                     (self._m_start_rect.topLeft().y() >= self._m_stop_rect.topLeft().y())):
                self._m_slide_timer.stop()
                if self._m_start_rect != self._m_stop_rect:
                    self._m_shake_timer.start()
        else:
            self._m_start_rect.adjust(-dx, -dy, -dx, -dy)
            if ((self._m_orientation == Qt.Horizontal) and
                (self._m_start_rect.topLeft().x() <= self._m_stop_rect.topLeft().x())) or \
                    ((self._m_orientation == Qt.Vertical) and
                     (self._m_start_rect.topLeft().y() <= self._m_stop_rect.topLeft().y())):
                self._m_slide_timer.stop()
                if self._m_start_rect != self._m_stop_rect:
                    self._m_shake_timer.start()
        self.update()

    def _on_do_shake(self):
        """
        完成晃动动作
        :return: None
        """
        delta = 2.0
        dx1 = dx2 = dy1 = dy2 = 0.0
        if self._m_start_rect.topLeft().x() > self._m_stop_rect.topLeft().x():
            dx1 = -delta
        elif self._m_start_rect.topLeft().x() < self._m_stop_rect.topLeft().x():
            dx1 = delta
        if self._m_start_rect.topLeft().y() > self._m_stop_rect.topLeft().y():
            dy1 = -delta
        elif self._m_start_rect.topLeft().y() < self._m_stop_rect.topLeft().y():
            dy1 = delta
        if self._m_start_rect.bottomRight().x() > self._m_stop_rect.bottomRight().x():
            dx2 = -delta
        elif self._m_start_rect.bottomRight().x() < self._m_stop_rect.bottomRight().x():
            dx2 = delta
        if self._m_start_rect.bottomRight().y() > self._m_stop_rect.bottomRight().y():
            dy2 = -delta
        elif self._m_start_rect.bottomRight().y() < self._m_stop_rect.bottomRight().y():
            dy2 = delta

        self._m_start_rect.adjust(dx1, dy1, dx2, dy2)

        if abs(self._m_start_rect.topLeft().x() - self._m_stop_rect.topLeft().x()) <= delta:
            self._m_start_rect.setLeft(self._m_stop_rect.topLeft().x())
        if abs(self._m_start_rect.topLeft().y() - self._m_stop_rect.topLeft().y()) <= delta:
            self._m_start_rect.setTop(self._m_stop_rect.topLeft().y())
        if abs(self._m_start_rect.bottomRight().x() - self._m_stop_rect.bottomRight().x()) <= delta:
            self._m_start_rect.setRight(self._m_stop_rect.bottomRight().x())
        if abs(self._m_start_rect.bottomRight().y() - self._m_stop_rect.bottomRight().y()) <= delta:
            self._m_start_rect.setBottom(self._m_stop_rect.bottomRight().y())
        if self._m_start_rect == self._m_stop_rect:
            self._m_shake_timer.stop()
        self.update()

    # -----------以下是事件响应函数的重载函数-----------#
    def paintEvent(self, a0: QtGui.QPaintEvent) -> None:
        """
        重载paintEvent函数
        :param a0:
        :return:
        """
        painter = QPainter(self)
        painter.setRenderHint(QPainter.Antialiasing)

        self._draw_bar_background(painter)
        self._draw_item_background(painter)
        self._draw_item_line(painter)
        self._draw_text(painter)

    def resizeEvent(self, a0: QtGui.QResizeEvent) -> None:
        """
        重载resizeEvent函数
        :param a0:
        :return:
        """
        self._adjust_item_size()

    def mousePressEvent(self, a0: QtGui.QMouseEvent) -> None:
        """
        重载mousePressEvent函数
        :param a0: 事件
        :return:None
        """
        self.on_move_to_position(a0.pos())

    def mouseMoveEvent(self, a0: QtGui.QMouseEvent) -> None:
        """
        重载mouseMoveEvent函数
        :param a0: 事件
        :return: None
        """
        is_on_item = False
        for key, value in self._m_item_maps.items():
            if value[1].contains(a0.pos()):
                self._m_current_hover_index = key
                is_on_item = True
                break
        if not is_on_item:
            self._m_current_hover_index = -1

        self.update()

    def keyPressEvent(self, a0: QtGui.QKeyEvent) -> None:
        """
        重载keyPressEvent函数
        :param a0:
        :return:
        """
        if not self._m_enable_key_move:
            # self.keyPressEvent(a0)
            return
        if a0.key() == Qt.Key_Home:
            self.on_move_to_first_item()
        elif a0.key() == Qt.Key_End:
            self.on_move_to_last_item()
        elif a0.key() == Qt.Key_Up or a0.key() == Qt.Key_Left:
            self.on_move_to_previous_item()
        elif a0.key() == Qt.Key_Down or a0.key() == Qt.Key_Right:
            self.on_move_to_next_item()
        else:
            # self.keyPressEvent(a0)
            return

    # -----------------以下是私有成员函数---------------------#
    def _draw_bar_background(self, p: QPainter):
        """
        绘制导航栏的背景
        :param p: 画刷
        :return: None
        """
        p.save()
        p.setPen(Qt.NoPen)
        lgt = QLinearGradient(QPointF(0, 0), QPointF(0, self.height()))
        lgt.setColorAt(0.0, self._m_bar_start_color)
        lgt.setColorAt(1.0, self._m_bar_end_color)
        p.setBrush(lgt)
        p.drawRoundedRect(self.rect(), self._m_bar_radius, self._m_bar_radius)
        p.restore()

    def _draw_item_background(self, p: QPainter):
        """
        绘制项目的背景
        :param p: 画刷
        :return: None
        """
        if self._m_start_rect.isNull():
            return

        p.save()
        lgt = QLinearGradient(self._m_start_rect.topLeft(), self._m_start_rect.bottomRight())
        lgt.setColorAt(0.0, self._m_item_start_color)
        lgt.setColorAt(1.0, self._m_item_end_color)
        p.setPen(Qt.NoPen)
        p.setBrush(lgt)
        p.drawRoundedRect(self._m_start_rect, self._m_item_radius, self._m_item_radius)

        # 绘制 hover 状态下的item
        if self._m_current_hover_index != -1:
            hover_rect = QRectF(self._m_item_maps[self._m_current_hover_index][1])
            lgt = QLinearGradient(hover_rect.topLeft(), hover_rect.bottomRight())
            lgt.setColorAt(0.0, self._m_item_hover_start_color)
            lgt.setColorAt(1.0, self._m_item_hover_end_color)
            p.setPen(Qt.NoPen)
            p.setBrush(lgt)
            p.drawRoundedRect(hover_rect, self._m_item_radius, self._m_item_radius)
        p.restore()

    def _draw_item_line(self, p: QPainter) -> None:
        """
        绘制项目周边的线条
        :param p: 画刷
        :return: None
        """
        if self._m_start_rect.isNull():
            return

        if self._m_item_line_style == self.ItemLineStyle.ItemNone:
            return
        elif self._m_item_line_style == self.ItemLineStyle.ItemTop:
            p1 = self._m_start_rect.topLeft()
            p2 = self._m_start_rect.topRight()
        elif self._m_item_line_style == self.ItemLineStyle.ItemRight:
            p1 = self._m_start_rect.topRight()
            p2 = self._m_start_rect.bottomRight()
        elif self._m_item_line_style == self.ItemLineStyle.ItemBottom:
            p1 = self._m_start_rect.bottomLeft()
            p2 = self._m_start_rect.bottomRight()
        elif self._m_item_line_style == self.ItemLineStyle.ItemLeft:
            p1 = self._m_start_rect.topLeft()
            p2 = self._m_start_rect.bottomLeft()
        elif self._m_item_line_style == self.ItemLineStyle.ItemRect:
            p1 = self._m_start_rect.topLeft()
            p2 = self._m_start_rect.bottomRight()
        else:
            return

        p.save()
        line_pen = QPen()
        line_pen.setColor(self._m_item_line_color)
        line_pen.setWidth(self._m_item_line_width)
        p.setPen(line_pen)
        if self._m_item_line_style == self.ItemLineStyle.ItemRect:
            p.drawRoundedRect(QRectF(p1, p2), self._m_item_radius, self._m_item_radius)
        else:
            p.drawLine(p1, p2)

        p.restore()

    def _draw_text(self, p: QPainter) -> None:
        """
        绘制项目的名称
        :param p: 画刷
        :return: None
        """
        p.save()
        p.setPen(self._m_item_text_color)
        for key, value in self._m_item_maps.items():
            self._m_item_font.setPointSize(self._m_item_font_size)
            p.setFont(self._m_item_font)
            p.drawText(value[1], Qt.AlignCenter, value[0])
        p.restore()

    def _adjust_item_size(self) -> None:
        """
        调整Item大小
        :return:
        """

        if self._m_fixed:
            return

        item_count = len(self._m_item_maps)

        if self._m_orientation == Qt.Horizontal:
            add_width = 1.0 * (self.width() - self._m_total_text_width) / item_count
            add_height = 1.0 * (self.height() - self._m_total_text_height)
        else:
            add_width = 1.0 * (self.width() - self._m_total_text_width)
            add_height = 1.0 * (self.height() - self._m_total_text_height) / item_count

        dx = dy = 0.0
        for key, value in self._m_item_maps.items():
            # f = QFont()
            fm = QFontMetrics(self._m_item_font)
            text_width = fm.width(value[0])
            text_height = fm.height()
            if self._m_orientation == Qt.Horizontal:
                topLeft = QPointF(dx, 0)
                dx += text_width + self._m_space + add_width
                dy = self._m_total_text_height + add_height
            else:
                topLeft = QPointF(0, dy)
                dx = self._m_total_text_width + add_width
                dy += text_height + self._m_space + add_height

            bottomRight = QPointF(dx, dy)
            text_rect = QRectF(topLeft, bottomRight)
            self._m_item_maps[key] = [value[0], QRectF(text_rect)]
            if key == self._m_current_index:
                self._m_start_rect = text_rect
                self._m_stop_rect = text_rect

        self.update()
예제 #9
0
initial_polygon = QPolygonF(initial_corridor)

corridor_points = {'bottom': [], 'right': [], 'top': [], 'left': []}

corridor_sides = {  # bottom y top deben estar cambiados
    'bottom': [
        initial_corridor_interior.topLeft(),
        initial_corridor_interior.topRight()
    ],
    'right': [
        initial_corridor_interior.topRight(),
        initial_corridor_interior.bottomRight()
    ],
    'top': [
        initial_corridor_interior.bottomLeft(),
        initial_corridor_interior.bottomRight()
    ],
    'left': [
        initial_corridor_interior.bottomLeft(),
        initial_corridor_interior.topLeft()
    ]
}

# -------- Recorro el pasillo inicial buscando puntos a lo largo de su perimetro -----------
for side, points in corridor_sides.items():
    line = QLineF(points[0], points[1])
    line_lenght = int(line.length())

    step = line_lenght / 100.
예제 #10
0
class Room:
    def __init__(self, type='genericRoom', p=QPointF(), w=-1, h=-1):
        self.type = type  # corridor, bedroom, kitchen, bathroom, etc
        self.width = w
        self.height = h
        self.initial_point = p
        self.room_qrect = QRectF()
        self.room_qpolygon = QPolygonF()
        self.area = -1
        self.side = None
        self.door_loc = -1  # 0 entre topL y topR, 1 entre topR y bottomR, 2 entre bottomR y bottomL y 3 entr bL y tL

        self.create_room()

    def create_room(self):
        print(
            f'Creating room of type {self.type} with width = {self.width} and height = {self.height}'
        )
        self.room_qrect = QRectF(self.initial_point.x(),
                                 self.initial_point.y(), self.width,
                                 self.height)
        self.room_qpolygon = QPolygonF(self.room_qrect)
        self.area = abs(self.width * self.height)

    def update_room_dimensions(self):
        self.width = self.room_qrect.width()
        self.height = self.room_qrect.height()
        self.area = abs(self.width * self.height)
        self.room_qpolygon = QPolygonF(self.room_qrect)

    def add_door(self, door_location, room_side):

        self.side = room_side

        dict_location_line = {
            'center':
            QLineF(self.room_qrect.topLeft(), self.room_qrect.topRight()),
            'left':
            QLineF(self.room_qrect.topLeft(), self.room_qrect.bottomLeft()),
            'right':
            QLineF(self.room_qrect.topRight(), self.room_qrect.bottomRight())
        }

        line = dict_location_line[door_location]
        line_lenght = int(line.length())
        step = line_lenght / 100.

        line_points = []
        for t in np.arange(0.25, 0.75, step):
            line_point = line.pointAt(t)
            line_points.append(QPointF(line_point.x(), line_point.y()))

        random_center_door = random.choice(line_points)

        door_sides = {
            'center': {
                'left_door':
                QPointF(random_center_door.x() - 0.5, random_center_door.y()),
                'right_door':
                QPointF(random_center_door.x() + 0.5, random_center_door.y())
            },
            'left': {
                'left_door':
                QPointF(random_center_door.x(),
                        random_center_door.y() - 0.5),
                'right_door':
                QPointF(random_center_door.x(),
                        random_center_door.y() + 0.5)
            },
            'right': {
                'left_door':
                QPointF(random_center_door.x(),
                        random_center_door.y() - 0.5),
                'right_door':
                QPointF(random_center_door.x(),
                        random_center_door.y() + 0.5)
            }
        }

        if door_location == 'center':
            self.room_qpolygon = QPolygonF([
                door_sides[door_location]['right_door'],
                self.room_qrect.topRight(),
                self.room_qrect.bottomRight(),
                self.room_qrect.bottomLeft(),
                self.room_qrect.topLeft(),
                door_sides[door_location]['left_door']
            ])

            self.door_loc = 0

        elif door_location == 'right':

            if room_side == 'bottom':
                self.room_qpolygon = QPolygonF([
                    door_sides[door_location]['right_door'],
                    self.room_qrect.topRight(),
                    self.room_qrect.topLeft(),
                    self.room_qrect.bottomLeft(),
                    self.room_qrect.bottomRight(),
                    door_sides[door_location]['left_door']
                ])

            elif room_side == 'top':
                self.room_qpolygon = QPolygonF([
                    door_sides[door_location]['right_door'],
                    self.room_qrect.bottomRight(),
                    self.room_qrect.bottomLeft(),
                    self.room_qrect.topLeft(),
                    self.room_qrect.topRight(),
                    door_sides[door_location]['left_door']
                ])

            self.door_loc = 1

        elif door_location == 'left':
            if room_side == 'bottom':
                self.room_qpolygon = QPolygonF([
                    door_sides[door_location]['right_door'],
                    self.room_qrect.topLeft(),
                    self.room_qrect.topRight(),
                    self.room_qrect.bottomRight(),
                    self.room_qrect.bottomLeft(),
                    door_sides[door_location]['left_door']
                ])

            elif room_side == 'top':
                self.room_qpolygon = QPolygonF([
                    door_sides[door_location]['right_door'],
                    self.room_qrect.bottomLeft(),
                    self.room_qrect.bottomRight(),
                    self.room_qrect.topRight(),
                    self.room_qrect.topLeft(),
                    door_sides[door_location]['left_door']
                ])

            self.door_loc = 3
예제 #11
0
initial_corridor.translate(
    -initial_corridor.center())  # Traslado el pasillo al centro

print(
    'Initial corridor --- ', f'Center = {initial_corridor.center()}\n',
    f'Top Left = {initial_corridor.topLeft()}\n',
    f'Top Right = {initial_corridor.topRight()}\n'
    f'Bottom Left = {initial_corridor.bottomLeft()}\n',
    f'Bottom Right = {initial_corridor.bottomRight()}\n')

corridor_sides = {  # bottom y top deben estar cambiados
    'bottom': [initial_corridor.topLeft(),
               initial_corridor.topRight()],
    'right': [initial_corridor.topRight(),
              initial_corridor.bottomRight()],
    'top': [initial_corridor.bottomLeft(),
            initial_corridor.bottomRight()],
    'left': [initial_corridor.topLeft(),
             initial_corridor.bottomLeft()]
}

# --------------------------------------------------------------------------------------------------------
# ------------ Se buscan n habitaciones que no interseccionen ni contengan a ninguna otra  --------------
# --------------------------------------------------------------------------------------------------------
random_qrect_list = []

for i in range(0, num_rooms):
    print(f'------------ i - {i} ------------')

    valid = False
    count = 0
예제 #12
0
    def redraw(self):
        self.graphics_scene.clear()

        # draw screenshot
        self.graphics_scene.addPixmap(self.screenPixel)

        # prepare for drawing selected area
        rect = QRectF(self.selected_area)
        rect = rect.normalized()

        top_left_point = rect.topLeft()
        top_right_point = rect.topRight()
        bottom_left_point = rect.bottomLeft()
        bottom_right_point = rect.bottomRight()
        top_middle_point = (top_left_point + top_right_point) / 2
        left_middle_point = (top_left_point + bottom_left_point) / 2
        bottom_middle_point = (bottom_left_point + bottom_right_point) / 2
        right_middle_point = (top_right_point + bottom_right_point) / 2

        # draw the picture mask
        mask = QColor(0, 0, 0, 155)

        if self.selected_area == QRect():
            self.graphics_scene.addRect(0, 0, self.screenPixel.width(),
                                        self.screenPixel.height(),
                                        QPen(Qt.NoPen), mask)
        else:
            self.graphics_scene.addRect(0, 0, self.screenPixel.width(),
                                        top_right_point.y(), QPen(Qt.NoPen),
                                        mask)
            self.graphics_scene.addRect(0, top_left_point.y(),
                                        top_left_point.x(), rect.height(),
                                        QPen(Qt.NoPen), mask)
            self.graphics_scene.addRect(
                top_right_point.x(), top_right_point.y(),
                self.screenPixel.width() - top_right_point.x(), rect.height(),
                QPen(Qt.NoPen), mask)
            self.graphics_scene.addRect(
                0, bottom_left_point.y(), self.screenPixel.width(),
                self.screenPixel.height() - bottom_left_point.y(),
                QPen(Qt.NoPen), mask)

        # draw the toolBar
        if self.action != ACTION_SELECT:
            spacing = 5
            # show the toolbar first, then move it to the correct position
            # because the width of it may be wrong if this is the first time it shows
            self.tooBar.show()

            dest = QPointF(rect.bottomRight() -
                           QPointF(self.tooBar.width(), 0) -
                           QPointF(spacing, -spacing))
            if dest.x() < spacing:
                dest.setX(spacing)
            pen_set_bar_height = self.penSetBar.height(
            ) if self.penSetBar is not None else 0
            if dest.y() + self.tooBar.height(
            ) + pen_set_bar_height >= self.height():
                if rect.top() - self.tooBar.height(
                ) - pen_set_bar_height < spacing:
                    dest.setY(rect.top() + spacing)
                else:
                    dest.setY(rect.top() - self.tooBar.height() -
                              pen_set_bar_height - spacing)

            self.tooBar.move(dest.toPoint())

            if self.penSetBar is not None:
                self.penSetBar.show()
                self.penSetBar.move(dest.toPoint() +
                                    QPoint(0,
                                           self.tooBar.height() + spacing))

                if self.action == ACTION_TEXT:
                    self.penSetBar.showFontWidget()
                else:
                    self.penSetBar.showPenWidget()
        else:
            self.tooBar.hide()

            if self.penSetBar is not None:
                self.penSetBar.hide()

        # draw the list
        for step in self.drawListResult:
            self.drawOneStep(step)

        if self.drawListProcess is not None:
            self.drawOneStep(self.drawListProcess)
            if self.action != ACTION_TEXT:
                self.drawListProcess = None

        if self.selected_area != QRect():
            self.items_to_remove = []

            # draw the selected rectangle
            pen = QPen(QColor(0, 255, 255), 2)
            self.items_to_remove.append(self.graphics_scene.addRect(rect, pen))

            # draw the drag point
            radius = QPoint(3, 3)
            brush = QBrush(QColor(0, 255, 255))
            self.items_to_remove.append(
                self.graphics_scene.addEllipse(
                    QRectF(top_left_point - radius, top_left_point + radius),
                    pen, brush))
            self.items_to_remove.append(
                self.graphics_scene.addEllipse(
                    QRectF(top_middle_point - radius,
                           top_middle_point + radius), pen, brush))
            self.items_to_remove.append(
                self.graphics_scene.addEllipse(
                    QRectF(top_right_point - radius, top_right_point + radius),
                    pen, brush))
            self.items_to_remove.append(
                self.graphics_scene.addEllipse(
                    QRectF(left_middle_point - radius,
                           left_middle_point + radius), pen, brush))
            self.items_to_remove.append(
                self.graphics_scene.addEllipse(
                    QRectF(right_middle_point - radius,
                           right_middle_point + radius), pen, brush))
            self.items_to_remove.append(
                self.graphics_scene.addEllipse(
                    QRectF(bottom_left_point - radius,
                           bottom_left_point + radius), pen, brush))
            self.items_to_remove.append(
                self.graphics_scene.addEllipse(
                    QRectF(bottom_middle_point - radius,
                           bottom_middle_point + radius), pen, brush))
            self.items_to_remove.append(
                self.graphics_scene.addEllipse(
                    QRectF(bottom_right_point - radius,
                           bottom_right_point + radius), pen, brush))

        # draw the textedit
        if self.textPosition is not None:
            textSpacing = 50
            position = QPoint()
            if self.textPosition.x() + self.textInput.width(
            ) >= self.screenPixel.width():
                position.setX(self.textPosition.x() - self.textInput.width())
            else:
                position.setX(self.textPosition.x())

            if self.textRect is not None:
                if self.textPosition.y() + self.textInput.height(
                ) + self.textRect.height() >= self.screenPixel.height():
                    position.setY(self.textPosition.y() -
                                  self.textInput.height() -
                                  self.textRect.height())
                else:
                    position.setY(self.textPosition.y() +
                                  self.textRect.height())
            else:
                if self.textPosition.y() + self.textInput.height(
                ) >= self.screenPixel.height():
                    position.setY(self.textPosition.y() -
                                  self.textInput.height())
                else:
                    position.setY(self.textPosition.y())

            self.textInput.move(position)
            self.textInput.show()
            # self.textInput.getFocus()

        # draw the magnifier
        if self.action == ACTION_SELECT:
            self.drawMagnifier()
            if self.mousePressed:
                self.drawSizeInfo()

        if self.action == ACTION_MOVE_SELECTED:
            self.drawSizeInfo()
예제 #13
0
    def drawMagnifier(self):
        # First, calculate the magnifier position due to the mouse position
        watch_area_width = 16
        watch_area_height = 16

        cursor_pos = self.mousePoint

        watch_area = QRect(
            QPoint(cursor_pos.x() - watch_area_width / 2,
                   cursor_pos.y() - watch_area_height / 2),
            QPoint(cursor_pos.x() + watch_area_width / 2,
                   cursor_pos.y() + watch_area_height / 2))
        if watch_area.left() < 0:
            watch_area.moveLeft(0)
            watch_area.moveRight(watch_area_width)
        if self.mousePoint.x(
        ) + watch_area_width / 2 >= self.screenPixel.width():
            watch_area.moveRight(self.screenPixel.width() - 1)
            watch_area.moveLeft(watch_area.right() - watch_area_width)
        if self.mousePoint.y() - watch_area_height / 2 < 0:
            watch_area.moveTop(0)
            watch_area.moveBottom(watch_area_height)
        if self.mousePoint.y(
        ) + watch_area_height / 2 >= self.screenPixel.height():
            watch_area.moveBottom(self.screenPixel.height() - 1)
            watch_area.moveTop(watch_area.bottom() - watch_area_height)

        # tricks to solve the hidpi impact on QCursor.pos()
        watch_area.setTopLeft(
            QPoint(watch_area.topLeft().x() * self.scale,
                   watch_area.topLeft().y() * self.scale))
        watch_area.setBottomRight(
            QPoint(watch_area.bottomRight().x() * self.scale,
                   watch_area.bottomRight().y() * self.scale))
        watch_area_pixmap = self.screenPixel.copy(watch_area)

        # second, calculate the magnifier area
        magnifier_area_width = watch_area_width * 10
        magnifier_area_height = watch_area_height * 10
        font_area_height = 40

        cursor_size = 24
        magnifier_area = QRectF(
            QPoint(QCursor.pos().x() + cursor_size,
                   QCursor.pos().y() + cursor_size),
            QPoint(QCursor.pos().x() + cursor_size + magnifier_area_width,
                   QCursor.pos().y() + cursor_size + magnifier_area_height))
        if magnifier_area.right() >= self.screenPixel.width():
            magnifier_area.moveLeft(QCursor.pos().x() - magnifier_area_width -
                                    cursor_size / 2)
        if magnifier_area.bottom(
        ) + font_area_height >= self.screenPixel.height():
            magnifier_area.moveTop(QCursor.pos().y() - magnifier_area_height -
                                   cursor_size / 2 - font_area_height)

        # third, draw the watch area to magnifier area
        watch_area_scaled = watch_area_pixmap.scaled(
            QSize(magnifier_area_width * self.scale,
                  magnifier_area_height * self.scale))
        magnifier_pixmap = self.graphics_scene.addPixmap(watch_area_scaled)
        magnifier_pixmap.setOffset(magnifier_area.topLeft())

        # then draw lines and text
        self.graphics_scene.addRect(QRectF(magnifier_area),
                                    QPen(QColor(255, 255, 255), 2))
        self.graphics_scene.addLine(
            QLineF(
                QPointF(magnifier_area.center().x(), magnifier_area.top()),
                QPointF(magnifier_area.center().x(), magnifier_area.bottom())),
            QPen(QColor(0, 255, 255), 2))
        self.graphics_scene.addLine(
            QLineF(
                QPointF(magnifier_area.left(),
                        magnifier_area.center().y()),
                QPointF(magnifier_area.right(),
                        magnifier_area.center().y())),
            QPen(QColor(0, 255, 255), 2))

        # get the rgb of mouse point
        point_rgb = QColor(self.screenPixel.toImage().pixel(self.mousePoint))

        # draw information
        self.graphics_scene.addRect(
            QRectF(
                magnifier_area.bottomLeft(),
                magnifier_area.bottomRight() +
                QPoint(0, font_area_height + 30)), QPen(Qt.black),
            QBrush(Qt.black))
        rgb_info = self.graphics_scene.addSimpleText(
            ' Rgb: ({0}, {1}, {2})'.format(point_rgb.red(), point_rgb.green(),
                                           point_rgb.blue()))
        rgb_info.setPos(magnifier_area.bottomLeft() + QPoint(0, 5))
        rgb_info.setPen(QPen(QColor(255, 255, 255), 2))

        rect = self.selected_area.normalized()
        size_info = self.graphics_scene.addSimpleText(
            ' Size: {0} x {1}'.format(rect.width() * self.scale,
                                      rect.height() * self.scale))
        size_info.setPos(magnifier_area.bottomLeft() + QPoint(0, 15) +
                         QPoint(0, font_area_height / 2))
        size_info.setPen(QPen(QColor(255, 255, 255), 2))