def testQGraphicsProxyWidget(self):
        scene = QGraphicsScene()

        proxy = QGraphicsProxyWidget(None, Qt.Window)
        widget = QLabel('Widget')
        proxy.setWidget(widget)
        proxy.setCacheMode(QGraphicsItem.DeviceCoordinateCache)
        scene.addItem(proxy)
        scene.setSceneRect(scene.itemsBoundingRect())

        view = QGraphicsView(scene)
        view.setRenderHints(QPainter.Antialiasing|QPainter.SmoothPixmapTransform)
        view.setViewportUpdateMode(QGraphicsView.BoundingRectViewportUpdate)
        view.show()

        timer = QTimer.singleShot(100, self.app.quit)
        self.app.exec_()
class MainWindowClass(QWidget):
    def __init__(self, parent=None):
        QWidget.__init__(self, parent)
        self.ui = Ui_MainWindowContainer()
        self.ui.setupUi(self)

        self.WindowWidth = 1000
        self.WindowHeight = 1000

        self.GraphicsSceneCont = QGraphicsScene()
        self.GraphicsSceneCont.setSceneRect(0, 0, self.WindowWidth,
                                            self.WindowHeight)
        self.ui.graphicsView.setScene(self.GraphicsSceneCont)

    def SetModuleWidget(self, x, y, WindowModule):
        Widget = QGraphicsProxyWidget()
        Widget.setWidget(WindowModule)
        Widget.setWindowFlags(Qt.Window)
        Widget.setPos(x, y)
        Widget.setFlag(PySide2.QtWidgets.QGraphicsItem.ItemIsMovable, True)
        Widget.setFlag(PySide2.QtWidgets.QGraphicsItem.ItemIsSelectable, True)
        self.GraphicsSceneCont.addItem(Widget)

    def SetWindowItem(self, x, y, WindowModule):
        WindowModule.setPos(x, y)
        WindowModule.resize(250, 250)
        #WindowModule.setWindowFlags(Qt.Window)
        WindowModule.setFlag(PySide2.QtWidgets.QGraphicsItem.ItemIsMovable,
                             True)
        WindowModule.setFlag(PySide2.QtWidgets.QGraphicsItem.ItemIsSelectable,
                             True)
        self.GraphicsSceneCont.addItem(WindowModule)
示例#3
0
    def __init__(self, player_1: Player, player_2: Player, size: int = 600):
        super().__init__()
        self.setWindowTitle("Ultimate Tic-Tac-Toe")
        self.player_1 = player_1
        self.player_2 = player_2
        self.game = UltimateTicTacToe()
        self.size = size  # size of window
        self.maxi_size = size
        self.mini_size = int(self.size / 3 * 0.8)
        self.click_needed = False
        self.clear = True

        scene = QGraphicsScene()
        self.board = TicTacToeBoard(state=self.game.get_maxiboard(),
                                    point=(self.size // 2, self.size // 2),
                                    size=self.maxi_size,
                                    board_thickness=6,
                                    token_thickness=4)
        scene.addItem(self.board)
        self.mini_centers = self._find_miniboard_centers()
        self.miniboards = [
            TicTacToeBoard(state=self.game.get_miniboard(i),
                           point=self.mini_centers[i],
                           size=self.mini_size,
                           board_thickness=3,
                           token_thickness=8) for i in range(9)
        ]
        for miniboard in self.miniboards:
            scene.addItem(miniboard)
            miniboard.setPos(miniboard.get_point()[0],
                             miniboard.get_point()[1])
        scene.setSceneRect(0, 0, self.size, self.size)
        self.setScene(scene)
示例#4
0
    def _set_portrait_from_current_index(self):
        portrait_name, texture = self._portraits[self._current_index]
        self.portrait_name_label.setText(portrait_name)
        self.current_image_label.setText(
            "%d / %d" % (self._current_index + 1, len(self._portraits)))

        scene = QGraphicsScene()
        scene.addPixmap(QPixmap.fromImage(texture.image()))
        scene.setSceneRect(0.0, 0.0, 128.0, 128.0)
        self.display.setScene(scene)
        self.display.setSceneRect(0.0, 0.0, float(texture.width()),
                                  float(texture.height()))
示例#5
0
class GameWidget(QGraphicsView):
    def __init__(self, parent=None):
        super(GameWidget, self).__init__(parent)
        self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.m = 150
        self.n = 150

        self.scene = QGraphicsScene(self)
        self.setScene(self.scene)
        self.scene.setSceneRect(0, 0, self.width(), self.height())
        self.setAlignment(Qt.AlignLeft | Qt.AlignTop)
        self.universe = engine.Universe(self.n, self.m)

        print(Qt.red)
        self.timer = QTimer(self)
        self.timer.timeout.connect(self.step)

    def load(self, item):
        self.universe.file_input(item)

    def drawUniverse(self):
        width = self.width()
        height = self.height()

        cellWidth = width / self.universe.n
        cellHeight = height / self.universe.m

        x = 0
        y = 0
        for this_list in self.universe.map:
            y = 0
            for elem in this_list:
                color = Qt.gray
                if elem == 1:
                    color = Qt.green
                self.scene.addRect(x, y, cellWidth, cellHeight, brush=color)
                y += cellHeight
            x += cellWidth

    def step(self):
        self.scene.clear()
        self.universe.step()
        self.drawUniverse()
        self.scene.update()

    def run(self):
        self.timer.start()

    def stop(self):
        self.timer.stop()
示例#6
0
class GameWindow(QGraphicsView):
    def __init__(self, parent=None):
        super(GameWindow, self).__init__(parent=parent)
        self.screen = None
        self.scene = QGraphicsScene()
        self.scene.setSceneRect(
            QRect(left=0,
                  top=0,
                  width=PLAYGROUND_SIZEX * SCALE_FACTORX,
                  height=PLAYGROUND_SIZEY * SCALE_FACTORY))
        self.setFrameStyle(4)
        self.setScene(self.scene)
        self.snake = []
        # define SnakeHead
        self.snake.append(QGraphicsRectItem())
        self.snake[0].setRect(QRect(0, 0, SCALE_FACTORX, SCALE_FACTORY))

        self.snake[0].setBrush(brushHead)
        self.scene.addItem(self.snake[0])
        # define rest of the snake
        for i in range(1, MAX_LENGTH_SNAKE):
            self.snake.append(QGraphicsRectItem())
            self.snake[i].setRect(QRect(0, 0, SCALE_FACTORX, SCALE_FACTORY))
            self.snake[i].setBrush(brushBody)
            self.snake[i].setVisible(False)
            self.scene.addItem(self.snake[i])
        # Create the graphic item for apple
        self.goal = QGraphicsRectItem()
        self.goal.setRect(QRect(0, 0, SCALE_FACTORX, SCALE_FACTORY))
        self.goal.setBrush(brushGoal)
        self.scene.addItem(self.goal)

        self.show()

    def draw(self, state):
        self.goal.setPos(state.goal.x * SCALE_FACTORX,
                         state.goal.y * SCALE_FACTORY)
        self.goal.setVisible(True)
        self.snake[0].setPos(float(state.snake[0].x * SCALE_FACTORX),
                             float(state.snake[0].y * SCALE_FACTORY))
        for i in range(1, state.snake_length):
            self.snake[i].setPos(state.snake[i].x * SCALE_FACTORX,
                                 state.snake[i].y * SCALE_FACTORY)
            self.snake[i].setVisible(True)
        for i in range(state.snake_length, MAX_LENGTH_SNAKE):
            self.snake[i].setVisible(False)

    def screenshot(self):
        self.screen = self.grab()
        self.screen.save("./snake_screen.png")
示例#7
0
    def __init__(self, params):
        MWB.__init__(self, params)
        QGraphicsView.__init__(self)

        self.setFixedWidth(300);
        self.setFixedHeight(300);

        scene = QGraphicsScene(self)
        scene.setSceneRect(0,0, self.width()-5, self.height()-5)
        self.setScene(scene)
        self.setCacheMode(QGraphicsView.CacheBackground)
        self.setRenderHint(QPainter.Antialiasing)

        self.setStyleSheet('''
border: none;
        ''')
示例#8
0
    def testQGraphicsProxyWidget(self):
        scene = QGraphicsScene()

        proxy = QGraphicsProxyWidget(None, Qt.Window)
        widget = QLabel('Widget')
        proxy.setWidget(widget)
        proxy.setCacheMode(QGraphicsItem.DeviceCoordinateCache)
        scene.addItem(proxy)
        scene.setSceneRect(scene.itemsBoundingRect())

        view = QGraphicsView(scene)
        view.setRenderHints(QPainter.Antialiasing|QPainter.SmoothPixmapTransform)
        view.setViewportUpdateMode(QGraphicsView.BoundingRectViewportUpdate)
        view.show()

        timer = QTimer.singleShot(100, self.app.quit)
        self.app.exec_()
示例#9
0
class MainWindow(QMainWindow):
    def __init__(self):
        # super(MainWindow, self).__init__()
        super().__init__()

        # self.ui = QMainWindow()
        self.label = QLabel(f'<h1>Hello World</h1>')
        self.setGeometry(10, 70, 1000, 700)
        
        self.view = QGraphicsView()
        self.scene = QGraphicsScene()
        self.scene.setSceneRect(0, 0, 800, 520)
        self.view.setScene(self.scene)

        # greenBrush = QBrush(Qt.green)
        # blueBrush = QBrush(Qt.blue)
        # outlinePen = QPen(Qt.black)
        # outlinePen.setWidth(2)

        # self.rectangle = self.scene.addRect(100, 0, 80, 100, outlinePen, blueBrush)
        # self.ellipse = self.scene.addEllipse(0, -100, 300, 60, outlinePen, greenBrush)
        # self.text = self.scene.addText('Hello World')

        # item = SlotItem(1);
        # self.scene.addItem(item)
        self.bracket1 = BracketItem(1)
        self.bracket1.setPos(10, 10)
        self.bracket2 = BracketItem(2)
        self.bracket2.setPos(10, 300)

        self.bracket3 = BracketItem(3)
        self.bracket3.setPos(450, 10)
        self.bracket4 = BracketItem(4)
        self.bracket4.setPos(450, 300)

        self.scene.addItem(self.bracket1)
        self.scene.addItem(self.bracket2)
        self.scene.addItem(self.bracket3)
        self.scene.addItem(self.bracket4)
        # self.bracket1.drawNodes()
        self.setCentralWidget(self.view)
示例#10
0
class AbstractGraphicViewer(QGraphicsView, TcWidget):
    def __init__(self, parent=None):
        super(AbstractGraphicViewer, self).__init__(parent)
        self.m_scaleX = 0
        self.m_scaleY = 0
        self._pan = False
        self._panStartX = 0
        self._panStartY = 0
        self.scene = QGraphicsScene()
        self.scene.setItemIndexMethod(QGraphicsScene.NoIndex)
        self.scene.setSceneRect(-2000, -2000, 4000, 4000)
        self.setScene(self.scene)
        self.setCacheMode(QGraphicsView.CacheBackground)
        self.setViewportUpdateMode(QGraphicsView.BoundingRectViewportUpdate)
        self.setRenderHint(QPainter.Antialiasing)
        self.setTransformationAnchor(QGraphicsView.AnchorUnderMouse)
        self.setMinimumSize(400, 400)
        self.adjustSize()
        self.setMouseTracking(True)
        self.viewport().setMouseTracking(True)

    def wheelEvent(self, event):
        if event.angleDelta().y() > 0:
            factor = 1.1
        else:
            factor = 0.9
        view_pos = event.pos()
        scene_pos = self.mapToScene(view_pos)
        self.centerOn(scene_pos)
        self.scale(factor, factor)
        delta = self.mapToScene(view_pos) - self.mapToScene(self.viewport().rect().center())
        self.centerOn(scene_pos - delta)

    def resizeEvent(self, event):
        super(AbstractGraphicViewer, self).resizeEvent(event)

    def mouseMoveEvent(self, event):
        if self._pan:
            self.horizontalScrollBar().setValue(self.horizontalScrollBar().value() - (event.x() - self._panStartX))
            self.verticalScrollBar().setValue(self.verticalScrollBar().value() - (event.y() - self._panStartY))
            self._panStartX = event.x()
            self._panStartY = event.y()
            event.accept()
        super(AbstractGraphicViewer, self).mouseMoveEvent(event)

    def mousePressEvent(self, event):
        if event.button() == Qt.LeftButton:
            self._pan = True
            self._panStartX = event.x()
            self._panStartY = event.y()
            self.setCursor(QCursor.ClosedHandCursor)
            event.accept()
            return
        super(AbstractGraphicViewer, self).mousePressEvent(event)

    def mouseReleaseEvent(self, event):
        if event.button() == Qt.LeftButton:
            self._pan = False
            self.setCursor(QCursor.ArrowCursor)
            event.accept()
        super(AbstractGraphicViewer, self).mouseReleaseEvent(event)

    def showEvent(self, event):
        super(AbstractGraphicViewer, self).showEvent(event)
        adjusted = self.scene.itemsBoundingRect().adjusted(-100, -100, 100, 100)
        self.scene.setSceneRect(adjusted)
        # FitInView is called two times because of this bug: https://bugreports.qt.io/browse/QTBUG-1047
        update_state = self.updatesEnabled()
        self.setUpdatesEnabled(False)
        self.fitInView(adjusted, Qt.KeepAspectRatio)
        QApplication.processEvents(QEventLoop.ExcludeUserInputEvents)
        self.fitInView(adjusted, Qt.KeepAspectRatio)
        self.setUpdatesEnabled(update_state)
示例#11
0
class MainWindow(QMainWindow):
    def __init__(self, *args, **kwargs):
        super(MainWindow, self).__init__(*args, **kwargs)

        view = QGraphicsView()
        self.scene = QGraphicsScene()
        self.scene.setSceneRect(QRectF(0, 0, *WINDOW_SIZE))

        felt = QBrush(QPixmap(os.path.join('images', 'felt.png')))
        self.scene.setBackgroundBrush(felt)

        name = QGraphicsPixmapItem()
        name.setPixmap(QPixmap(os.path.join('images', 'ronery.png')))
        name.setPos(QPointF(170, 375))
        self.scene.addItem(name)

        view.setScene(self.scene)

        # Timer for the win animation only.
        self.timer = QTimer()
        self.timer.setInterval(5)
        self.timer.timeout.connect(self.win_animation)

        self.animation_event_cover = AnimationCover()
        self.scene.addItem(self.animation_event_cover)

        menu = self.menuBar().addMenu("&Game")

        deal_action = QAction(
            QIcon(os.path.join('images', 'playing-card.png')), "Deal...", self)
        deal_action.triggered.connect(self.restart_game)
        menu.addAction(deal_action)

        menu.addSeparator()

        deal1_action = QAction("1 card", self)
        deal1_action.setCheckable(True)
        deal1_action.triggered.connect(lambda: self.set_deal_n(1))
        menu.addAction(deal1_action)

        deal3_action = QAction("3 card", self)
        deal3_action.setCheckable(True)
        deal3_action.setChecked(True)
        deal3_action.triggered.connect(lambda: self.set_deal_n(3))

        menu.addAction(deal3_action)

        dealgroup = QActionGroup(self)
        dealgroup.addAction(deal1_action)
        dealgroup.addAction(deal3_action)
        dealgroup.setExclusive(True)

        menu.addSeparator()

        rounds3_action = QAction("3 rounds", self)
        rounds3_action.setCheckable(True)
        rounds3_action.setChecked(True)
        rounds3_action.triggered.connect(lambda: self.set_rounds_n(3))
        menu.addAction(rounds3_action)

        rounds5_action = QAction("5 rounds", self)
        rounds5_action.setCheckable(True)
        rounds5_action.triggered.connect(lambda: self.set_rounds_n(5))
        menu.addAction(rounds5_action)

        roundsu_action = QAction("Unlimited rounds", self)
        roundsu_action.setCheckable(True)
        roundsu_action.triggered.connect(lambda: self.set_rounds_n(None))
        menu.addAction(roundsu_action)

        roundgroup = QActionGroup(self)
        roundgroup.addAction(rounds3_action)
        roundgroup.addAction(rounds5_action)
        roundgroup.addAction(roundsu_action)
        roundgroup.setExclusive(True)

        menu.addSeparator()

        quit_action = QAction("Quit", self)
        quit_action.triggered.connect(self.quit)
        menu.addAction(quit_action)

        self.deck = []
        self.deal_n = 3  # Number of cards to deal each time
        self.rounds_n = 3  # Number of rounds (restacks) before end.

        for suit in SUITS:
            for value in range(1, 14):
                card = Card(value, suit)
                self.deck.append(card)
                self.scene.addItem(card)
                card.signals.doubleclicked.connect(
                    lambda card=card: self.auto_drop_card(card))

        self.setCentralWidget(view)
        self.setFixedSize(*WINDOW_SIZE)

        self.deckstack = DeckStack()
        self.deckstack.setPos(OFFSET_X, OFFSET_Y)
        self.scene.addItem(self.deckstack)

        # Set up the working locations.
        self.works = []
        for n in range(7):
            stack = WorkStack()
            stack.setPos(OFFSET_X + CARD_SPACING_X * n, WORK_STACK_Y)
            self.scene.addItem(stack)
            self.works.append(stack)

        self.drops = []
        # Set up the drop locations.
        for n in range(4):
            stack = DropStack()
            stack.setPos(OFFSET_X + CARD_SPACING_X * (3 + n), OFFSET_Y)
            stack.signals.complete.connect(self.check_win_condition)

            self.scene.addItem(stack)
            self.drops.append(stack)

        # Add the deal location.
        self.dealstack = DealStack()
        self.dealstack.setPos(OFFSET_X + CARD_SPACING_X, OFFSET_Y)
        self.scene.addItem(self.dealstack)

        # Add the deal click-trigger.
        dealtrigger = DealTrigger()
        dealtrigger.signals.clicked.connect(self.deal)
        self.scene.addItem(dealtrigger)

        self.shuffle_and_stack()

        self.setWindowTitle("Ronery")
        self.show()

    def restart_game(self):
        reply = QMessageBox.question(
            self, "Deal again", "Are you sure you want to start a new game?",
            QMessageBox.Yes | QMessageBox.No)

        if reply == QMessageBox.Yes:
            self.shuffle_and_stack()

    def quit(self):
        self.close()

    def set_deal_n(self, n):
        self.deal_n = n

    def set_rounds_n(self, n):
        self.rounds_n = n
        self.deckstack.update_stack_status(self.rounds_n)

    def shuffle_and_stack(self):
        # Stop any ongoing animation.
        self.timer.stop()
        self.animation_event_cover.hide()

        # Remove cards from all stacks.
        for stack in [self.deckstack, self.dealstack
                      ] + self.drops + self.works:
            stack.reset()

        random.shuffle(self.deck)

        # Deal out from the top of the deck, turning over the
        # final card on each line.
        cards = self.deck[:]
        for n, workstack in enumerate(self.works, 1):
            for a in range(n):
                card = cards.pop()
                workstack.add_card(card)
                card.turn_back_up()
                if a == n - 1:
                    card.turn_face_up()

        # Ensure removed from all other stacks here.
        self.deckstack.stack_cards(cards)

    def deal(self):
        if self.deckstack.cards:
            self.dealstack.spread_from = len(self.dealstack.cards)
            for n in range(self.deal_n):
                card = self.deckstack.take_top_card()
                if card:
                    self.dealstack.add_card(card)
                    card.turn_face_up()

        elif self.deckstack.can_restack(self.rounds_n):
            self.deckstack.restack(self.dealstack)
            self.deckstack.update_stack_status(self.rounds_n)

    def auto_drop_card(self, card):
        for stack in self.drops:
            if stack.is_valid_drop(card):
                card.stack.remove_card(card)
                stack.add_card(card)
                break

    def check_win_condition(self):
        complete = all(s.is_complete for s in self.drops)
        if complete:
            # Add click-proof cover to play area.
            self.animation_event_cover.show()
            # Get the stacks of cards from the drop,stacks.
            self.timer.start()

    def win_animation(self):
        # Start off a new card
        for drop in self.drops:
            if drop.cards:
                card = drop.cards.pop()
                if card.vector is None:
                    card.vector = QPoint(-random.randint(3, 10),
                                         -random.randint(0, 10))
                    break

        for card in self.deck:
            if card.vector is not None:
                card.setPos(card.pos() + card.vector)
                card.vector += QPoint(0, 1)  # Gravity
                if card.pos().y() > WINDOW_SIZE[1] - CARD_DIMENSIONS.height():
                    # Bounce the card, losing some energy.
                    card.vector = QPoint(
                        card.vector.x(),
                        -max(1, int(card.vector.y() * BOUNCE_ENERGY)))
                    # Bump back up to base of screen.
                    card.setPos(card.pos().x(),
                                WINDOW_SIZE[1] - CARD_DIMENSIONS.height())

                if card.pos().x() < -CARD_DIMENSIONS.width():
                    card.vector = None
                    # Put the card back where it started.
                    card.stack.add_card(card)
示例#12
0
文件: gui.py 项目: paiv/icfpc2020
class AppView(QGraphicsView):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setWindowTitle("Arrival")

        self.gscene = QGraphicsScene()
        self.setScene(self.gscene)
        CanvasSize = (WorldSize[0] * WorldScale, WorldSize[1] * WorldScale)
        self.gscene.setSceneRect(0, 0, *CanvasSize)
        global _Scene
        _Scene = self.gscene

        worker = Worker(execute_this_fn)
        worker.signals.result.connect(print_output)
        worker.signals.finished.connect(thread_complete)
        worker.signals.progress.connect(progress_fn)
        self.worker = worker

        self.threadpool = QThreadPool()
        self.threadpool.start(worker)

    def mousePressEvent(self, event):
        p = self.mapToScene(event.pos())
        WorldCenter = (WorldSize[0] // 2, WorldSize[1] // 2)
        mouse = (p.x() // WorldScale - WorldCenter[0],
                 p.y() // WorldScale - WorldCenter[1])
        self.worker.mouse_click = mouse

    def keyPressEvent(self, event):
        ctrl = (event.modifiers() == Qt.ControlModifier) or (
            event.modifiers() == (Qt.ControlModifier | Qt.ShiftModifier))
        if ctrl:
            if event.key() == 45:
                self.zoom_out()
            elif (event.key() == 43) or (event.key() == 61):
                self.zoom_in()
            elif event.key() == 71:
                self.input_state()
            elif event.key() == 73:
                self.ocr()
            else:
                print('keyboard:', event.key(), file=sys.stderr)

    def zoom_in(self):
        global WorldScale
        WorldScale += 1
        if WorldScale > 14:
            WorldScale = int(WorldScale * 1.1)
        self.worker.redraw = True

    def zoom_out(self):
        global WorldScale
        if WorldScale > 14:
            WorldScale = int(WorldScale / 1.1)
        WorldScale = max(1, WorldScale - 1)
        self.worker.redraw = True

    def input_state(self):
        text, ok = QInputDialog().getText(self, "Enter state", "State:",
                                          QLineEdit.Normal,
                                          '[2, [1, -1], 0, []]')
        if ok and text:
            self.worker.set_state = eval(text)
            self.worker.mouse_click = (-1000, -1000)

    def ocr(self):
        self.worker.ocr = True
示例#13
0
class Apartment2D(object):
    def __init__(self, ui):
        #self.ui = ui
        #self.ui.guiDlg.resize(QDesktopWidget().availableGeometry(self).size() * 0.6)
        self.scene = QGraphicsScene()
        self.dim = {
            "HMIN": -3000,
            "VMIN": -4000,
            "WIDTH": 6000,
            "HEIGHT": 8000
        }
        self.scene.setSceneRect(self.dim['HMIN'], self.dim['VMIN'],
                                self.dim['WIDTH'], self.dim['HEIGHT'])
        ui.graphicsView.setScene(self.scene)
        self.boxes = []
        #self.ui.graphicsView.setViewport(QGLWidget())
        ui.graphicsView.scale(1, -1)
        ui.graphicsView.fitInView(self.scene.sceneRect(), Qt.KeepAspectRatio)
        ui.graphicsView.setTransformationAnchor(QGraphicsView.NoAnchor)
        ui.graphicsView.setResizeAnchor(QGraphicsView.NoAnchor)

        self.persons = {}
        self.pixmapSize = (0, 0)
        self.initializeWorld()

    def addPerson(self, pos, angle=0, color=-1, size=100):
        colors = QColor.colorNames()
        color = colors[random.randint(0,
                                      len(colors) -
                                      1)] if color == -1 else color
        pos = [pos[0], pos[2]] if len(pos) > 2 else pos
        p = self.scene.addEllipse(pos[0] - size // 2,
                                  pos[1] - size // 2,
                                  size,
                                  size,
                                  pen=QPen(QColor(color), 20),
                                  brush=QBrush(color=QColor(color)))

        # pixmap
        pixmap = QPixmap("person.png").scaled(600, 300)
        self.pixmapSize = (pixmap.width() / 2, pixmap.height() / 2)
        pixItem = QGraphicsPixmapItem(pixmap)
        pixItem.setTransformOriginPoint(pixItem.boundingRect().center())
        pixItem.setZValue(20)
        self.scene.addItem(pixItem)

        self.persons[p] = pixItem

        return p

    def movePerson(self, elipse, pos, size=100):
        #elipse.setPos(pos[0], pos[1])
        pos = [pos[0], pos[2]] if len(pos) > 2 else pos
        color = elipse.pen().color()
        self.scene.addEllipse(pos[0] - size // 2,
                              pos[1] - size // 2,
                              size,
                              size,
                              pen=QPen(QColor(color), 20),
                              brush=QBrush(color=QColor(color)))
        # pixmap
        self.persons[elipse].setPos(pos[0] - self.pixmapSize[0],
                                    pos[1] - self.pixmapSize[1])

        # change rotation value when provided
        self.persons[elipse].setRotation(180)

    def wheelEvent(self, event):
        zoomInFactor = 1.15
        zoomOutFactor = 1 / zoomInFactor
        # Zoom
        if event.delta() > 0:
            zoomFactor = zoomInFactor
        else:
            zoomFactor = zoomOutFactor
        self.graphicsView.scale(zoomFactor, zoomFactor)

    def initializeWorld(self):
        with open('autonomy.json', 'r') as f:
            world = json.load(f)

        #load dimensions
        dim = world["dimensions"]
        x_offset = -3200
        y_offset = 1850

        # load roundtables
        # for k,v in world["roundTables"].items():
        #     print(v)
        #     box = self.scene.addEllipse(QRectF(-v[2]// 2, -v[3]// 2, v[2], v[3]), QPen(QColor("Khaki")), QBrush(QColor("Khaki")));
        #     box.setPos(v[4]+x_offset, v[5]+x_offset);
        #     self.boxes.append(box)

        # load tables
        for k, v in world["tables"].items():
            box = self.scene.addRect(
                QRectF(-v[2] // 2, -v[3] // 2, v[2], v[3]),
                QPen(QColor("SandyBrown")), QBrush(QColor("SandyBrown")))
            box.setPos(v[4] + x_offset, v[5] + y_offset)
            box.setTransformOriginPoint(box.mapFromScene(QPointF(0, 0)))
            box.setRotation(v[6])
            self.boxes.append(box)

        # load walls
        for k, v in world['walls'].items():
            box = self.scene.addRect(
                QRectF(-v[2] // 2, -v[3] // 2, v[2], v[3]),
                QPen(QColor("Brown")), QBrush(QColor("Brown")))
            box.setPos(v[4] + x_offset, v[5] + y_offset)
            box.setTransformOriginPoint(box.mapFromScene(QPointF(0, 0)))
            box.setRotation(v[6])
            self.boxes.append(box)
        # }

        # //load points
        # QVariantMap points = mainMap[QString("points")].toMap();
        # for (auto &t : points)
        # {
        #     QVariantList object = t.toList();
        #     auto box = scene.addRect(QRectF(-object[2].toFloat() / 2, -object[3].toFloat() / 2, object[2].toFloat(), object[3].toFloat()), QPen(QColor("Brown")), QBrush(QColor("Brown")));
        #     box->setPos(object[4].toFloat()+x_offset, object[5].toFloat()+y_offset);
        #     boxes.push_back(box);
        # }
        # //load boxes
        # QVariantMap cajas = mainMap[QString("boxes")].toMap();
        # for (auto &t : cajas)
        # {
        #     QVariantList object = t.toList();
        #     auto box = scene.addRect(QRectF(-object[2].toFloat() / 2, -object[3].toFloat() / 2, object[2].toFloat(), object[3].toFloat()), QPen(QColor("Brown")), QBrush(QColor("Orange")));
        #     box->setPos(object[4].toFloat()+x_offset, object[5].toFloat()+y_offset);
        #     //box->setPos(object[4].toFloat(), object[5].toFloat());
        #     //box->setRotation(object[6].toFloat()*180/M_PI2);
        #     box->setFlag(QGraphicsItem::ItemIsMovable);
        #     boxes.push_back(box);
        # }
        # QTransform t;
        # //t.translate(3200, -1850);
        # t.rotate(-90);
        # //t.translate(-3200, 1850);
        # for(auto &item : boxes)
        # {
        #     item->setPos(t.map(item->pos()));
        #     item->setRotation(item->rotation() + 90);
        #     item->setPos(item->pos() + QPointF(1850,3200));
        # }
        # /////////////
        # //AXIS
        self.scene.addLine(0, 0, 400, 0, QPen(QBrush(QColor("red")), 20))
        self.scene.addLine(0, 0, 0, 400, QPen(QBrush(QColor("blue")), 20))
示例#14
0
class EvisionCamera(QWidget):
    def __init__(self):
        super(EvisionCamera, self).__init__()
        self.ui = Ui_EvisionCameraForm()
        self.ui.setupUi(self)
        self.device = 0
        self.camtype = "usb_cam"
        self.colorspace = "rgb"
        self.image_suffix = "png"
        self.video_codec = "AVC1"
        self.video_suffix = "avi"
        self.dst = Path("./")
        self.parent_dir = Path(__file__).parent.resolve()

        self.filename_rule_lst = FileIO.file_save
        self.filename_rule = FileIO.file_save_lst[-1]

        self.is_display = True
        self.param_separate = False

        self.slot = Slot(self)

        cam = self.get_cam()

        self.camera = cam(self.device, self.colorspace, parent=self)
        self.support_params = self.camera.get_supported_params()
        self.current_params = self.camera.get_current_params("full")

        self.prop_table = [["Fourcc", "aa"], ["Width", 640], ["Height", 480],
                           ["FPS", 30.0], ["Bit depth", 8],
                           ["File naming style", self.filename_rule]]

        self.setup()
        self.set_timer()

    def get_cam(self):
        """Return camera object according to current OS.

        Detects what OS you are using, return camera objects  in order to function properly.

            - Linux: LinuxCamera
            - RaspberryPi OS: RaspiCamera
            - Windows: WindowsCamera

        Returns:
            Camera class
        """
        self.system = sys.platform
        if self.system == 'linux':
            return LinuxCamera
        elif self.system == 'win32':
            return WindowsCamera
        else:
            return "Unknown type"

    def setup(self):
        """Setup the main window for displaying frame and widget.

        Creates a QMainWindow object, then add menubar, toolbar, statusbar, widgets and layout
        into the window.
        """
        self.setFocusPolicy(Qt.ClickFocus)
        self.setContentsMargins(20, 0, 20, 0)
        # self.information_window_setup()
        self.view_setup()
        self.layout_setup()
        self.image_setup()
        self.update_prop_table()
        self.adjust_windowsize()

    def set_timer(self):
        """Set QTimer

        Creates a QTimer object to update frame on view area. The interval is set to the inverse
        of camera FPS.
        """
        self.qtime_factor = 0.8
        self.fps = 30.0
        if self.fps:
            self.msec = 1 / self.fps * 1000 * self.qtime_factor
        else:
            self.msec = 1 / 30.0 * 1000 * self.qtime_factor
        self.timer = QTimer()
        self.timer.setInterval(self.msec)
        self.timer.timeout.connect(self.next_frame)
        self.timer.start()

    def next_frame(self):
        """Get next frame from the connected camera.

        Get next frame, set it to the view area and update.
        """
        #print("display :", self.is_display)
        if self.is_display:
            self.camera.read_frame()
            self.convert_frame()
            self.scene.clear()
            self.scene.addPixmap(self.pixmap)
            self.update()
            #print("update")

    def convert_frame(self):
        """Convert the class of frame

        Create qimage, qpixmap objects from ndarray frame for displaying on the window.

        """
        if self.colorspace == "rgb" or self.colorspace == "RGB":
            self.qimage = QImage(self.camera.frame.data,
                                 self.camera.frame.shape[1],
                                 self.camera.frame.shape[0],
                                 self.camera.frame.shape[1] * 3,
                                 QImage.Format_RGB888)
        elif self.colorspace == "gray":
            self.qimage = QImage(self.camera.frame.data,
                                 self.camera.frame.shape[1],
                                 self.camera.frame.shape[0],
                                 self.camera.frame.shape[1] * 1,
                                 QImage.Format_Grayscale8)

        self.pixmap.convertFromImage(self.qimage)

    def stop_timer(self):
        """Deactivate the Qtimer object.
        """
        self.timer.stop()

    def start_timer(self):
        """Activate the Qtimer object.
        """
        self.fps = 30.0
        if self.fps:
            self.msec = 1 / self.fps * 1000 * self.qtime_factor
        else:
            self.msec = 1 / 30.0 * 1000 * self.qtime_factor
        self.timer.setInterval(self.msec)
        self.timer.start()

    def view_setup(self):
        """Set view area to diplay read frame in part of the main window
        """
        self.scene = QGraphicsScene()
        self.ui.view.setScene(self.scene)
        self.width = 640
        self.height = 480
        self.scene.setSceneRect(0, 0, self.width, self.height)
        self.ui.view.setMouseTracking(True)
        self.ui.view.setSizeAdjustPolicy(QAbstractScrollArea.AdjustToContents)
        self.ui.view.setCacheMode(QGraphicsView.CacheBackground)
        self.ui.view.setViewportUpdateMode(QGraphicsView.SmartViewportUpdate)

    def layout_setup(self):
        """Set layout of objects on the window.
        """
        # self.add_statusbar()
        self.add_buttons()
        self.add_prop_window()

    def add_statusbar(self):
        """Create status bar, then add to the main window.

        The status bar shows the coordinates on the frame where the cursor is located and
        its pixel value. The pixel value has RGB if the format of is color (RGB), does grayscale
        value if grayscale.
        """
        self.statbar_list = []
        if self.colorspace == "rgb":
            self.stat_css = {
                "postion": "color: white",
                "R": "color: white;",
                "G": "color: white;",
                "B": "color: white;",
                "alpha": "color: white;",
            }
        else:
            self.stat_css = {
                "postion": "color: black;",
                "gray": "color: black"
            }

        for s in self.stat_css.values():
            stat = QStatusBar(self)
            stat.setStyleSheet(s)
            self.statbar_list.append(stat)

        first = True
        for stat in self.statbar_list:
            if first:
                # self.ssetStatusBar(stat)
                self.statbar_list[0].reformat()
                first = False
            else:
                self.statbar_list[0].addPermanentWidget(stat)

    def add_buttons(self):
        self.ui.save_button.clicked.connect(self.save_frame)
        self.ui.stop_button.clicked.connect(self.stop_frame)
        self.ui.rec_button.clicked.connect(self.record)
        self.ui.close_button.clicked.connect(self.slot.quit)
        self.ui.theme_button.clicked.connect(self.slot.switch_theme)
        self.ui.help_button.clicked.connect(self.slot.usage)
        self.ui.frame_button.clicked.connect(self.slot.change_frame_prop)
        self.ui.default_button.clicked.connect(self.set_param_default)
        self.ui.filerule_button.clicked.connect(self.slot.set_file_rule)
        pass

    def add_prop_window(self):
        """Create a table to show the current properties of camera.

        Returns:
            QGridLayout: PySide2 QGridLayout
        """
        header = ["property", "value"]

        self.ui.prop_table_widget.setColumnCount(len(header))
        self.ui.prop_table_widget.setRowCount(len(self.prop_table))

        self.ui.prop_table_widget.setHorizontalHeaderLabels(header)
        self.ui.prop_table_widget.verticalHeader().setVisible(False)
        self.ui.prop_table_widget.setAlternatingRowColors(True)
        self.ui.prop_table_widget.horizontalHeader().setStretchLastSection(
            True)
        self.ui.prop_table_widget.setEditTriggers(
            QAbstractItemView.NoEditTriggers)
        self.ui.prop_table_widget.setFocusPolicy(Qt.NoFocus)

        for row, content in enumerate(self.prop_table):
            for col, elem in enumerate(content):
                self.item = QTableWidgetItem(elem)
                self.ui.prop_table_widget.setItem(row, col, self.item)
        self.ui.prop_table_widget.setSizePolicy(QSizePolicy.Minimum,
                                                QSizePolicy.Minimum)
        # self.prop_table_widget.resizeColumnsToContents()
        # self.prop_table_widget.resizeRowsToContents()
        self.ui.prop_table_widget.setVerticalScrollBarPolicy(
            Qt.ScrollBarAlwaysOff)
        self.ui.prop_table_widget.setHorizontalScrollBarPolicy(
            Qt.ScrollBarAlwaysOff)
        self.ui.prop_table_widget.setSizeAdjustPolicy(
            QAbstractScrollArea.AdjustToContentsOnFirstShow)
        self.ui.prop_table_widget.setColumnWidth(0, 150)
        self.ui.prop_table_widget.setColumnWidth(1, 150)

    # slot save_button_down
    def save_frame(self):
        """Save the frame on the window as an image.
        """
        if self.filename_rule == "Manual":
            self.save_frame_manual()
            if not self.filename:
                return None
            prm = re.sub(r"\.(.*)", ".csv", str(self.filename))
        else:
            self.filename = FileIO.get_filename(self.filename_rule,
                                                self.image_suffix,
                                                self.parent_dir)
            prm = str(self.filename).replace(self.image_suffix, "csv")

        if not self.dst.exists():
            self.dst.mkdir(parents=True)
        im = Image.fromarray(self.camera.frame)
        im.save(self.filename)

        # make a parameter file
        with open(prm, "w") as f:
            for name, key in self.current_params.items():
                f.write("{},{}\n".format(name,
                                         self.current_params[name]["value"]))

        self.write_text("{:<10}: {}".format("save image", self.filename))
        self.write_text("{:<10}: {}".format("save param", prm))

    def stop_frame(self, checked: bool):
        """Stop reading next frame.

        Args:
            checked (bool): True when presse the Stop button (toggle on). False when press
                again (toggel off).
        """
        if checked:
            self.write_text("Stop !!")
            self.is_display = False
            self.ui.stop_button.setText('Start')
            self.ui.stop_button.setChecked(True)
        else:
            self.write_text("Start !!")
            self.is_display = True
            self.ui.stop_button.setText('&Pause')
            self.ui.stop_button.setChecked(False)

    def record(self):
        """Start or end recording
        """
        if self.camera.is_recording:
            self.camera.stop_recording()
            self.rec_button.setText('&Rec')
            self.rec_act.setText('&Record')
            self.write_text("save : {}".format(self.video_filename))
        else:
            self.video_filename = FileIO.get_filename(self.filename_rule,
                                                      self.video_suffix,
                                                      self.parent_dir)
            self.camera.start_recording(self.video_filename, self.video_codec)
            self.rec_button.setText('Stop rec')
            self.rec_act.setText('Stop record')

    def image_setup(self):
        """Creates a Qimage to assign frame, then initialize with an image which has zero in all pixels.
        """
        self.frame = np.zeros((640, 480, 3), dtype=np.uint8)
        #cinit = np.ctypeslib.as_ctypes(self.frame)
        #self.frame.buffer = sharedctypes.RawArray(cinit._type_, cinit)
        self.qimage = QImage(self.frame.data, 640, 480, 640 * 3,
                             QImage.Format_RGB888)
        self.pixmap = QPixmap.fromImage(self.qimage)

    def update_prop_table(self):
        """Updates the table that shows the camera properties.
        """
        w, h, cc, f = self.camera.get_properties()
        self.prop_table = [["Fourcc", cc], ["Width", int(w)],
                           ["Height", int(h)], ["FPS", "{:.1f}".format(f)],
                           ["Bit depth", 8],
                           ["Naming Style", self.filename_rule]]
        col = 1
        for row in range(len(self.prop_table)):
            text = str(self.prop_table[row][col])
            self.ui.prop_table_widget.item(row, col).setText(text)

    def adjust_windowsize(self):
        """Adjusts the main window size
        """
        system = Utility.get_os()
        if system == "linux":
            w, h, _ = self.get_screensize()
            wscale = 0.5
            hscale = 0.7
            self.resize(wscale * w, hscale * h)
        else:
            self.resize(800, 600)

    def set_param_default(self):
        """Sets all paramters to default.
        """
        for param, values in self.current_params.items():
            default = values["default"]
            self.camera.set_parameter(param, default)
            self.current_params[param]["slider"].setValue(int(default))
            self.current_params[param]["slider_value"].setText(str(default))

    def write_text(self, text: str, level: str = "info", color: str = None):
        print(text)

    # decorator
    def display(func):
        def wrapper(self, *args, **kwargs):
            try:
                self.is_display = False
                self.stop_timer()
                func(self, *args, **kwargs)
            finally:
                self.is_display = True
                self.start_timer()

        return wrapper

    @display
    def save_frame_manual(self) -> bool:
        """Determine file name of image to save with QFileDialog
        """
        self.dialog = QFileDialog()
        self.dialog.setWindowTitle("Save File")
        self.dialog.setNameFilters(
            ["image (*.jpg *.png *.tiff *.pgm)", "All Files (*)"])
        self.dialog.setAcceptMode(QFileDialog.AcceptSave)
        self.dialog.setOption(QFileDialog.DontUseNativeDialog)

        if self.dialog.exec_():
            r = self.dialog.selectedFiles()

            # If the file name doesn't include supproted suffixes, add to the end.
            if re.search(".pgm$|.png$|.jpg$|.tiff$", r[0]):
                self.filename = r[0]
            else:
                self.filename = "{}.{}".format(r[0], self.image_suffix)
            return True
        else:
            return False

    def get_properties(self) -> list:
        """Get the current camera properties.

        Returns:
            list: parameters. fourcc, width, height, fps.
        """
        tmp = []
        for row in range(4):
            tmp.append(self.prop_table[row][1])
        return tmp
示例#15
0
文件: _View.py 项目: kurtu5/Labeler
class DisplayWidget(QStackedWidget):
    imageClicked = Signal(int, QEvent)

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.max_columns = None  # Set when presenter starts # Max cols for multimages
        self.cached_images = {}  # Cache read of image from disk

        self.start()

    def emitter(self, index, event):
        self.imageClicked.emit(index, event)

    def start(self):
        # Layout for single images
        self.single_image = QWidget()
        self.single_image_layout = QGridLayout()
        self.single_image_view = QGraphicsView()
        self.single_image_scene = QGraphicsScene()
        self.single_image_view.setScene(self.single_image_scene)
        self.single_image_layout.addWidget(self.single_image_view)
        self.single_image.setLayout(self.single_image_layout)

        # Layout for multiple images
        self.multiple_image = QWidget()
        self.multiple_image_view_layout = QVBoxLayout()
        self.multiple_image_layout = QGraphicsGridLayout()
        self.multiple_image_view = QGraphicsView()
        self.multiple_image_scene = QGraphicsScene()
        self.multiple_image_view.setScene(self.multiple_image_scene)
        self.panel = QGraphicsWidget()
        self.multiple_image_scene.addItem(self.panel)
        self.multiple_image_view_layout.addWidget(self.multiple_image_view)
        self.panel.setLayout(self.multiple_image_layout)
        self.multiple_image.setLayout(self.multiple_image_view_layout)

        self.addWidget(self.single_image)
        self.addWidget(self.multiple_image)

    def setMaxColumns(self, max_cols):
        self.max_columns = max_cols

    def images_load(self, images):
        """ Take list of images and display in main window """
        num = len(images)
        if num == 0:
            return

        width = self.width()
        maxcol = self.max_columns
        if num < maxcol:
            maxcol = num
        colwidth = width / maxcol

        # Set proper widget for display of multiple or single images
        if num > 1:
            self.setCurrentWidget(self.multiple_image)
            # Clear the layout
            while self.multiple_image_layout.count():
                self.multiple_image_layout.removeAt(0)
            # Clear the scene
            for child in self.panel.childItems():
                child.setParent(None)
        else:
            self.setCurrentWidget(self.single_image)
            self.single_image_scene.clear()
            self.single_image_scene.setSceneRect(
                self.single_image_scene.itemsBoundingRect())

        # Display images or image
        row = 0
        col = -1
        for index, image in images.items():
            col += 1
            if col >= maxcol:
                col = 0
                row += 1

            # Used any cached reads
            if index not in self.cached_images.keys():
                image_reader = QImageReader()
                image_reader.setDecideFormatFromContent(True)
                image_reader.setFileName(image.getFilename())
                self.cached_images[index] = image_reader.read()
            cached_image = self.cached_images[index]

            pixmap = QPixmap(cached_image)
            if num > 1:
                pixmap = pixmap.scaledToWidth(colwidth - 20)
                rec = MultiImageWidget(pixmap, basename(image.getFilename()),
                                       index)
                rec.imageClicked.connect(self.emitter)
                self.multiple_image_layout.addItem(rec, row, col)
            else:
                self.single_image_scene.addPixmap(pixmap)

        adjusted = self.multiple_image_scene.itemsBoundingRect()
        adjusted.adjust(0, 0, 0, 8 * row)
        self.multiple_image_scene.setSceneRect(adjusted)
示例#16
0
class Window(QMainWindow):
    """Class to create main widnow

    Creates main window for displaying frame read from a connected camera.
    The main window contains memu bar, tool bar, status bar, sliders and the
    boxes showing the camera's information. These widget are created and added to
    main window in the instance method of this class.

    """
    def __init__(
            self, device: int = 0, suffix: str = "png", camtype: str = "usb_cam",
            color: str = "RGB", dst: str = ".", param: str = "full",
            rule: str = "Sequential", parent=None):
        super(Window, self).__init__(parent)
        self.device = device
        self.camtype = camtype
        self.colorspace = color
        self.image_suffix = suffix
        self.video_codec = "AVC1"
        self.video_suffix = "avi"
        self.dst = Path(dst)
        self.parent_dir = Path(__file__).parent.resolve()

        self.filename_rule_lst = FileIO.file_save
        self.filename_rule = FileIO.file_save_lst[-1]

        self.is_display = True
        self.param_separate = False

        self.slot = Slot(self)

        cam = self.get_cam()
        self.camera = cam(self.device, self.colorspace, parent=self)
        self.support_params = self.camera.get_supported_params()
        self.current_params = self.camera.get_current_params(param)

        # List of camera properties with temporal initial values
        self.prop_table = [
            ["Fourcc", "aa"],
            ["Width", 640],
            ["Height", 480],
            ["FPS", 30.0],
            ["Bit depth", 8],
            ["File naming style", self.filename_rule]
        ]
        self.setup()
        self.set_timer()

    def get_cam(self) -> str:
        """Return camera object according to current OS.

        Detects what OS you are using, return camera objects  in order to function properly.

            - Linux: LinuxCamera
            - RaspberryPi OS: RaspiCamera
            - Windows: WindowsCamera

        Returns:
            Camera class
        """
        if self.camtype == "raspi":
            return RaspiCamera

        self.system = platform.system()
        if re.search("linux", self.system, re.IGNORECASE):
            return LinuxCamera
        elif re.search("windows", self.system, re.IGNORECASE):
            return WindowsCamera
        else:
            return "Unknown type"

    def setup(self):
        """Setup the main window for displaying frame and widget.

        Creates a QMainWindow object, then add menubar, toolbar, statusbar, widgets and layout
        into the window.
        """
        self.setFocusPolicy(Qt.ClickFocus)
        self.setContentsMargins(20, 0, 20, 0)
        self.information_window_setup()
        self.view_setup()
        self.layout_setup()
        self.image_setup()
        self.toolbar_setup()
        self.setWindowTitle("usbcamGUI")
        self.update_prop_table()
        self.adjust_windowsize()
        self.set_theme()

    def adjust_windowsize(self):
        """Adjusts the main window size
        """
        system = Utility.get_os()
        if system == "linux":
            w, h, _ = self.get_screensize()
            wscale = 0.5
            hscale = 0.7
            self.resize(wscale * w, hscale * h)
        else:
            self.resize(800, 600)

    def set_theme(self):
        """Set color theme of the main window.
        """
        self.style_theme = "light"
        self.style_theme_sheet = ":/{}.qss".format(self.style_theme)
        self.slot.switch_theme()
        self.set_font(self.camera.font_family, self.camera.font_size)

    def set_font(self, family: str = "Yu Gothic", size: int = 14):
        """Sets font-family and size of UI.

        Args:
            family (str, optional): Font-family. Defaults to "Yu Gothic".
            size (int, optional): Font-size. Defaults to 20.
        """
        self.setStyleSheet('font-family: "{}"; font-size: {}px;'.format(family, size))

    def set_timer(self):
        """Set QTimer

        Creates a QTimer object to update frame on view area. The interval is set to the inverse
        of camera FPS.
        """
        self.qtime_factor = 0.8
        self.fps = 30.0
        if self.fps:
            self.msec = 1 / self.fps * 1000 * self.qtime_factor
        else:
            self.msec = 1 / 30.0 * 1000 * self.qtime_factor
        self.timer = QTimer()
        self.timer.setInterval(self.msec)
        self.timer.timeout.connect(self.next_frame)
        self.timer.start()

    def stop_timer(self):
        """Deactivate the Qtimer object.
        """
        self.timer.stop()

    def start_timer(self):
        """Activate the Qtimer object.
        """
        self.fps = 30.0
        if self.fps:
            self.msec = 1 / self.fps * 1000 * self.qtime_factor
        else:
            self.msec = 1 / 30.0 * 1000 * self.qtime_factor
        self.timer.setInterval(self.msec)
        self.timer.start()

    def toolbar_setup(self):
        """Create toolbar
        """
        self.toolbar = QToolBar("test", self)
        self.addToolBar(self.toolbar)

        current_size = str(self.font().pointSize())
        lst = [str(i) for i in range(6, 14)]
        lst.extend([str(i) for i in range(14, 40, 2)])
        index = lst.index(current_size)

        self.fontsize_combo = QComboBox()
        self.fontsize_combo.addItems(lst)
        self.fontsize_combo.setCurrentIndex(index)
        self.fontsize_combo.currentTextChanged.connect(self.slot.set_fontsize)
        self.fontsize_label = QLabel("Font size")
        self.fontsize_label.setFrameShape(QFrame.Box)

        self.comb = QFontComboBox()

        self.toolbar.addWidget(self.save_button)
        self.toolbar.addWidget(self.stop_button)
        self.toolbar.addWidget(self.rec_button)
        self.toolbar.addWidget(self.close_button)
        self.toolbar.addWidget(self.theme_button)
        self.toolbar.addWidget(self.help_button)
        self.toolbar.addWidget(self.fontsize_label)
        self.toolbar.addWidget(self.fontsize_combo)
        self.toolbar.setStyleSheet(
            """
            QToolBar {spacing:5px;}
            """
            )

    def view_setup(self):
        """Set view area to diplay read frame in part of the main window
        """
        self.view = QGraphicsView()
        self.scene = QGraphicsScene()
        self.view.setScene(self.scene)
        self.width = 640
        self.height = 480
        self.scene.setSceneRect(0, 0, self.width, self.height)
        self.view.setMouseTracking(True)
        self.view.setSizeAdjustPolicy(QAbstractScrollArea.AdjustToContents)
        self.view.setCacheMode(QGraphicsView.CacheBackground)
        self.view.setViewportUpdateMode(QGraphicsView.SmartViewportUpdate)

    def layout_setup(self):
        """Set layout of objects on the window.
        """
        self.window = QWidget()
        self.setCentralWidget(self.window)
        #self.view.mouseMoveEvent = self.get_coordinates

        self.main_layout = QHBoxLayout()
        self.window.setLayout(self.main_layout)

        self.add_actions()
        self.add_menubar()
        self.add_statusbar()
        self.button_block = self.add_buttons()
        self.slider_group = self.add_params()
        self.prop_block = self.add_prop_window()
        self.create_mainlayout()

    def image_setup(self):
        """Creates a Qimage to assign frame, then initialize with an image which has zero in all pixels.
        """
        self.frame = np.zeros((640, 480, 3), dtype=np.uint8)
        #cinit = np.ctypeslib.as_ctypes(self.frame)
        #self.frame.buffer = sharedctypes.RawArray(cinit._type_, cinit)
        self.qimage = QImage(
            self.frame.data,
            640,
            480,
            640 * 3,
            QImage.Format_RGB888
            )
        self.pixmap = QPixmap.fromImage(self.qimage)

    def add_actions(self):
        """Add actions executed when press each item in the memu window.
        """
        self.save_act = self.create_action("&Save", self.save_frame, "Ctrl+s")
        self.stop_act = self.create_action("&Pause", self.stop_frame, "Ctrl+p", checkable=True)
        self.rec_act = self.create_action("&Record", self.record, "Ctrl+r", True)
        self.quit_act = self.create_action("&Quit", self.slot.quit, "Ctrl+q")

        self.theme_act = self.create_action("Switch &Theme", self.slot.switch_theme, "Ctrl+t")
        self.param_act = self.create_action("Choose parameter slider", self.slot.switch_paramlist, "Ctrl+g")
        self.show_paramlist_act = self.create_action("Parameters &List", self.slot.show_paramlist, "Ctrl+l")
        self.show_shortcut_act = self.create_action("&Keybord shortcut", self.slot.show_shortcut, "Ctrl+k")
        self.font_act = self.create_action("&Font", self.slot.set_font, "Ctrl+f")

        self.usage_act = self.create_action("&Usage", self.slot.usage, "Ctrl+h")
        self.about_act = self.create_action("&About", self.slot.about, "Ctrl+a")

    def create_action(self, text: str, slot: Callable, key: str = None, checkable: bool = False,
        check_defalut: bool = False) -> QAction:
        """Create a QAction object.

        Args:
            text (str): Text shown on menu.
            slot (Callable): A method called when click the menu.
            key (str, optional): Shortcut key. Defaults to None.
            checkable (bool, optional): Add a checkbox into the menu. Defaults to False.
            check_defalut (bool, optional): Check default status. Defaults to False.

        Returns:
            QAction: PySide2 QAction
        """
        act = QAction(text)
        act.setShortcut(key)
        if checkable:
            act.setCheckable(True)
            act.setChecked(check_defalut)
            act.toggled.connect(slot)
        else:
            act.triggered.connect(slot)

        return act

    def add_menubar(self):
        """Create menu bar, then add to the main window.
        """
        self.menubar = QMenuBar()
        self.setMenuBar(self.menubar)

        self.file_tab = QMenu("&File")
        self.file_tab.addAction(self.save_act)
        self.file_tab.addAction(self.stop_act)
        self.file_tab.addAction(self.rec_act)
        self.file_tab.addSeparator()
        self.file_tab.addAction(self.quit_act)
        #self.file_tab.setSizePolicy(policy)

        self.view_tab = QMenu("&View")
        self.view_tab.addAction(self.theme_act)
        self.view_tab.addAction(self.font_act)
        self.view_tab.addAction(self.param_act)
        self.view_tab.addAction(self.show_shortcut_act)
        self.view_tab.addAction(self.show_paramlist_act)

        self.help_tab = QMenu("&Help")
        self.help_tab.addAction(self.usage_act)
        self.help_tab.addAction(self.about_act)

        self.menubar.addMenu(self.file_tab)
        self.menubar.addMenu(self.view_tab)
        self.menubar.addMenu(self.help_tab)
        self.menubar.setStyleSheet(
            """
            QMenuBar {
                    font-size: 16px;
                    spacing:10px;
                    padding-top: 5px;
                    padding-bottom: 10px;
                }
            """
            )

    def add_statusbar(self):
        """Create status bar, then add to the main window.

        The status bar shows the coordinates on the frame where the cursor is located and
        its pixel value. The pixel value has RGB if the format of is color (RGB), does grayscale
        value if grayscale.
        """
        self.statbar_list = []
        if self.colorspace == "rgb":
            self.stat_css = {
                "postion": "color: white",
                "R": "color: white;",
                "G": "color: white;",
                "B": "color: white;",
                "alpha": "color: white;",
            }
        else:
            self.stat_css = {
                "postion": "color: black;",
                "gray": "color: black"
            }

        for s in self.stat_css.values():
            stat = QStatusBar(self)
            stat.setStyleSheet(s)
            self.statbar_list.append(stat)

        first = True
        for stat in self.statbar_list:
            if first:
                self.setStatusBar(stat)
                self.statbar_list[0].reformat()
                first = False
            else:
                self.statbar_list[0].addPermanentWidget(stat)

    def add_buttons(self):
        """Add push buttons on the window.

        Add quit, save stop and usage buttons on the windows. When press each button, the set
        method (called "slot" in Qt framework) are execeuted.
        """
        self.save_button = self.create_button("&Save", self.save_frame, None, None, "Save the frame")
        self.stop_button = self.create_button("&Pause", self.stop_frame, None, None, "Stop reading frame", True)
        self.rec_button = self.create_button("&Rec", self.record, None, None, "Start recording", True)
        self.close_button = self.create_button("&Quit", self.slot.quit, None, None, "Quit the program")
        self.theme_button = self.create_button("Light", self.slot.switch_theme, None, None, "Switche color theme")
        self.help_button = self.create_button("&Usage", self.slot.usage, None, None, "Show usage")

        self.frame_button = self.create_button(
            "Properties",
            self.slot.change_frame_prop,
            None,
            tip="Change properties",
            minsize=(150, 30)
            )
        self.default_button = self.create_button(
            "&Default params",
            self.set_param_default,
            "Ctrl+d",
            tip="Set default parameters",
            minsize=(150, 30)
            )
        self.filerule_button = self.create_button(
            "&Naming style",
            self.slot.set_file_rule,
            "Ctrl+n",
            tip="Change naming style",
            minsize=(150, 30)
            )

        hbox = QHBoxLayout()
        hbox.addWidget(self.save_button)
        hbox.addWidget(self.stop_button)
        hbox.addWidget(self.rec_button)
        hbox.addWidget(self.close_button)
        hbox.addWidget(self.theme_button)
        hbox.addWidget(self.help_button)
        return hbox

    def create_button(self, text: str, slot: Callable, key: str = None, icon: Icon = None,
        tip: str = None, checkable: bool = False, minsize: tuple = None) -> QPushButton:
        """Create a QPushButton object.

        Args:
            text (str): Text shown on the button.
            slot (Callable): A method called when click the button.
            key (str, optional): Shortcut key. Defaults to None.
            icon (Icon, optional): An icon shown on the button. Defaults to None.
            tip (str, optional): A tips shown when position the pointer on the button. Defaults to None.
            checkable (bool, optional): Add button to checkbox. Defaults to False.
            msize (tuple, optional): Minimum size of the button box, (width, height).

        Returns:
            QPushButton: PySide2 QPushButton
        """
        button = QPushButton(text)
        if checkable:
            button.setCheckable(True)
            button.toggled.connect(slot)
        else:
            button.clicked.connect(slot)

        if key:
            button.setShortcut(key)
        if icon:
            button.setIcon(QIcon(icon))
        if tip:
            button.setToolTip(tip)
        if minsize:
            button.setMinimumSize(minsize[0], minsize[1])
        else:
            button.setMinimumSize(80, 30)
        return button

    def add_params(self) -> QGridLayout:
        """Set the properties of camera parameter.

        Set the properties of camera parameter, then add sliders to change each parameter.
        When change value on the slider, the value of paramter also changes by the caller
        function.

        """
        lst = self.current_params
        for key, value in lst.items():
            self.add_slider(key)

        # add sliders
        self.slider_table = QGridLayout()
        self.slider_table.setSpacing(15)
        self.slider_table.setContentsMargins(20, 20, 20, 20)
        for row, param in enumerate(self.current_params):
            self.slider_table.addWidget(self.current_params[param]["slider_label"], row, 0)
            self.slider_table.addWidget(self.current_params[param]["slider"], row, 1)
            self.slider_table.addWidget(self.current_params[param]["slider_value"], row, 2)
        if len(self.current_params) > 15:
            self.param_separate = True
        else:
            self.param_separate = False
        return self.slider_table

    def update_params(self, plist: list) -> QGridLayout:
        """Update camera's paramters and sliders shown on the windows.
        """
        #self.current_params.clear()
        self.current_params = self.camera.get_current_params("selected", plist)
        for key, value in self.current_params.items():
            self.add_slider(key)

        # add sliders
        grid = QGridLayout()
        grid.setSpacing(15)
        grid.setContentsMargins(20, 20, 20, 20)
        for row, param in enumerate(self.current_params):
            grid.addWidget(self.current_params[param]["slider_label"], row, 0)
            grid.addWidget(self.current_params[param]["slider"], row, 1)
            grid.addWidget(self.current_params[param]["slider_value"], row, 2)
        if len(self.current_params) > 15:
            self.param_separate = True
        else:
            self.param_separate = False
        self.slider_group = grid
        self.update_mainlayout()
        self.update_prop_table()
        self.write_text("update sliders")
        return grid

    def add_slider(self, param: str):
        """Creates slider, labels to show pamarater's name and its value.

        Args:
            param (str): A parameter to create slider.
        """
        min_ = self.current_params[param]["min"]
        max_ = self.current_params[param]["max"]
        step = self.current_params[param]["step"]
        value = self.current_params[param]["value"]

        slider = QSlider(Qt.Horizontal)
        if max_:
            slider.setRange(min_, max_)
        else:
            slider.setRange(0, 1)
        slider.setValue(int(value))
        slider.setTickPosition(QSlider.TicksBelow)
        slider.valueChanged.connect(lambda val, p=param: self.set_sliderval(p, val))

        if step:
            if max_ < 5:
                slider.setTickInterval(step)
            else:
                slider.setTickInterval(10)

        slider_label = QLabel(param)
        slider_value = QLabel(str(value))

        slider_label.setAlignment(Qt.AlignLeft | Qt.AlignVCenter)
        slider_value.setAlignment(Qt.AlignLeft | Qt.AlignVCenter)

        self.current_params[param]["slider"] = slider
        self.current_params[param]["slider_label"] = slider_label
        self.current_params[param]["slider_value"] = slider_value

    def add_prop_window(self) -> QGridLayout:
        """Create a table to show the current properties of camera.

        Returns:
            QGridLayout: PySide2 QGridLayout
        """
        header = ["property", "value"]
        self.prop_table_widget = QTableWidget(self)
        self.prop_table_widget.setColumnCount(len(header))
        self.prop_table_widget.setRowCount(len(self.prop_table))

        self.prop_table_widget.setHorizontalHeaderLabels(header)
        self.prop_table_widget.verticalHeader().setVisible(False)
        self.prop_table_widget.setAlternatingRowColors(True)
        self.prop_table_widget.horizontalHeader().setStretchLastSection(True)
        self.prop_table_widget.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.prop_table_widget.setFocusPolicy(Qt.NoFocus)

        for row, content in enumerate(self.prop_table):
            for col, elem in enumerate(content):
                self.item = QTableWidgetItem(elem)

                self.prop_table_widget.setItem(row, col, self.item)
        self.prop_table_widget.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum)
        #self.prop_table_widget.resizeColumnsToContents()
        #self.prop_table_widget.resizeRowsToContents()
        self.prop_table_widget.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.prop_table_widget.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.prop_table_widget.setSizeAdjustPolicy(QAbstractScrollArea.AdjustToContentsOnFirstShow)
        self.prop_table_widget.setColumnWidth(0, 150)
        self.prop_table_widget.setColumnWidth(1, 150)

        vbox = QVBoxLayout()
        vbox.addWidget(self.prop_table_widget)
        vbox.setContentsMargins(20, 20, 20, 20)
        self.prop_group = QGroupBox("Frame Properties")
        self.prop_group.setLayout(vbox)
        return self.prop_group

    def information_window_setup(self):
        """Creates information window.

        Creates the information window where the event related to camera or window.
        """
        self.text_edit = QTextEdit()
        self.text_edit.setReadOnly(True)
        self.text_edit.show()
        vbox = QVBoxLayout()
        vbox.addWidget(self.text_edit)
        self.text_edit_box = QGroupBox("Information", self)
        self.text_edit_box.setLayout(vbox)
        self.text_edit_box.setAlignment(Qt.AlignLeft)

    def create_mainlayout(self):
        """Create the main layout which consists of view area and information window.
        """
        self.main_layout.addLayout(self.create_view_area_layout())
        self.main_layout.addLayout(self.create_information_layout())

    def update_mainlayout(self):
        """Recreate the main layout.
        """
        self.delete_layout(self.information_layout)
        self.delete_layout(self.upper_right)
        self.add_prop_window()
        self.main_layout.addLayout(self.create_information_layout())

    def delete_layout(self, layout):
        """Delete layout

        Args:
            layout (QBoxLayout): QBoxLayout class object to delete
        """
        while layout.count():
            child = layout.takeAt(0)
            if child.widget():
                child.widget().deleteLater()
            try:
                child.spacerIitem().deleteLater()
            except:
                pass

    def create_view_area_layout(self) -> QVBoxLayout:
        """Creates view area layout
        """
        self.view_area_layout = QVBoxLayout()
        self.view_area_layout.addWidget(self.view, 2)
        self.view_area_layout.addWidget(self.text_edit_box)
        return self.view_area_layout

    def create_information_layout(self):
        """Creates information part layout

        upper-left: current properties
        upper-right: buttons
        lower: sliders
        """
        if self.param_separate:
            self.entry_box = QVBoxLayout()
            self.entry_box.addWidget(self.frame_button)
            self.entry_box.addWidget(self.filerule_button)
            self.entry_box.addWidget(self.default_button)
            self.entry_box.addStretch(1)
            self.entry_box.setSpacing(20)
            self.entry_box.setContentsMargins(20, 20, 20, 20)

            self.button_group_box = QGroupBox("Buttons", self)
            self.button_group_box.setLayout(self.entry_box)
            self.button_group_box.setAlignment(Qt.AlignLeft)

            self.upper_right = QVBoxLayout()
            self.upper_right.addWidget(self.prop_group, 1)
            self.upper_right.addWidget(self.button_group_box, 1)

            self.slider_group_box = QGroupBox("Parameters")
            self.slider_group_box.setLayout(self.slider_group)
            self.slider_group_box.setContentsMargins(20, 20, 20, 20)

            self.information_layout = QHBoxLayout()
            self.information_layout.addLayout(self.upper_right, 1)
            self.information_layout.addWidget(self.slider_group_box, 2)
            #self.information_layout.addStretch(1)
            return self.information_layout
        else:
            self.entry_box = QVBoxLayout()
            self.entry_box.addWidget(self.frame_button)
            self.entry_box.addWidget(self.filerule_button)
            self.entry_box.addWidget(self.default_button)
            self.entry_box.addStretch(1)
            self.entry_box.setSpacing(20)
            self.entry_box.setContentsMargins(20, 20, 20, 20)

            self.button_group_box = QGroupBox("Buttons", self)
            self.button_group_box.setLayout(self.entry_box)
            self.button_group_box.setAlignment(Qt.AlignLeft)

            self.upper_right = QHBoxLayout()
            self.upper_right.addWidget(self.prop_group)
            self.upper_right.addWidget(self.button_group_box)

            self.slider_group_box = QGroupBox("Parameters")
            self.slider_group_box.setLayout(self.slider_group)
            self.slider_group_box.setContentsMargins(20, 20, 20, 20)

            self.information_layout = QVBoxLayout()
            self.information_layout.addLayout(self.upper_right)
            self.information_layout.addWidget(self.slider_group_box)
            self.information_layout.setSpacing(30)
            return self.information_layout

    # decorator
    def display(func):
        def wrapper(self, *args, **kwargs):
            try:
                self.is_display = False
                self.stop_timer()
                func(self, *args, **kwargs)
            finally:
                self.is_display = True
                self.start_timer()
        return wrapper

    def stop_frame(self, checked: bool):
        """Stop reading next frame.

        Args:
            checked (bool): True when presse the Stop button (toggle on). False when press
                again (toggel off).
        """
        if checked:
            self.write_text("Stop !!")
            self.is_display = False
            self.stop_button.setText('Start')
            self.stop_button.setChecked(True)
            self.stop_act.setText('Start')
            self.stop_act.setChecked(True)
        else:
            self.write_text("Start !!")
            self.is_display = True
            self.stop_button.setText('&Pause')
            self.stop_button.setChecked(False)
            self.stop_act.setText('&Pause')
            self.stop_act.setChecked(False)

    def keyPressEvent(self, event):
        """Exit the program

        This method will be called when press the Escape key on the window.
        """
        if event.key() == Qt.Key_Escape:
            QApplication.quit()

    def get_coordinates(self, event):
        """Show the current coordinates and value in the pixel where the cursor is located.

        The status bar is updates by the obtained values.
        """
        if self.item is self.view.itemAt(event.pos()):
            sp = self.view.mapToScene(event.pos())
            lp = self.item.mapFromScene(sp).toPoint()
            (x, y) = lp.x(), lp.y()
            #color = self.frame.image.pixel(x, y)
            color = self.qimage.pixelColor(x, y)
            if self.colorspace == "rgb":
                value = color.getRgb()
            elif self.colorspace == "gray":
                value = color.value()

            # Return none if the coordinates are out of range
            if x < 0 and self.frame.width < x:
                return
            elif y < 0 and self.frame.height < y:
                return

            if self.frame.img_is_rgb:
                status_list = [
                    "( x : {}, y :{} )".format(x, y),
                    "R : {}".format(value[0]),
                    "G : {}".format(value[1]),
                    "B : {}".format(value[2]),
                    "alpha : {}".format(value[3])
                ]
            else:
                status_list = [
                    "( x : {}, y :{} )".format(x, y),
                    "gray value : {}".format(value),
                ]

            for statbar, stat in zip(self.statbar_list, status_list):
                statbar.showMessage(stat)

    def next_frame(self):
        """Get next frame from the connected camera.

        Get next frame, set it to the view area and update.
        """
        #print("display :", self.is_display)
        if self.is_display:
            self.camera.read_frame()
            self.convert_frame()
            self.scene.clear()
            self.scene.addPixmap(self.pixmap)
            self.update()
            #print("update")

    def convert_frame(self):
        """Convert the class of frame

        Create qimage, qpixmap objects from ndarray frame for displaying on the window.

        """
        if self.colorspace == "rgb":
            self.qimage = QImage(
                self.camera.frame.data,
                self.camera.frame.shape[1],
                self.camera.frame.shape[0],
                self.camera.frame.shape[1] * 3,
                QImage.Format_RGB888
                )
        elif self.colorspace == "gray":
            self.qimage = QImage(
                self.camera.frame.data,
                self.camera.frame.shape[1],
                self.camera.frame.shape[0],
                self.camera.frame.shape[1] * 1,
                QImage.Format_Grayscale8)

        self.pixmap.convertFromImage(self.qimage)

    def save_frame(self):
        """Save the frame on the window as an image.
        """
        if self.filename_rule == "Manual":
            self.save_frame_manual()
            if not self.filename:
                return None
            prm = re.sub(r"\.(.*)", ".csv", str(self.filename))
        else:
            self.filename = FileIO.get_filename(self.filename_rule, self.image_suffix, self.parent_dir)
            prm = str(self.filename).replace(self.image_suffix, "csv")

        if not self.dst.exists():
            self.dst.mkdir(parents=True)
        im = Image.fromarray(self.camera.frame)
        im.save(self.filename)

        # make a parameter file
        with open(prm, "w") as f:
            for name, key in self.current_params.items():
                f.write("{},{}\n".format(name, self.current_params[name]["value"]))

        self.write_text("{:<10}: {}".format("save image", self.filename))
        self.write_text("{:<10}: {}".format("save param", prm))

    def update_prop_table(self):
        """Updates the table that shows the camera properties.
        """
        w, h, cc, f = self.camera.get_properties()
        self.prop_table = [
            ["Fourcc", cc],
            ["Width", int(w)],
            ["Height", int(h)],
            ["FPS", "{:.1f}".format(f)],
            ["Bit depth", 8],
            ["Naming Style", self.filename_rule]
        ]
        col = 1
        for row in range(len(self.prop_table)):
            text = str(self.prop_table[row][col])
            self.prop_table_widget.item(row, col).setText(text)

    def record(self):
        """Start or end recording
        """
        if self.camera.is_recording:
            self.camera.stop_recording()
            self.rec_button.setText('&Rec')
            self.rec_act.setText('&Record')
            self.write_text("save : {}".format(self.video_filename))
        else:
            self.video_filename = FileIO.get_filename(self.filename_rule, self.video_suffix, self.parent_dir)
            self.camera.start_recording(self.video_filename, self.video_codec)
            self.rec_button.setText('Stop rec')
            self.rec_act.setText('Stop record')

    @display
    def save_frame_manual(self) -> bool:
        """Determine file name of image to save with QFileDialog
        """
        self.dialog = QFileDialog()
        self.dialog.setWindowTitle("Save File")
        self.dialog.setNameFilters([
            "image (*.jpg *.png *.tiff *.pgm)",
            "All Files (*)"
            ])
        self.dialog.setAcceptMode(QFileDialog.AcceptSave)
        self.dialog.setOption(QFileDialog.DontUseNativeDialog)

        if self.dialog.exec_():
            r = self.dialog.selectedFiles()

            # If the file name doesn't include supproted suffixes, add to the end.
            if re.search(".pgm$|.png$|.jpg$|.tiff$", r[0]):
                self.filename = r[0]
            else:
                self.filename = "{}.{}".format(r[0], self.image_suffix)
            return True
        else:
            return False

    def get_screensize(self):
        """Get current screen size from the output of linux cmd `xrandr`.
        """
        cmd = ["xrandr"]
        ret = subprocess.check_output(cmd)
        output = ret.decode()
        pattern = r"current(\s+\d+\s+x\s+\d+)"

        m = re.search(pattern, output)
        if m:
            size = re.sub(" ", "", m.group(1))
            w, h = map(int, size.split("x"))
            return w, h, size
        else:
            return None

    def set_sliderval(self, param: str, value: int):
        """Changes a camera parameter.

        Updates the label on the right of the slider if input value is valid.

        Args:
            param (str): A camera parameter
            value (int): its value
        """
        val = self.camera.set_parameter(param, value)
        self.current_params[param]["value"] = str(val)
        self.current_params[param]["slider_value"].setText(str(value))

    def set_param_default(self):
        """Sets all paramters to default.
        """
        for param, values in self.current_params.items():
            default = values["default"]
            self.camera.set_parameter(param, default)
            self.current_params[param]["slider"].setValue(int(default))
            self.current_params[param]["slider_value"].setText(str(default))

    def get_properties(self) -> list:
        """Get the current camera properties.

        Returns:
            list: parameters. fourcc, width, height, fps.
        """
        tmp = []
        for row in range(4):
            tmp.append(self.prop_table[row][1])
        return tmp

    def write_text(self, text: str, level: str = "info", color: str = None):
        """Writes the message into information window.

        Args:
            text (str): A text to write.
            level (str, optional): Log lebel of the message. Defaults to "info".
            color (str, optional): Font color. Defaults to None.
        """
        now = datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f")
        now = now[:-3]
        if color == "red":
            form = f"<font color='red'>[{level.upper():<4} {now}] {text}</font>"
        elif color == "yellow":
            form = f"<font color='yellow'>[{level.upper():<4} {now}] {text}</font>"
        else:
            form = f"[{level.upper():<4} {now}] {text}"
        self.text_edit.append(form)
示例#17
0
class QTraceViewer(QWidget):
    """
    Load a basic block trace through json and visualize it in the disassembly
    Ref: https://github.com/angr/angr-management/pull/122
    """

    TAG_SPACING = 50
    LEGEND_X = -50
    LEGEND_Y = 0
    LEGEND_WIDTH = 10

    TRACE_FUNC_X = 0
    TRACE_FUNC_Y = 0
    TRACE_FUNC_WIDTH = 50
    TRACE_FUNC_MINHEIGHT = 1000

    TAB_HEADER_SIZE = 40
    MAX_WINDOW_SIZE = 500

    MARK_X = LEGEND_X
    MARK_WIDTH = TRACE_FUNC_X - LEGEND_X + TRACE_FUNC_WIDTH
    MARK_HEIGHT = 1

    def __init__(self, workspace, disasm_view, parent=None):
        super().__init__(parent=parent)
        self.workspace = workspace
        self.disasm_view = disasm_view

        self.mark = None
        self.legend = None
        self.legend_height = 0
        self.legend_img = None
        self.trace_func_unit_height = 0

        self.trace_func = None
        self.trace_id = None

        self.view = None
        self.traceView = None
        self.traceTab = None
        self.traceScene = None
        self.multiView = None
        self.listView = None
        self.mark = None
        self.curr_position = 0
        self._use_precise_position = False
        self._selected_traces = []

        self._init_widgets()

        self.trace.am_subscribe(self._on_set_trace)
        self.selected_ins.am_subscribe(self._on_select_ins)
        self.traceTab.installEventFilter(self)

    #
    # Forwarding properties
    #

    @property
    def trace(self):
        return self.workspace.instance.trace

    @property
    def multi_trace(self):
        return self.workspace.instance.multi_trace

    @property
    def selected_ins(self):
        return self.disasm_view.infodock.selected_insns

    def _init_widgets(self):
        self.view = QTabWidget()  # QGraphicsView()

        self.traceTab = QWidget()
        tracelayout = QVBoxLayout()

        self.traceView = QGraphicsView()
        self.traceScene = QGraphicsScene()
        self.traceView.setScene(self.traceScene)

        self.listView = QTableWidget(0, 2)  # row, col
        self.listView.setHorizontalHeaderItem(0, QTableWidgetItem("Trace ID"))
        self.listView.setHorizontalHeaderItem(1, QTableWidgetItem("Input ID"))
        self.listView.setSelectionMode(QAbstractItemView.SingleSelection)
        self.listView.setSelectionBehavior(QAbstractItemView.SelectRows)
        # self.listView.horizontalHeader().setStretchLastSection(True)
        # self.listView.horizontalHeader().setSectionResizeModel(0, QHeaderView.Stretch)
        self.listView.cellClicked.connect(self._switch_current_trace)

        self.traceSeedButton = QPushButton("View Input Seed")
        self.traceSeedButton.clicked.connect(self._view_input_seed)

        tracelayout.addWidget(self.traceView)
        tracelayout.addWidget(self.listView)
        tracelayout.addWidget(self.traceSeedButton)
        self.traceTab.setLayout(tracelayout)

        self.multiView = QWidget()
        multiLayout = QVBoxLayout()
        self.multiTraceList = QTableWidget(0, 2)  # row, col
        self.multiTraceList.setSelectionMode(QAbstractItemView.MultiSelection)
        self.multiTraceList.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.multiTraceList.setHorizontalScrollMode(
            self.multiTraceList.ScrollPerPixel)
        self.multiTraceList.setHorizontalHeaderItem(
            0, QTableWidgetItem("Trace ID"))
        self.multiTraceList.setHorizontalHeaderItem(
            1, QTableWidgetItem("Input ID"))
        self.selectMultiTrace = QPushButton("Refresh Heatmap")
        self.selectMultiTrace.clicked.connect(self._refresh_heatmap)
        multiLayout.addWidget(self.multiTraceList)
        multiLayout.addWidget(self.selectMultiTrace)
        self.multiView.setLayout(multiLayout)

        self.view.addTab(self.traceTab, "SingleTrace")
        self.view.addTab(self.multiView, "MultiTrace HeatMap")
        self.SINGLE_TRACE = 0
        self.MULTI_TRACE = 1

        self.view.currentChanged.connect(self._on_tab_change)

        self._reset()

        layout = QVBoxLayout()
        layout.addWidget(self.view)
        layout.setContentsMargins(0, 0, 0, 0)
        layout.setAlignment(self.view, Qt.AlignLeft)

        self.setLayout(layout)

    def _reset(self):
        self.traceScene.clear()  #clear items
        self.listView.clearContents()
        self.multiTraceList.clearContents()
        self.mark = None

        self.legend = None
        self.legend_height = 0

        self.trace_func = QGraphicsItemGroup()
        self.trace_id = QGraphicsItemGroup()
        self.traceScene.addItem(self.trace_func)
        self.hide()

    def _view_input_seed(self):
        current_trace_stats = self.trace.am_obj
        input_id = current_trace_stats.input_id

        inputSeed = self.multi_trace.am_obj.get_input_seed_for_id(input_id)
        msgText = "%s" % inputSeed
        msgDetails = "Input for [%s]" % current_trace_stats.id
        msgbox = QMessageBox()
        msgbox.setWindowTitle("Seed Input")
        msgbox.setDetailedText(msgDetails)
        msgbox.setText(msgText)
        msgbox.setStandardButtons(QMessageBox.Ok)
        msgbox.exec()

    def _switch_current_trace(self, row):
        if self.listView.rowCount() <= 0:
            return

        current_trace = self.trace.am_obj.id
        new_trace = self.multiTraceList.item(row, 0).text()
        if current_trace == new_trace:
            return

        trace_stats = self.multi_trace.am_obj.get_trace_with_id(new_trace)
        if trace_stats:
            self.trace.am_obj = trace_stats
            self._on_set_trace()

    def _on_set_trace(self):
        self._reset()
        if self.trace.am_none or self.trace.count is None:
            return

        l.debug('minheight: %d, count: %d', self.TRACE_FUNC_MINHEIGHT,
                self.trace.count)
        if self.trace.count <= 0:
            l.warning(
                "No valid addresses found in trace to show. Check base address offsets?"
            )
            self.trace.am_obj = None
            self.trace.am_event()
            return
        if self.TRACE_FUNC_MINHEIGHT < self.trace.count * 15:
            self.trace_func_unit_height = 15
            show_func_tag = True
        else:
            self.trace_func_unit_height = self.TRACE_FUNC_MINHEIGHT / self.trace.count
            show_func_tag = True

        self.legend_height = int(self.trace.count *
                                 self.trace_func_unit_height)

        self._show_trace_func(show_func_tag)
        self._show_legend()
        self._show_trace_ids()
        self._set_mark_color()
        self._refresh_multi_list()

        boundingSize = self.traceScene.itemsBoundingRect().width()
        windowSize = boundingSize
        if boundingSize > self.MAX_WINDOW_SIZE:
            windowSize = self.MAX_WINDOW_SIZE
        self.traceScene.setSceneRect(
            self.traceScene.itemsBoundingRect())  #resize
        self.setFixedWidth(windowSize)

        # self.listScene.setSceneRect(self.listScene.itemsBoundingRect()) #resize
        self.multiView.setFixedWidth(windowSize)
        cellWidth = windowSize // 2
        self.listView.setColumnWidth(0, cellWidth)
        self.listView.setColumnWidth(1, cellWidth)
        self.listView.setFixedHeight(self.multiView.height() // 4)
        self.multiTraceList.setColumnWidth(0, cellWidth)
        self.multiTraceList.setColumnWidth(1, cellWidth)
        self.view.setFixedWidth(windowSize)

        self.show()

    def _populate_trace_table(self, view, trace_ids):
        numIDs = len(trace_ids)
        view.clearContents()
        view.setRowCount(numIDs)
        row = 0  #start after label row
        for traceID in trace_ids:
            inputID = self.multi_trace.am_obj.get_input_id_for_trace_id(
                traceID)
            if inputID is None:
                self.workspace.log("No inputID found for trace %s" % traceID)
            view.setItem(row, 0, QTableWidgetItem(traceID))
            view.setItem(row, 1, QTableWidgetItem(inputID))
            row += 1

    def _refresh_heatmap(self):
        multiTrace = self.multi_trace.am_obj
        multiTrace.clear_heatmap()
        multiTrace.is_active_tab = True

        selected_items = self.multiTraceList.selectedItems()
        self._selected_traces.clear()
        for row in range(self.multiTraceList.rowCount()):
            item = self.multiTraceList.item(row, 0)
            if item in selected_items:
                self._selected_traces.append(item.text())
        multiTrace.reload_heatmap(self._selected_traces)
        self.multi_trace.am_event()

    def _refresh_multi_list(self):
        multiTrace = self.multi_trace.am_obj
        trace_ids = multiTrace.get_all_trace_ids()

        self.multiTraceList.clearContents()
        self._populate_trace_table(self.multiTraceList, trace_ids)
        if self._selected_traces and self.multiTraceList.rowCount() > 0:
            self.multiTraceList.item(0, 0).setSelected(True)
            self.multiTraceList.item(0, 1).setSelected(True)
        else:
            for row in range(self.multiTraceList.rowCount()):
                item = self.multiTraceList.item(row, 0)
                inputItem = self.multiTraceList.item(row, 1)
                if item.text() in self._selected_traces:
                    item.setSelected(True)
                    inputItem.setSelected(True)
        self.multi_trace.am_event()

    def _on_tab_change(self):
        # self._reset()
        multiTrace = self.multi_trace.am_obj
        if self.view.currentIndex() == self.MULTI_TRACE:
            multiTrace.is_active_tab = True
            self._refresh_multi_list()
        elif self.view.currentIndex() == self.SINGLE_TRACE:
            multiTrace = self.multi_trace.am_obj
            multiTrace.is_active_tab = False
            self._show_trace_ids()

    def _on_select_ins(self, **kwargs):  # pylint: disable=unused-argument
        if self.trace.am_none:
            return

        if self.mark is not None:
            for i in self.mark.childItems():
                self.mark.removeFromGroup(i)
                self.traceScene.removeItem(i)
            self.traceScene.removeItem(self.mark)

        self.mark = QGraphicsItemGroup()
        self.traceScene.addItem(self.mark)

        if self.selected_ins:
            addr = next(iter(self.selected_ins))
            positions = self.trace.get_positions(addr)
            if positions:  #if addr is in list of positions
                if not self._use_precise_position:  #handle case where insn was selected from disas view
                    self.curr_position = positions[0] - self.trace.count
                for p in positions:
                    color = self._get_mark_color(p, self.trace.count)
                    y = self._get_mark_y(p)

                    if p == self.trace.count + self.curr_position:  #add thicker line for 'current' mark
                        self.mark.addToGroup(
                            self.traceScene.addRect(self.MARK_X, y,
                                                    self.MARK_WIDTH,
                                                    self.MARK_HEIGHT * 4,
                                                    QPen(QColor('black')),
                                                    QBrush(color)))
                    else:
                        self.mark.addToGroup(
                            self.traceScene.addRect(self.MARK_X, y,
                                                    self.MARK_WIDTH,
                                                    self.MARK_HEIGHT,
                                                    QPen(color),
                                                    QBrush(color)))

                self.traceScene.update()  #force redraw of the traceScene
                self.scroll_to_position(self.curr_position)

    def scroll_to_position(self, position):
        relative_pos = self.trace.count + position
        y_offset = self._get_mark_y(relative_pos)

        scrollValue = 0
        if y_offset > 0.5 * self.traceView.size().height():
            scrollValue = y_offset - 0.5 * self.traceView.size().height()
        scrollValue = min(scrollValue,
                          self.traceView.verticalScrollBar().maximum())
        self.traceView.verticalScrollBar().setValue(scrollValue)
        self._use_precise_position = False

    def jump_next_insn(self):
        if self.curr_position + self.trace.count < self.trace.count - 1:  #for some reason indexing is done backwards
            self.curr_position += 1
            self._use_precise_position = True
            bbl_addr = self.trace.get_bbl_from_position(self.curr_position)
            func = self.trace.get_func_from_position(self.curr_position)
            self._jump_bbl(func, bbl_addr)

    def jump_prev_insn(self):
        if self.curr_position + self.trace.count > 0:
            self.curr_position -= 1
            self._use_precise_position = True
            bbl_addr = self.trace.get_bbl_from_position(self.curr_position)
            func = self.trace.get_func_from_position(self.curr_position)
            self._jump_bbl(func, bbl_addr)

    def eventFilter(self, obj, event):  #specifically to catch arrow keys #pylint: disable=unused-argument
        # more elegant solution to link w/ self.view's scroll bar keypressevent?
        if event.type() == QEvent.Type.KeyPress:
            if not event.modifiers() & Qt.ShiftModifier:  #shift + arrowkeys
                return False
            key = event.key()
            if key in [Qt.Key_Up, Qt.Key_Left]:
                self.jump_prev_insn()
            elif key in [Qt.Key_Down, Qt.Key_Right]:
                self.jump_next_insn()
            return True

        return False  # pass through all other events

    def mousePressEvent(self, event):
        button = event.button()
        pos = self._to_logical_pos(event.pos())
        if button == Qt.LeftButton and self.view.currentIndex(
        ) == self.SINGLE_TRACE and self._at_legend(pos):
            func = self._get_func_from_y(pos.y())
            bbl_addr = self._get_bbl_from_y(pos.y())
            self._use_precise_position = True
            self.curr_position = self._get_position(pos.y())
            self._jump_bbl(func, bbl_addr)

    def _jump_bbl(self, func, bbl_addr):
        all_insn_addrs = self.workspace.instance.project.factory.block(
            bbl_addr).instruction_addrs
        # TODO: replace this with am_events perhaps?
        if func is None:
            return
        self.workspace.on_function_selected(func)
        self.selected_ins.clear()
        self.selected_ins.update(all_insn_addrs)
        self.selected_ins.am_event()
        # TODO: this ought to happen automatically as a result of the am_event
        self.disasm_view.current_graph.show_instruction(bbl_addr)

    def _get_mark_color(self, i, total):
        relative_gradient_pos = i * 1000 // total
        return self.legend_img.pixelColor(self.LEGEND_WIDTH // 2,
                                          relative_gradient_pos)

    def _get_mark_y(self, i):
        return self.TRACE_FUNC_Y + self.trace_func_unit_height * i

    def _show_trace_ids(self):
        trace_ids = self.multi_trace.get_all_trace_ids()
        # traceID = self.listScene.addText(id_txt, QFont("Source Code Pro", 7))
        # traceID.setPos(5,5)
        self.listView.clearContents()
        self._populate_trace_table(self.listView, trace_ids)
        if len(self.listView.selectedItems()) <= 0 and not self.trace.am_none:
            for row in range(self.listView.rowCount()):
                item = self.listView.item(row, 0)
                inputItem = self.listView.item(row, 1)
                if self.trace.id in item.text():
                    item.setSelected(True)
                    inputItem.setSelected(True)
                    break

    def _show_trace_func(self, show_func_tag):
        x = self.TRACE_FUNC_X
        y = self.TRACE_FUNC_Y
        prev_name = None
        for position in self.trace.trace_func:
            bbl_addr = position.bbl_addr
            func_name = position.func_name
            l.debug('Draw function %x, %s', bbl_addr, func_name)
            color = self.trace.get_func_color(func_name)
            self.trace_func.addToGroup(
                self.traceScene.addRect(x, y, self.TRACE_FUNC_WIDTH,
                                        self.trace_func_unit_height,
                                        QPen(color), QBrush(color)))
            if show_func_tag is True and func_name != prev_name:
                tag = self.traceScene.addText(func_name,
                                              QFont("Source Code Pro", 7))
                tag.setPos(x + self.TRACE_FUNC_WIDTH + self.TAG_SPACING,
                           y - tag.boundingRect().height() // 2)
                self.trace_func.addToGroup(tag)
                anchor = self.traceScene.addLine(
                    self.TRACE_FUNC_X + self.TRACE_FUNC_WIDTH, y,
                    x + self.TRACE_FUNC_WIDTH + self.TAG_SPACING, y)
                self.trace_func.addToGroup(anchor)
                prev_name = func_name
            y += self.trace_func_unit_height

    @staticmethod
    def _make_legend_gradient(x1, y1, x2, y2):
        gradient = QLinearGradient(x1, y1, x2, y2)
        gradient.setColorAt(0.0, Qt.red)
        gradient.setColorAt(0.4, Qt.yellow)
        gradient.setColorAt(0.6, Qt.green)
        gradient.setColorAt(0.8, Qt.blue)
        gradient.setColorAt(1.0, Qt.darkBlue)
        return gradient

    def _show_legend(self):
        pen = QPen(Qt.transparent)

        gradient = self._make_legend_gradient(
            self.LEGEND_X, self.LEGEND_Y, self.LEGEND_X,
            self.LEGEND_Y + self.legend_height)
        brush = QBrush(gradient)
        self.legend = self.traceScene.addRect(self.LEGEND_X, self.LEGEND_Y,
                                              self.LEGEND_WIDTH,
                                              self.legend_height, pen, brush)

        reference_gradient = self._make_legend_gradient(
            0, 0, self.LEGEND_WIDTH, 1000)
        base_img = QImage(self.LEGEND_WIDTH, 1000, QImage.Format.Format_ARGB32)
        p = QPainter(base_img)
        p.fillRect(base_img.rect(), reference_gradient)
        self.legend_img = base_img  #reference shade

    def _set_mark_color(self):
        for p in range(self.trace.count):
            color = self._get_mark_color(p, self.trace.count)
            self.trace.set_mark_color(p, color)

    def _at_legend(self, pos):
        x = pos.x()
        y = pos.y()
        return self.TRACE_FUNC_X + self.LEGEND_X < x < self.traceView.width() and \
           self.TRACE_FUNC_Y < y < self.TRACE_FUNC_Y + self.legend_height

    def _to_logical_pos(self, pos):
        x_offset = self.traceView.horizontalScrollBar().value()
        y_offset = self.traceView.verticalScrollBar().value()
        return QPoint(pos.x() + x_offset, pos.y() + y_offset)

    def _get_position(self, y):
        y_relative = y - self.legend_height - self.TAB_HEADER_SIZE

        return int(y_relative // self.trace_func_unit_height)

    def _get_bbl_from_y(self, y):
        position = self._get_position(y)
        return self.trace.get_bbl_from_position(position)

    def _get_func_from_y(self, y):
        position = self._get_position(y)
        func = self.trace.get_func_from_position(position)
        return func
示例#18
0
class Escena(QWidget):
    def __init__(self):
        QWidget.__init__(self)
        self.resize(QDesktopWidget().availableGeometry(self).size() * 0.6)
        self.scene = QGraphicsScene()
        self.scene.setSceneRect(-3000, -4000, 6000, 8000)
        self.view = QGraphicsView(self.scene)
        self.view.resize(self.size())
        self.view.fitInView(self.scene.sceneRect(), Qt.KeepAspectRatio)
        self.view.setParent(self)
        self.view.setTransformationAnchor(QGraphicsView.NoAnchor)
        self.view.setResizeAnchor(QGraphicsView.NoAnchor)
        self.view.scale(3, -3)
        self.lines = []
        self.show()

    def wheelEvent(self, event):
        zoomInFactor = 1.15
        zoomOutFactor = 1 / zoomInFactor
        # Zoom
        if event.delta() > 0:
            zoomFactor = zoomInFactor
        else:
            zoomFactor = zoomOutFactor
        self.view.scale(zoomFactor, zoomFactor)

    def resizeEvent(self, event):
        self.view.resize(self.size())

    def draw(self, comps, cluster):
        colors = QColor.colorNames()

        # for co in sample:
        #     print(co)
        #     x, _, z, _ = co['world']
        #     self.scene.addEllipse(x-50,z-50,100,100, pen=QPen(QColor('orange'), 5))

        # x,_,z,_ = sample[-1]['world']
        # self.scene.addRect(x,z,60,60, pen=QPen(QColor('red'), 100))
        # x,_,z,_ = sample[0]['world']
        # self.scene.addRect(x,z,60,60, pen=QPen(QColor('green'), 100))

        # for co in comps:
        #     if sample[co[-1]]['timestamp']-sample[co[0]]['timestamp'] > 200 and len(co)> 4:
        #         color = colors[random.randint(0, len(colors)-1)]
        #         for c in co:
        #             x, _, z, _ = sample[c]['world']
        #             self.scene.addEllipse(x-15,z-15,30,30, pen=QPen(QColor(color), 100), brush=QBrush(color=QColor(color)))

        if cluster[-1]['timestamp'] - cluster[0]['timestamp'] > 200 and len(
                cluster) > 4:
            color = colors[random.randint(0, len(colors) - 1)]
            for sample in cluster:
                x, _, z, _ = sample['world']
                self.scene.addEllipse(x - 15,
                                      z - 15,
                                      30,
                                      30,
                                      pen=QPen(QColor(color), 100),
                                      brush=QBrush(color=QColor(color)))

    def drawTrack(self, clusters):
        colors = QColor.colorNames()
        # for line in self.lines:
        #     self.scene.removeItem(line)
        self.scene.clear()
        for cluster in clusters:
            color = colors[random.randint(0, len(colors) - 1)]
            for t in cluster:
                self.scene.addLine(t[0][0],
                                   t[0][1],
                                   t[1][0],
                                   t[1][1],
                                   pen=QPen(QColor(color), 60))
示例#19
0
class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)

        self.scene = QGraphicsScene()
        self.scene.setSceneRect(0, 0, 500, 500)
        self.ui.graphicsView.setScene(self.scene)

        self.pen = QPen()
        self.pen.setColor(QColor(0, 0, 0))
        self.pen.setWidth(1)

        self.capturador = Capturador()

        self.ui.pushButton.clicked.connect(self.click)
        self.ui.pushButton_2.clicked.connect(self.mostrar)

        self.ui.actionGuardar.triggered.connect(self.guardar)
        self.ui.actionAbrir_2.triggered.connect(self.abrir)

    @Slot()
    def guardar(self):

        file = QFileDialog.getSaveFileName(self, 'Guardar archivo...', '.',
                                           'JSON (*.json)')
        print(file)
        self.capturador.guardar(file[0], self.pen, self.scene)

    @Slot()
    def abrir(self):
        file = QFileDialog.getOpenFileName(self, 'Abrir archivo', '.',
                                           'JSON (*.json)')
        self.capturador.recuperar(file[0])

    @Slot()
    def mostrar(self):
        self.scene.addLine(0, 0, 499, 0, self.pen)
        for particula in self.capturador.lista:
            self.ui.plainTextEdit.insertPlainText(str(particula))
            self.pen.setColor(
                QColor(particula.red, particula.green, particula.blue))
            self.scene.addEllipse(
                particula.origenX, particula.origenY, 5, 5, self.pen,
                QBrush(
                    QColor(particula.red, 10, particula.green,
                           particula.blue)))
            self.scene.addLine(particula.origenX, particula.origenY,
                               particula.destinoX, particula.destinoY,
                               self.pen)
        #self.paqueteria.mostrar()

    @Slot()
    def click(self):

        id = self.ui.lineEdit.text()
        origenX = self.ui.lineEdit_2.text()
        origenY = self.ui.lineEdit_6.text()
        destinoX = self.ui.lineEdit_3.text()
        destinoY = self.ui.lineEdit_7.text()
        velocidad = self.ui.lineEdit_4.text()
        red = self.ui.lineEdit_5.text()
        green = self.ui.lineEdit_8.text()
        blue = self.ui.lineEdit_9.text()

        print(id, origenX, origenY, destinoX, destinoY, velocidad, red, green,
              blue)

        partiula = Particula()
        partiula.id = id
        partiula.origenX = int(origenX)
        partiula.origenY = int(origenY)
        partiula.destinoX = int(destinoX)
        partiula.destinoY = int(destinoY)
        partiula.distancia = math.sqrt(
            pow((int(destinoX) - int(origenX)), 2) +
            pow((int(destinoY) - int(origenY)), 2))
        partiula.red = int(red)
        partiula.green = int(green)
        partiula.blue = int(blue)
        partiula.velocidad = int(velocidad)

        self.capturador.agregar(partiula)

        msg = QMessageBox.information(
            self, 'Exito', 'Se agrego paquete con exito'
        )  #Ventana de mensaje de la libreria QMessageBox

        self.ui.lineEdit.clear()  #Limpiar campos
        self.ui.lineEdit_2.clear()
        self.ui.lineEdit_3.clear()
        self.ui.lineEdit_4.clear()
        self.ui.lineEdit_5.clear()
        self.ui.lineEdit_6.clear()
        self.ui.lineEdit_7.clear()
        self.ui.lineEdit_8.clear()
        self.ui.lineEdit_9.clear()
示例#20
0
class ImageView(TopicMessageView):
    """
    Popup image viewer
    """
    name = 'Image'

    def __init__(self, timeline, parent, topic):
        super(ImageView, self).__init__(timeline, parent, topic)

        self._image = None
        self._image_topic = None
        self._image_stamp = None
        self.quality = Image.NEAREST  # quality hint for scaling

        # TODO put the image_topic and image_stamp on the picture or display them in some fashion
        self._overlay_font_size = 14.0
        self._overlay_indent = (4, 4)
        self._overlay_color = (0.2, 0.2, 1.0)

        self._image_view = QGraphicsView(parent)
        self._image_view.resizeEvent = self._resizeEvent
        self._scene = QGraphicsScene()
        self._image_view.setScene(self._scene)
        parent.layout().addWidget(self._image_view)

    # MessageView implementation
    def _resizeEvent(self, event):
        # TODO make this smarter. currently there will be no scrollbar even if the timeline extends beyond the viewable area
        self._scene.setSceneRect(0, 0, self._image_view.size().width() - 2, self._image_view.size().height() - 2)
        self.put_image_into_scene()

    def message_viewed(self, bag, msg_details):
        """
        refreshes the image
        """
        TopicMessageView.message_viewed(self, bag, msg_details)
        topic, msg, t = msg_details[:3]
        if not msg:
            self.set_image(None, topic, 'no message')
        else:
            self.set_image(msg, topic, msg.header.stamp)

    def message_cleared(self):
        TopicMessageView.message_cleared(self)
        self.set_image(None, None, None)

    # End MessageView implementation
    def put_image_into_scene(self):
        if self._image:
            resized_image = self._image.resize((self._image_view.size().width() - 2, self._image_view.size().height() - 2), self.quality)

            QtImage = ImageQt(resized_image)
            pixmap = QPixmap.fromImage(QtImage)
            self._scene.clear()
            self._scene.addPixmap(pixmap)

    def set_image(self, image_msg, image_topic, image_stamp):
        self._image_msg = image_msg
        if image_msg:
            self._image = image_helper.imgmsg_to_pil(image_msg)
        else:
            self._image = None
        self._image_topic = image_topic
        self._image_stamp = image_stamp
        self.put_image_into_scene()
示例#21
0
class CanvasGraphicsView(QGraphicsView):
    onSelection = Signal(PickNode)
    requestEditMode = Signal(bool)

    def __init__(self, parent=None):
        super(CanvasGraphicsView, self).__init__(parent)

        self.setFocusPolicy(Qt.StrongFocus)
        # Scene properties
        self.setAcceptDrops(True)
        self.setMouseTracking(True)
        self.setRenderHint(QPainter.Antialiasing)
        self.setTransformationAnchor(QGraphicsView.AnchorUnderMouse)
        self.setResizeAnchor(QGraphicsView.AnchorUnderMouse)
        self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.setBackgroundBrush(QBrush(QColor(51, 51, 51)))
        self.setFrameShape(QFrame.NoFrame)
        self.setDragMode(QGraphicsView.RubberBandDrag)
        self.ViewportUpdateMode(QGraphicsView.BoundingRectViewportUpdate)

        self.init()

    def init(self):
        self.piiPath = str()
        self._model = {'background': str()}
        self._isPanning = False
        self._isZooming = False
        self._mousePressed = False
        self._scene = QGraphicsScene()
        self._scene.selectionChanged.connect(self.update_node_settings)
        self._backgroundNode = QGraphicsPixmapItem()
        self._scene.addItem(self._backgroundNode)
        self._orderSelected = list()
        self._lastPos = QPoint(0, 0)
        self.editMode = False
        self._namespace = str()
        self._dragMulti = list()

        self._defaultColor = QColor(255, 255, 255)
        self._defaultTextColor = QColor(0, 0, 0)
        self._defaultTextSize = 20
        self._defaultText = "New Node"

        self.workHight = 2160
        self.workWidth = 4096

        self.setScene(self._scene)
        self.setContextMenuPolicy(Qt.CustomContextMenu)
        self.setBackgroundImage(str())

    def update_node_settings(self):
        if self._orderSelected:
            node = self._orderSelected[-1]
            self._defaultText = node.toPlainText()
            self._defaultColor = node.Background
            self._defaultTextColor = node.defaultTextColor()
            self._defaultTextSize = node.font().pointSize()

    def update_maya_selection(self):
        '''
        Update Maya Scene base on active selection.
        '''
        clearSelection()
        selection = list()
        for each in self._orderSelected:
            selection += each.Items
        if selection:
            selectObjects(selection)

    def setBackgroundImage(self, path=str()):
        '''
        Set background image

        Parameters
        ----------
        path: (str)
            Path to background image.
        '''
        self._model['background'] = path
        self.setStatusTip(self._model['background'])
        pixmap = QPixmap(self._model['background'])
        self._backgroundNode.setPixmap(pixmap)

    def getBackgroundImage(self):
        '''
        Get background image
        '''
        return self._model['background']

    BackgroundImage = property(getBackgroundImage, setBackgroundImage)

    def actionMenu(self, QPos):
        '''
        Show action menu.

        Parameters
        ----------
        QPos: (list)
            list of x and y location.
        '''
        self.mainMenu = QMenu()

        add_action = self.mainMenu.addAction('Add A Button')
        add_action.setEnabled(self.editMode)
        add_action.triggered.connect(self.add_node)

        addMany_action = self.mainMenu.addAction('Add Many Buttons')
        addMany_action.setEnabled(self.editMode)
        addMany_action.triggered.connect(self.add_multiple_nodes)

        activeNode = self.mouse_on_node()
        if activeNode:
            update_action = self.mainMenu.addAction('Update Button')
            update_action.setEnabled(self.editMode)
            update_action.triggered.connect(
                lambda: self.update_node(activeNode))

        delete_action = self.mainMenu.addAction('Delete Button')
        delete_action.setEnabled(self.editMode)
        delete_action.setShortcut('Backspace')
        delete_action.triggered.connect(self.removeSelected)

        self.mainMenu.addSeparator()

        # search for selected ButtonNode
        btnStatus = [
            isinstance(n, ButtonNode) for n in self._scene.selectedItems()
        ]
        if True in btnStatus:
            # first ButtonNode
            activeNode = self._scene.selectedItems()[btnStatus.index(True)]
            command_action = self.mainMenu.addAction('Edit Command Button...')
            command_action.setEnabled(self.editMode)
            command_action.triggered.connect(
                lambda: self.update_ButtonNode(activeNode))
        else:
            command_action = self.mainMenu.addAction('add Command Button...')
            command_action.setEnabled(self.editMode)
            command_action.triggered.connect(self.add_commands)

        self.mainMenu.addSeparator()

        reset_action = self.mainMenu.addAction('Reset View')
        reset_action.setShortcut('H')
        reset_action.triggered.connect(self.reset_view)

        frame_action = self.mainMenu.addAction('Frame View')
        frame_action.setShortcut('F')
        frame_action.triggered.connect(self.frame_view)

        self.mainMenu.addSeparator()

        alignGrp = QMenu('Align')
        self.mainMenu.addMenu(alignGrp)

        hac_action = alignGrp.addAction('Horizontal Align Center')
        hac_action.setIcon(QIconSVG('h_align-01'))
        hac_action.setEnabled(self.editMode)
        hac_action.triggered.connect(self.align_horizontal)

        vac_action = alignGrp.addAction('Vertical Align Center')
        vac_action.setIcon(QIconSVG('v_align-01'))
        vac_action.setEnabled(self.editMode)
        vac_action.triggered.connect(self.align_vertical)

        hd_action = alignGrp.addAction('Horizontal Distribute')
        hd_action.setIcon(QIconSVG('h_d_align-01'))
        hd_action.setEnabled(self.editMode)
        hd_action.triggered.connect(self.align_horizontal_distribute)

        vd_action = alignGrp.addAction('Vertical Distribute')
        vd_action.setIcon(QIconSVG('v_d_align-01'))
        vd_action.setEnabled(self.editMode)
        vd_action.triggered.connect(self.align_vertical_distribute)

        alignGrp.addSeparator()

        ins_action = alignGrp.addAction('Increase Size')
        ins_action.setShortcut('+')
        ins_action.setEnabled(self.editMode)
        ins_action.triggered.connect(self.increase_size)

        dis_action = alignGrp.addAction('Decrease Size')
        dis_action.setShortcut('-')
        dis_action.setEnabled(self.editMode)
        dis_action.triggered.connect(self.decrease_size)

        self.mainMenu.addSeparator()

        edit_mode = self.mainMenu.addAction('Edit Mode')
        edit_mode.setCheckable(True)
        edit_mode.setChecked(self.editMode)
        edit_mode.triggered.connect(
            lambda: self.request_edit(not self.editMode))

        pos = self.mapToGlobal(QPoint(0, 0))
        self.mainMenu.move(pos + QPos)
        self.mainMenu.show()

    def mouse_on_node(self):
        globPosition = self.mapFromGlobal(QCursor.pos())
        scenePosition = self.mapToScene(globPosition)
        for node in self._scene.items():
            if isinstance(node, PickNode):
                if node.mapRectToScene(
                        node.boundingRect()).contains(scenePosition):
                    return node
        return None

    def update_node(self, node=PickNode):
        '''
        Update the Node selection base on selection in maya.
        '''
        mayaScene = getActiveItems()
        # for each in self._scene.selectedItems():
        node.Items = mayaScene

    def update_ButtonNode(self, node=ButtonNode):
        '''
        Update the ButtonNode commands.

        Parameters
        ----------
        node: (ButtonNode)
            ButtonNode Node.
        '''
        self.newCommand = CommandDialog(text=node.toPlainText(),
                                        cmd=node.Command,
                                        cmdType=node.CommandsType)
        if self.newCommand.exec_() == QDialog.Accepted:
            data = self.newCommand.Raw
            node.setPlainText(data[PIIButton.TEXT])
            node.Command = data[PIIButton.COMMAND]
            node.CommandsType = data[PIIButton.COMMANDTYPE]

    def add_commands(self):
        '''
        Create a new ButtonNode with Commands.
        '''
        globPosition = self.mapFromGlobal(QCursor.pos())
        scenePosition = self.mapToScene(globPosition)
        self.newCommand = CommandDialog()
        if self.newCommand.exec_() == QDialog.Accepted:
            data = self.newCommand.Raw
            self.create_button(position=scenePosition,
                               text=data[PIIButton.TEXT],
                               size=self._defaultTextSize,
                               textColor=self._defaultTextColor,
                               bgColor=self._defaultColor,
                               cmd=data[PIIButton.COMMAND],
                               cmdType=data[PIIButton.COMMANDTYPE])

    def align_horizontal(self):
        '''
        Align the selection to center horizontally.
        '''
        selected = self._scene.selectedItems()
        if len(selected) > 1:
            minValue = selected[0].y()
            maxValue = selected[0].y()
            whole = None
            for each in selected:
                y = each.y()
                value = y + each.boundingRect().height()
                # finding lowest value
                minValue = y if y < minValue else minValue
                minValue = value if value < minValue else minValue
                # finding highest value
                maxValue = y if y > maxValue else maxValue
                maxValue = value if value > maxValue else maxValue

            total = maxValue - minValue
            if total != 0:
                middle = (maxValue + minValue) / 2
                for each in selected:
                    center = each.shape().boundingRect().center()
                    start_y = each.y()
                    offset = start_y + center.y() - middle
                    each.setY(each.y() - offset)

    def align_vertical(self):
        '''
        Align the selection to center vertically.
        '''
        selected = self._scene.selectedItems()
        if len(selected) > 1:
            # sort it based on x position + width
            selected = sorted(selected,
                              key=lambda x: x.x() + x.boundingRect().width())
            leftNode = selected[0]
            rightNode = selected[-1]
            # total length of x axis
            total = rightNode.boundingRect().width() + rightNode.x(
            ) - leftNode.x()
            if total != 0:
                middle = (total / 2) + leftNode.x()
                for each in selected:
                    center = each.shape().boundingRect().center()
                    start_x = each.x()
                    offset = start_x + center.x() - middle
                    each.setX(each.x() - offset)

    def align_horizontal_distribute(self):
        '''
        Disturbute the selected nodes evenly between first node on the left and last 
        node on the right horizontally.
        '''
        selected = self._scene.selectedItems()
        if len(selected) > 2:
            # sort it based on x position + width
            selected = sorted(selected,
                              key=lambda x: x.x() + x.boundingRect().width())
            startItem = selected.pop(0)
            endItem = selected.pop(-1)

            # total length of items
            itemsLength = int()
            for each in selected:
                itemsLength += each.boundingRect().width()

            startPoint = startItem.x() + startItem.boundingRect().width()
            total = endItem.x() - startPoint
            section_num = len(selected) + 1
            extraSpace = total - itemsLength
            # nicly divide
            if extraSpace > 0:
                gap = extraSpace / section_num
                nextPlace = startPoint
                for each in selected:
                    newLoc = nextPlace + gap
                    nextPlace += gap + each.boundingRect().width()
                    each.setX(newLoc)
            else:
                total = endItem.x() - startPoint
                gap = total / section_num
                nextPlace = startPoint
                for each in selected:
                    nextPlace += gap
                    each.setX(nextPlace)
        else:
            errorMes("PUPPETMASTER-INFO: Select more than 2 nodes.")

    def align_vertical_distribute(self):
        '''
        Disturbute the selected nodes evenly between first node on the top and last 
        node on the bottom vertically.
        '''
        selected = self._scene.selectedItems()
        if len(selected) > 2:
            # sort it based on y position + width
            selected = sorted(
                selected,
                key=lambda node: node.y() + node.boundingRect().height())
            startItem = selected.pop(0)
            endItem = selected.pop(-1)

            # total length of items
            itemsLength = int()
            for each in selected:
                itemsLength += each.boundingRect().height()

            startPoint = startItem.y() + startItem.boundingRect().height()
            total = endItem.y() - startPoint
            section_num = len(selected) + 1
            extraSpace = total - itemsLength
            # nicly divide
            if extraSpace > 0:
                gap = extraSpace / section_num
                nextPlace = startPoint
                for each in selected:
                    newLoc = nextPlace + gap
                    nextPlace += gap + each.boundingRect().height()
                    each.setY(newLoc)
            else:
                total = endItem.y() - startPoint
                gap = total / section_num
                nextPlace = startPoint
                for each in selected:
                    nextPlace += gap
                    each.setY(nextPlace)
        else:
            errorMes("PUPPETMASTER-INFO: Select more than 2 nodes.")

    def reset_view(self):
        '''
        Fit all the items to the view.
        '''
        items = self._scene.items()
        if items:
            rects = [
                item.mapToScene(item.boundingRect()).boundingRect()
                for item in items
            ]
            rect = self.min_bounding_rect(rects)
            self._scene.setSceneRect(rect)
            self.fitInView(rect, Qt.KeepAspectRatio)

    def frame_view(self):
        '''
        Fit selected items to the view.
        '''
        items = self._scene.selectedItems()
        if items:
            rects = [
                item.mapToScene(item.boundingRect()).boundingRect()
                for item in items
            ]
            rect = self.min_bounding_rect(rects)
            self.fitInView(rect, Qt.KeepAspectRatio)

    def fit_contents(self):
        '''
        Update the scene boundery.
        '''
        items = self._scene.items()
        if items:
            rects = [
                item.mapToScene(item.boundingRect()).boundingRect()
                for item in items
            ]
            rect = self.min_bounding_rect(rects)
            self._scene.setSceneRect(rect)

    def request_edit(self, value=bool):
        self.requestEditMode.emit(value)

    def min_bounding_rect(self, rectList=list()):
        '''
        Get the minimum boundry based on objects in the scene.

        Parameters
        ----------
        rectList: (list)
            List of QRectF (boundry of objects)

        Return
        ------
        out: (QRectF)
            Get the minimum boundry
        '''
        minX = rectList[0].left()
        minY = rectList[0].top()
        maxX = rectList[0].right()
        maxY = rectList[0].bottom()

        for k in range(1, len(rectList)):
            minX = min(minX, rectList[k].left())
            minY = min(minY, rectList[k].top())
            maxX = max(maxX, rectList[k].right())
            maxY = max(maxY, rectList[k].bottom())

        return QRectF(minX, minY, maxX - minX, maxY - minY)

    def increase_size(self):
        '''
        Increase the size of selected items by 1 unit.
        '''
        selected = self._scene.selectedItems()
        for each in selected:
            font = each.font()
            fontSize = font.pointSize()
            if fontSize < 99:
                fontSize += 1
                font.setPointSize(fontSize)
                each.setFont(font)

    def decrease_size(self):
        '''
        Decrease the size of selected items by 1 unit.
        '''
        selected = self._scene.selectedItems()
        for each in selected:
            font = each.font()
            fontSize = font.pointSize()
            if fontSize > 1:
                fontSize -= 1
                font.setPointSize(fontSize)
                each.setFont(font)

    def is_texture(self, path=str):
        '''
        Check if the texture path is valid.

        Return
        ------
        out: (bool)
            True if texture is valide, otherwise False.
        '''
        if path.lower().endswith(IMAGE_FORMATS):
            return True
        return False

    def _QMimeDataToFile(self, data=QMimeData):
        '''
        Get all the filepath from drag file.

        Parameters
        ----------
        data: (QMimeData)
            QMimeData of dragged file.
        '''
        files = list()
        if data.hasUrls:
            for each in data.urls():
                files.append(each.toLocalFile())
        return files

    def _is_dragValid(self, event):
        '''
        Check for draged file validation
        '''
        dragedItems = self._QMimeDataToFile(event.mimeData())
        if dragedItems:
            first_path = dragedItems[0]
            if self.is_texture(first_path) and self.editMode:
                return True
        return False

    def dragEnterEvent(self, event):
        event.accept() if self._is_dragValid(event) else event.ignore()

    def dragMoveEvent(self, event):
        event.accept() if self._is_dragValid(event) else event.ignore()

    def dropEvent(self, event):
        dragedItems = self._QMimeDataToFile(event.mimeData())
        if dragedItems:
            first_path = dragedItems[0]
            if self.is_texture(first_path):
                self.setBackgroundImage(path=first_path)
                event.accept()
        else:
            event.ignore()

    def mousePressEvent(self, event):
        self._lastPos = event.pos()
        self._lastScenePos = self.mapToScene(event.pos())
        if self._dragMulti:
            for each in self._dragMulti:
                each.setSelected(True)
            self._dragMulti = list()
        if event.button() == Qt.MiddleButton:
            self._isPanning = True
            self.setCursor(QPixmap(iconSVG('nav-pan-02')))
            self._dragPos = event.pos()
            event.accept()
        elif event.button() == Qt.RightButton:
            if event.modifiers() == Qt.AltModifier:
                self._isZooming = True
                self.setCursor(QPixmap(iconSVG('nav-zoom-02')))
                self._dragPos = event.pos()
                self._dragPos2 = self.mapToScene(event.pos())
            else:
                self.actionMenu(event.pos())
            event.accept()
        else:
            super(CanvasGraphicsView, self).mousePressEvent(event)

    def mouseMoveEvent(self, event):
        if self._dragMulti and len(self._dragMulti) > 1:
            start = self._lastScenePos
            end = self.mapToScene(event.pos())

            total = len(self._dragMulti) - 1
            xLength = start.x() - end.x()
            yLength = start.y() - end.y()
            xStep = 0 if xLength == 0 else -(xLength / total)
            yStep = 0 if yLength == 0 else -(yLength / total)
            num = 0
            for each in self._dragMulti:
                position = QPointF(start.x() + (num * xStep),
                                   start.y() + (num * yStep))
                each.setPos(position)
                num += 1

        if self._isPanning:
            newPos = event.pos()
            diff = newPos - self._dragPos
            self._dragPos = newPos
            self.horizontalScrollBar().setValue(
                self.horizontalScrollBar().value() - diff.x())
            self.verticalScrollBar().setValue(
                self.verticalScrollBar().value() - diff.y())
            event.accept()
        elif self._isZooming:
            newPos = event.pos()
            diff = newPos - self._dragPos
            self._dragPos = newPos
            factor = 1.000
            if diff.x() < 0:
                factor = 0.98
            else:
                factor = 1.02

            self.scale(factor, factor)
            event.accept()
        else:
            if event.modifiers() == Qt.ShiftModifier:
                diff = event.pos() - self._lastPos
                x = event.x() if abs(diff.x()) > abs(
                    diff.y()) else self._lastPos.x()
                y = event.y() if abs(diff.y()) > abs(
                    diff.x()) else self._lastPos.y()
                event = QMouseEvent(QEvent.MouseMove, QPoint(x, y),
                                    self.mapToGlobal(QPoint(x,
                                                            y)), Qt.LeftButton,
                                    Qt.LeftButton, Qt.NoModifier)
            super(CanvasGraphicsView, self).mouseMoveEvent(event)

    def mouseReleaseEvent(self, event):
        self._isPanning = False
        self._isZooming = False
        self.setCursor(Qt.ArrowCursor)
        super(CanvasGraphicsView, self).mouseReleaseEvent(event)
        self.fit_contents()
        self.update_maya_selection()

    def keyPressEvent(self, event):
        if event.key() == Qt.Key_Backspace or event.key() == Qt.Key_Delete:
            if self.editMode:
                self.removeSelected()
        elif event.key() == Qt.Key_Plus:
            if self.editMode:
                self.increase_size()
        elif event.key() == Qt.Key_Minus:
            if self.editMode:
                self.decrease_size()
        elif event.key() == Qt.Key_H:
            self.reset_view()
        elif event.key() == Qt.Key_F:
            self.frame_view()
        else:
            super(CanvasGraphicsView, self).keyPressEvent(event)

    def removeSelected(self):
        '''
        Remove selected Items.
        '''
        for each in self._scene.selectedItems():
            self._scene.removeItem(each)
            self.remove_stack(each)

    def wheelEvent(self, event):
        factor = 1.05
        if event.delta() < 0:
            # factor = .2 / factor
            factor = 0.95
        self.scale(factor, factor)
        self.update()

    def add_node(self):
        '''
        Add a new PickNode to the scene.
        '''
        # Cursor Position on Scene
        globPosition = self.mapFromGlobal(QCursor.pos())
        scenePosition = self.mapToScene(globPosition)

        self.create_node(text=self._defaultText,
                         size=self._defaultTextSize,
                         textColor=self._defaultTextColor,
                         bgColor=self._defaultColor,
                         position=scenePosition,
                         items=getActiveItems(),
                         shape=PickShape.SQUARE)

    def add_multiple_nodes(self):
        '''
        Add group of PickNode bellow each other to the scene.
        '''
        # Cursor Position on Scene
        globPosition = self.mapFromGlobal(QCursor.pos())
        scenePosition = self.mapToScene(globPosition)

        self._dragMulti = list()
        for each in getActiveItems():
            node = self.create_node(text=self._defaultText,
                                    size=self._defaultTextSize,
                                    textColor=self._defaultTextColor,
                                    bgColor=self._defaultColor,
                                    position=scenePosition,
                                    items=[each],
                                    shape=PickShape.SQUARE)
            self._dragMulti.append(node)
            # scenePosition = QPointF(scenePosition.x(), node.y() + node.boundingRect().height() + 5)

    def create_node(self,
                    position=list,
                    text=str,
                    size=int,
                    textColor=QColor,
                    bgColor=QColor,
                    items=list,
                    shape=PickShape.SQUARE):
        '''
        Create a new PickNode.

        Parameters
        ----------
        position: (list)
            List of x and y location.
        text: (str)
            Name of the text.
        size: (int)
            Size of the text.
        textColor: (QColor)
            Color of the text.
        bgColor: (QColor)
            Background Color of the node.
        items: (list)
            List of selected Maya object.

        Return
        ------
        out: (PickNode)
            Reference of created Node.
        '''
        textNode = PickNode()
        font = QFont("SansSerif", size)
        font.setStyleHint(QFont.Helvetica)
        textNode.setFont(font)
        textNode.setDefaultTextColor(textColor)
        textNode.setFlag(QGraphicsItem.ItemIsMovable, self.editMode)
        textNode.setFlag(QGraphicsItem.ItemIsSelectable)
        # textNode.setFlag(QGraphicsItem.ItemIsFocusable, self.editMode)
        textNode.Background = bgColor
        textNode.Items = items
        textNode.Shape = shape

        textNode.onSelected.connect(lambda: self.onSelection.emit(textNode))
        textNode.onAddToStack.connect(lambda: self.add_stack(textNode))
        textNode.onRemoveFromStack.connect(lambda: self.remove_stack(textNode))

        textNode.setPos(position)
        textNode.setPlainText(text)

        self._scene.addItem(textNode)
        return textNode

    def create_button(self,
                      position=list,
                      text=str,
                      size=int,
                      textColor=QColor,
                      bgColor=QColor,
                      cmd=str,
                      cmdType=str):
        '''
        Create a new ButtonNode.

        Parameters
        ----------
        position: (list)
            List of x and y location.
        text: (str)
            Name of the text.
        size: (int)
            Size of the text.
        textColor: (QColor)
            Color of the text.
        bgColor: (QColor)
            Background Color of the node.
        cmd: (str)
            Command to run when it's pressed.
        cmdType: (str)
            Type of command.("python"/"mel")
        '''
        btnNode = ButtonNode()
        font = QFont("SansSerif", size)
        font.setStyleHint(QFont.Helvetica)
        btnNode.setFont(font)
        btnNode.setDefaultTextColor(textColor)
        btnNode.setFlag(QGraphicsItem.ItemIsMovable, self.editMode)
        btnNode.setFlag(QGraphicsItem.ItemIsSelectable)
        btnNode.Background = bgColor
        btnNode.CommandsType = cmdType
        btnNode.Command = cmd

        # btnNode.onSelected.connect(lambda: self.onSelection.emit(textNode))
        btnNode.onSelected.connect(lambda: self.onSelection.emit(btnNode))
        btnNode.onClicked.connect(self.scriptJob)

        btnNode.setPos(position)
        btnNode.setPlainText(text)

        self._scene.addItem(btnNode)

    def scriptJob(self, cmdType=str, cmd=str):
        '''
        Run a command.

        Parameters
        ----------
        cmd: (str)
            Command to run.
        cmdType: (str)
            Type of command.("python"/"mel")
        '''
        if not self.editMode:
            if cmdType == CommandType.PYTHON:
                runPython(cmd)
            elif cmdType == CommandType.MEL:
                runMel(cmd)

    def add_stack(self, node=PickNode):
        '''
        Add a node selection in right order into the stack.

        Parameters
        ----------
        node: (PickNode)
            Selected node.
        '''
        self._orderSelected.append(node)

    def remove_stack(self, node=PickNode):
        '''
        Remove a node from the stack.

        Parameters
        ----------
        node: (PickNode)
            Selected node.
        '''
        if node in self._orderSelected:
            index = self._orderSelected.index(node)
            self._orderSelected.pop(index)

    def get_edit(self):
        return self.editMode

    def set_edit(self, value=bool):
        self.editMode = value
        for each in self._scene.items():
            if type(each) == PickNode:
                each.setFlag(QGraphicsItem.ItemIsMovable, self.editMode)
            elif type(each) == ButtonNode:
                each.setFlag(QGraphicsItem.ItemIsMovable, self.editMode)

    Edit = property(get_edit, set_edit)

    def get_path(self):
        return self.piiPath

    def set_path(self, path=str):
        self.piiPath = path

    Path = property(get_path, set_path)

    def get_raw(self):
        '''
        Get the scene information. (can be be save in .pii)

        Return
        ------
        out: (dict)
            Dictionary of scene date to be save in .pii file.
        '''
        image_data = str()
        pixmap = self._backgroundNode.pixmap()
        # Extract Image Data
        if not pixmap.isNull():
            buffer = QBuffer()
            buffer.open(QIODevice.WriteOnly)
            pixmap.save(buffer, "PNG")
            # Image Data
            image_data = bytes(buffer.data().toBase64()).decode('ascii')

        nodeList = []
        for each in self._scene.items():
            if type(each) == PickNode:
                textColor = each.defaultTextColor()
                bgColor = each.Background
                item = {
                    PIIPick.TYPE:
                    PIINode.PICK,
                    PIIPick.TEXT:
                    each.toPlainText(),
                    PIIPick.SIZE:
                    each.font().pointSize(),
                    PIIPick.POSITION: (each.pos().x(), each.pos().y()),
                    PIIPick.COLOR:
                    (textColor.red(), textColor.green(), textColor.blue()),
                    PIIPick.BACKGROUND:
                    (bgColor.red(), bgColor.green(), bgColor.blue()),
                    PIIPick.SELECTION:
                    each.Items,
                    PIIPick.SHAPE:
                    each.Shape
                }
                nodeList.append(item)
            elif type(each) == ButtonNode:
                textColor = each.defaultTextColor()
                bgColor = each.Background
                item = {
                    PIIButton.TYPE:
                    PIINode.BUTTON,
                    PIIButton.TEXT:
                    each.toPlainText(),
                    PIIButton.SIZE:
                    each.font().pointSize(),
                    PIIButton.POSITION: (each.pos().x(), each.pos().y()),
                    PIIButton.COLOR:
                    (textColor.red(), textColor.green(), textColor.blue()),
                    PIIButton.BACKGROUND:
                    (bgColor.red(), bgColor.green(), bgColor.blue()),
                    PIIButton.COMMAND:
                    each.Command,
                    PIIButton.COMMANDTYPE:
                    each.CommandsType
                }
                nodeList.append(item)

        rawData = {
            PII.VERSION: "1.0.0",
            PII.BACKGROUND: image_data,
            PII.NODES: nodeList
        }
        return rawData

    def set_raw(self, data=dict):
        '''
        set the scene information. (information from .pii)

        Parameters
        ----------
        data: (dict)
            Dictionary of date from .pii file.
        '''
        if data:
            if data[PII.VERSION] == "1.0.0":
                self.load_1_0_0(data)

    Raw = property(get_raw, set_raw)

    def get_namespace(self):
        '''
        Get namespace of all PickNode.

        Return
        ------
        out: (list)
            List of namespaces.
        '''
        namespaceList = []
        for each in self._scene.items():
            if type(each) == PickNode:
                valueList = each.Items
                for sObj in valueList:
                    if ":" in sObj:
                        group = sObj.split(":")[:-1]
                        for index in range(len(group)):
                            namespaceList.append(":".join(group[:index + 1]))
        return list(set(namespaceList))

    def set_namespace(self, data=dict):
        '''
        Set namespace of all PickNode.

        Parameters
        ----------
        data: (dict)
            Dictionary of namespace with value of new namespace.
        '''
        for each in self._scene.items():
            if type(each) == PickNode:
                valueList = each.Items
                newValue = list()
                for sObj in valueList:
                    if ":" in sObj:
                        # namesapce
                        nameS = ":".join(sObj.split(":")[:-1])
                        # object name
                        object_name = sObj.split(":")[-1]
                        keys = data.keys()
                        keys.sort(reverse=True)
                        for key in keys:
                            if key in nameS:
                                nameS = nameS.replace(key, data[key], 1)
                        # making sure doesn't start with ':'
                        nameS = nameS[1:] if nameS.startswith(":") else nameS
                        # add the object to namespace
                        nameS = ":".join([nameS, object_name
                                          ]) if nameS else object_name
                        newValue.append(nameS)
                    else:
                        newValue.append(sObj)
                each.Items = newValue

    Namespace = property(get_namespace, set_namespace)

    def get_NSHistory(self):
        return self._namespace

    def set_NSHistory(self, name=str):
        self._namespace = name

    NamespaceHistory = property(get_NSHistory, set_NSHistory)

    def get_highlight(self):
        return

    def set_highlight(self, data=list):
        if data:
            for each in self._scene.items():
                # QApplication.processEvents()
                if type(each) == PickNode:
                    for item in data:
                        if item in each.Items:
                            each.Highlight = True
                            break
                        else:
                            each.Highlight = False
        else:
            for each in self._scene.items():
                if type(each) == PickNode:
                    each.Highlight = False

    Highlight = property(get_highlight, set_highlight)

    def clear_scene(self):
        '''
        Clear the scene.
        '''
        self._orderSelected = list()
        self._scene.clear()
        self._backgroundNode = QGraphicsPixmapItem()
        self._scene.addItem(self._backgroundNode)
        self.reset_view()

    def is_changed(self):
        '''
        Check for the scene changes.
        '''
        if self._backgroundNode.pixmap():
            return True
        elif len(self._scene.items()) > 1:
            return True
        return False

    def load_1_0_0(self, data=dict):
        '''
        Load v1.0.0 of .pii version file.

        Parameters
        ----------
        data: (dict)
            Dictionary of date from .pii file.
        '''
        if data[PII.BACKGROUND]:
            # Import Image Data
            newPix = QPixmap()
            newPix.loadFromData(
                QByteArray.fromBase64(data[PII.BACKGROUND].encode('ascii')),
                "PNG")
            self._backgroundNode.setPixmap(newPix)

        for each in data[PII.NODES]:
            if each["type"] == PIINode.PICK:
                self.create_node(text=each[PIIPick.TEXT],
                                 size=each[PIIPick.SIZE],
                                 textColor=QColor(*each[PIIPick.COLOR]),
                                 bgColor=QColor(*each[PIIPick.BACKGROUND]),
                                 position=QPointF(*each[PIIPick.POSITION]),
                                 items=each[PIIPick.SELECTION],
                                 shape=each[PIIPick.SHAPE])
            elif each["type"] == PIINode.BUTTON:
                self.create_button(position=QPointF(*each[PIIButton.POSITION]),
                                   text=each[PIIButton.TEXT],
                                   size=each[PIIButton.SIZE],
                                   textColor=QColor(*each[PIIButton.COLOR]),
                                   bgColor=QColor(*each[PIIButton.BACKGROUND]),
                                   cmd=each[PIIButton.COMMAND],
                                   cmdType=each[PIIButton.COMMANDTYPE])

    def set_nodes_bg_color(self, color=QColor):
        '''
        Set background color of selected nodes.

        Parameters
        ----------
        color: (QColor)
            QColor value.
        '''
        self._defaultColor = color
        for each in self._scene.selectedItems():
            each.Background = color
        self.update()

    def set_nodes_font_color(self, color=QColor):
        '''
        Set font color of selected nodes.

        Parameters
        ----------
        color: (QColor)
            QColor value.
        '''
        self._defaultTextColor = color
        for each in self._scene.selectedItems():
            each.setDefaultTextColor(color)

    def set_nodes_font_size(self, size=int):
        '''
        Set font size of selected nodes.

        Parameters
        ----------
        size: (int)
            font size.
        '''
        self._defaultTextSize = size
        for each in self._scene.selectedItems():
            font = each.font()
            font.setPointSize(size)
            each.setFont(font)

    def set_nodes_text(self, text=str):
        '''
        Set text for selected nodes.

        Parameters
        ----------
        text: (str)
            text for the node.
        '''
        self._defaultText = text
        for each in self._scene.selectedItems():
            each.setPlainText(text)

    def set_nodes_shape(self, shape=str):
        '''
        Set shape for selected nodes.

        Parameters
        ----------
        shape: (str)
            name for the shape.
        '''
        for each in self._scene.selectedItems():
            if isinstance(each, PickNode):
                each.Shape = shape
示例#22
0
class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)

        self.paqueteria = Paqueteria()

        self.ui.pushButton.clicked.connect(self.click)
        self.ui.pushButton_2.clicked.connect(self.mostrar)
        self.ui.actionGuardar.triggered.connect(self.guardar)
        self.ui.actionAbrir.triggered.connect(self.abrir)

        self.scene = QGraphicsScene()
        ##COMENTERA ABAJAO
        self.scene.setSceneRect(0, 0, 500, 500)
        self.ui.graphicsView.setScene(self.scene)

        self.pen = QPen()
        self.pen.setColor(QColor(0, 0, 0))
        self.pen.setWidth(30)

        self.scene.addLine(0, 0, 499, 0, self.pen)
        self.scene.addLine(0, 499, 499, 499, self.pen)
        self.scene.addLine(0, 0, 0, 499, self.pen)
        self.scene.addLine(499, 0, 499, 499, self.pen)

        self.pen.setColor(QColor(100, 20, 200))
        self.scene.addLine(10, 10, 490, 490, self.pen)

        self.scene.addEllipse(10, 10, 5, 5, self.pen,
                              QBrush(QColor(50, 100, 0)))

        self.scene.addEllipse(490, 490, 5, 5, self.pen,
                              QBrush(QColor(50, 100, 0)))

        self.ui.pushButton_3.clicked.connect(self.ordenar_origen)

        self.ui.pushButton_4.clicked.connect(self.ordenar_distancia)

    @Slot()
    def ordenar_origen(self):
        self.paqueteria.oredenar_origen()

    @Slot()
    def ordenar_distancia(self):
        self.paqueteria.ordenar_distancia()

    @Slot()
    def abrir(self):
        file = QFileDialog.getOpenFileName(self, 'Abrir archivo', '.',
                                           'JSON(*.json)')
        self.paqueteria.recuperar(file[0])

    @Slot()
    def mostrar(self):
        #self.paqueteria.mostrar()
        for paquete in self.paqueteria.lista:
            self.ui.plainTextEdit.insertPlainText(str(paquete))

    @Slot()
    def guardar(self):
        file = QFileDialog.getSaveFileName(self, 'Guardar Archivo...', '.',
                                           'JSON (*.json)')
        print(file)
        self.paqueteria.guardar(file[0])

    @Slot()
    def click(self):
        id = self.ui.lineEdit.text()
        origen = self.ui.lineEdit_2.text()
        destino = self.ui.lineEdit_3.text()
        distancia = self.ui.lineEdit_4.text()
        peso = self.ui.lineEdit_5.text()
        print(id, origen, destino, distancia, peso)

        paquete = Paquete()
        paquete.id = id
        paquete.origen = origen
        paquete.destino = destino
        paquete.distancia = distancia
        paquete.peso = peso

        self.paqueteria.agregar(paquete)

        msg = QMessageBox.information(
            self, 'Exito', 'Se agrego paquete con exito'
        )  #Ventana de mensaje de la libreria QMessageBox

        self.ui.lineEdit.clear()  #Limpiar campos
        self.ui.lineEdit_2.clear()
        self.ui.lineEdit_3.clear()
        self.ui.lineEdit_4.clear()
        self.ui.lineEdit_5.clear()
示例#23
0
class DynamicView(QGraphicsView):
    viewChanged = Signal(QRect, float, int, int)

    def __init__(self, image, parent=None):
        super(DynamicView, self).__init__(parent)
        self.scene = QGraphicsScene()
        self.scene.setBackgroundBrush(Qt.darkGray)
        self.setScene(self.scene)
        self.set_image(image)
        self.setRenderHint(QPainter.SmoothPixmapTransform)
        self.setDragMode(QGraphicsView.ScrollHandDrag)
        self.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded)
        self.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
        self.ZOOM_STEP = 0.2
        self.mouse_pressed = False
        self.next_fit = False
        self.fit_scale = 0
        self.zoom_fit()

    def set_image(self, image):
        if type(image) is QPixmap:
            pixmap = image
        elif type(image) is QImage:
            pixmap = QPixmap.fromImage(image)
        elif type(image) is np.ndarray:
            pixmap = QPixmap.fromImage(mat2img(image))
        else:
            raise TypeError(
                self.tr('DynamicView.set_image: Unsupported type: {}'.format(
                    type(image))))
        if not self.scene.items():
            self.scene.addPixmap(pixmap)
        else:
            self.scene.items()[0].setPixmap(pixmap)
        self.scene.setSceneRect(QRectF(pixmap.rect()))

    def zoom_full(self):
        self.set_scaling(1)
        self.next_fit = True
        self.notify_change()

    def zoom_fit(self):
        self.fitInView(self.scene.sceneRect(), Qt.KeepAspectRatio)
        self.fit_scale = self.matrix().m11()
        if self.fit_scale > 1:
            self.fit_scale = 1
            self.zoom_full()
        else:
            self.next_fit = False
            self.notify_change()

    def mousePressEvent(self, event):
        if event.button() == Qt.LeftButton:
            self.mouse_pressed = True
        QGraphicsView.mousePressEvent(self, event)

    def mouseMoveEvent(self, event):
        QGraphicsView.mouseMoveEvent(self, event)
        if self.mouse_pressed:
            self.notify_change()

    def mouseReleaseEvent(self, event):
        if event.button() == Qt.LeftButton:
            self.mouse_pressed = False
        QGraphicsView.mouseReleaseEvent(self, event)

    def mouseDoubleClickEvent(self, event):
        if event.button() == Qt.LeftButton:
            if self.next_fit:
                self.zoom_fit()
            else:
                self.zoom_full()
        QGraphicsView.mouseDoubleClickEvent(self, event)

    def wheelEvent(self, event):
        if event.delta() > 0:
            self.change_zoom(+1)
        else:
            self.change_zoom(-1)

    def resizeEvent(self, event):
        # FIXME: Se la finestra viene massimizzata, il valore di fit_scale non si aggiorna
        if self.matrix().m11() <= self.fit_scale:
            self.zoom_fit()
        else:
            self.notify_change()
        QGraphicsView.resizeEvent(self, event)

    def change_zoom(self, direction):
        level = math.log2(self.matrix().m11())
        if direction > 0:
            level += self.ZOOM_STEP
        else:
            level -= self.ZOOM_STEP
        scaling = 2**level
        if scaling < self.fit_scale:
            scaling = self.fit_scale
            self.next_fit = False
        elif scaling > 1:
            # scaling = 1
            if scaling > 4:
                scaling = 4
            self.next_fit = True
        self.set_scaling(scaling)
        self.notify_change()

    def set_scaling(self, scaling):
        matrix = QMatrix()
        matrix.scale(scaling, scaling)
        self.setMatrix(matrix)

    def change_view(self, _, new_scaling, new_horiz, new_vert):
        old_factor = self.matrix().m11()
        old_horiz = self.horizontalScrollBar().value()
        old_vert = self.verticalScrollBar().value()
        if new_scaling != old_factor or new_horiz != old_horiz or new_vert != old_vert:
            self.set_scaling(new_scaling)
            self.horizontalScrollBar().setValue(new_horiz)
            self.verticalScrollBar().setValue(new_vert)
            self.notify_change()

    def notify_change(self):
        scene_rect = self.get_rect()
        horiz_scroll = self.horizontalScrollBar().value()
        vert_scroll = self.verticalScrollBar().value()
        zoom_factor = self.matrix().m11()
        self.viewChanged.emit(scene_rect, zoom_factor, horiz_scroll,
                              vert_scroll)

    def get_rect(self):
        top_left = self.mapToScene(0, 0).toPoint()
        if top_left.x() < 0:
            top_left.setX(0)
        if top_left.y() < 0:
            top_left.setY(0)
        view_size = self.viewport().size()
        bottom_right = self.mapToScene(view_size.width(),
                                       view_size.height()).toPoint()
        image_size = self.sceneRect().toRect()
        if bottom_right.x() >= image_size.width():
            bottom_right.setX(image_size.width() - 1)
        if bottom_right.y() >= image_size.height():
            bottom_right.setY(image_size.height() - 1)
        return QRect(top_left, bottom_right)
示例#24
0
class QTraceViewer(QWidget):
    TAG_SPACING = 50
    LEGEND_X = -50
    LEGEND_Y = 0
    LEGEND_WIDTH = 10

    TRACE_FUNC_X = 0
    TRACE_FUNC_Y = 0
    TRACE_FUNC_WIDTH = 50
    TRACE_FUNC_MINHEIGHT = 1000

    MARK_X = LEGEND_X
    MARK_WIDTH = TRACE_FUNC_X - LEGEND_X + TRACE_FUNC_WIDTH
    MARK_HEIGHT = 1

    def __init__(self, workspace, disasm_view, parent=None):
        super().__init__(parent=parent)
        self.workspace = workspace
        self.disasm_view = disasm_view

        self.view = None
        self.scene = None
        self.mark = None
        self.curr_position = 0
        self._use_precise_position = False

        self._init_widgets()

        self.trace.am_subscribe(self._on_set_trace)
        self.selected_ins.am_subscribe(self._on_select_ins)
        self.view.installEventFilter(self)

    #
    # Forwarding properties
    #

    @property
    def trace(self):
        return self.workspace.instance.trace

    @property
    def selected_ins(self):
        return self.disasm_view.infodock.selected_insns

    def _init_widgets(self):
        self.view = QGraphicsView()
        self.scene = QGraphicsScene()
        self.view.setScene(self.scene)

        self._reset()

        layout = QHBoxLayout()
        layout.addWidget(self.view)
        layout.setContentsMargins(0, 0, 0, 0)
        layout.setAlignment(self.view, Qt.AlignLeft)

        self.setLayout(layout)

    def _reset(self):
        self.scene.clear()  #clear items
        self.mark = None

        self.legend = None
        self.legend_height = 0

        self.trace_func = QGraphicsItemGroup()
        self.scene.addItem(self.trace_func)
        self.hide()

    def _on_set_trace(self, **kwargs):
        self._reset()

        if self.trace.am_obj is not None:
            l.debug('minheight: %d, count: %d', self.TRACE_FUNC_MINHEIGHT,
                    self.trace.count)
            if self.trace.count <= 0:
                l.warning(
                    "No valid addresses found in trace to show. Check base address offsets?"
                )
                self.trace.am_obj = None
                self.trace.am_event()
                return
            if self.TRACE_FUNC_MINHEIGHT < self.trace.count * 15:
                self.trace_func_unit_height = 15
                show_func_tag = True
            else:
                self.trace_func_unit_height = self.TRACE_FUNC_MINHEIGHT / self.trace.count
                show_func_tag = True

            self.legend_height = int(self.trace.count *
                                     self.trace_func_unit_height)

            self._show_trace_func(show_func_tag)
            self._show_legend()
            self._set_mark_color()

            self.scene.setSceneRect(self.scene.itemsBoundingRect())  #resize
            self.setFixedWidth(self.scene.itemsBoundingRect().width())
            self.view.setFixedWidth(self.scene.itemsBoundingRect().width())

            self.show()

    def _on_select_ins(self, **kwargs):
        if self.trace == None:
            return

        if self.mark is not None:
            for i in self.mark.childItems():
                self.mark.removeFromGroup(i)
                self.scene.removeItem(i)
            self.scene.removeItem(self.mark)

        self.mark = QGraphicsItemGroup()
        self.scene.addItem(self.mark)

        if self.selected_ins:
            addr = next(iter(self.selected_ins))
            positions = self.trace.get_positions(addr)
            if positions:  #if addr is in list of positions
                if not self._use_precise_position:  #handle case where insn was selected from disas view
                    self.curr_position = positions[0] - self.trace.count
                for p in positions:
                    color = self._get_mark_color(p, self.trace.count)
                    y = self._get_mark_y(p, self.trace.count)

                    if p == self.trace.count + self.curr_position:  #add thicker line for 'current' mark
                        self.mark.addToGroup(
                            self.scene.addRect(self.MARK_X, y, self.MARK_WIDTH,
                                               self.MARK_HEIGHT * 4,
                                               QPen(QColor('black')),
                                               QBrush(color)))
                    else:
                        self.mark.addToGroup(
                            self.scene.addRect(self.MARK_X, y, self.MARK_WIDTH,
                                               self.MARK_HEIGHT, QPen(color),
                                               QBrush(color)))
                #y = self._get_mark_y(positions[0], self.trace.count)
                #self.view.verticalScrollBar().setValue(y - 0.5 * self.view.size().height())

                self.scene.update()  #force redraw of the scene
                self.scroll_to_position(self.curr_position)

    def scroll_to_position(self, position):
        relative_pos = self.trace.count + position
        y_offset = self._get_mark_y(relative_pos, self.trace.count)

        scrollValue = 0
        if y_offset > 0.5 * self.view.size().height():
            scrollValue = y_offset - 0.5 * self.view.size().height()
        scrollValue = min(scrollValue, self.view.verticalScrollBar().maximum())
        self.view.verticalScrollBar().setValue(scrollValue)
        self._use_precise_position = False

    def jump_next_insn(self):
        if self.curr_position + self.trace.count < self.trace.count - 1:  #for some reason indexing is done backwards
            self.curr_position += 1
            self._use_precise_position = True
            func_name = self.trace.trace_func[self.curr_position].func_name
            func = self._get_func_from_func_name(func_name)
            bbl_addr = self.trace.trace_func[self.curr_position].bbl_addr
            self._jump_bbl(func, bbl_addr)

    def jump_prev_insn(self):
        if self.curr_position + self.trace.count > 0:
            self.curr_position -= 1
            self._use_precise_position = True
            func_name = self.trace.trace_func[self.curr_position].func_name
            func = self._get_func_from_func_name(func_name)
            bbl_addr = self.trace.trace_func[self.curr_position].bbl_addr
            self._jump_bbl(func, bbl_addr)

    def eventFilter(self, object, event):  #specifically to catch arrow keys
        # more elegant solution to link w/ self.view's scroll bar keypressevent?
        if event.type() == QEvent.Type.KeyPress:
            if not (event.modifiers() & Qt.ShiftModifier):  #shift + arrowkeys
                return False
            key = event.key()
            if key == Qt.Key_Up or key == Qt.Key_Left:
                self.jump_prev_insn()
            elif key == Qt.Key_Down or key == Qt.Key_Right:
                self.jump_next_insn()
            return True

        return False  # pass through all other events

    def mousePressEvent(self, event):
        button = event.button()
        pos = self._to_logical_pos(event.pos())
        if button == Qt.LeftButton and self._at_legend(pos):
            func = self._get_func_from_y(pos.y())
            bbl_addr = self._get_bbl_from_y(pos.y())
            self._use_precise_position = True
            self.curr_position = self._get_position(pos.y())
            self._jump_bbl(func, bbl_addr)

    def _jump_bbl(self, func, bbl_addr):
        all_insn_addrs = self.workspace.instance.project.factory.block(
            bbl_addr).instruction_addrs
        # TODO: replace this with am_events perhaps?
        self.workspace.on_function_selected(func)
        self.selected_ins.clear()
        self.selected_ins.update(all_insn_addrs)
        self.selected_ins.am_event()
        # TODO: this ought to happen automatically as a result of the am_event
        self.disasm_view.current_graph.show_instruction(bbl_addr)

    def _get_mark_color(self, i, total):
        relative_gradient_pos = i * 1000 // total
        return self.legend_img.pixelColor(self.LEGEND_WIDTH // 2,
                                          relative_gradient_pos)

    def _get_mark_y(self, i, total):
        return self.TRACE_FUNC_Y + self.trace_func_unit_height * i

    def _show_trace_func(self, show_func_tag):
        x = self.TRACE_FUNC_X
        y = self.TRACE_FUNC_Y
        prev_name = None
        for position in self.trace.trace_func:
            bbl_addr = position.bbl_addr
            func_name = position.func_name
            l.debug('Draw function %x, %s', bbl_addr, func_name)
            color = self.trace.get_func_color(func_name)
            self.trace_func.addToGroup(
                self.scene.addRect(x, y, self.TRACE_FUNC_WIDTH,
                                   self.trace_func_unit_height, QPen(color),
                                   QBrush(color)))
            if show_func_tag is True and func_name != prev_name:
                tag = self.scene.addText(func_name,
                                         QFont("Source Code Pro", 7))
                tag.setPos(x + self.TRACE_FUNC_WIDTH + self.TAG_SPACING,
                           y - tag.boundingRect().height() // 2)
                self.trace_func.addToGroup(tag)
                anchor = self.scene.addLine(
                    self.TRACE_FUNC_X + self.TRACE_FUNC_WIDTH, y,
                    x + self.TRACE_FUNC_WIDTH + self.TAG_SPACING, y)
                self.trace_func.addToGroup(anchor)
                prev_name = func_name
            y += self.trace_func_unit_height

    def _make_legend_gradient(self, x1, y1, x2, y2):
        gradient = QLinearGradient(x1, y1, x2, y2)
        gradient.setColorAt(0.0, Qt.red)
        gradient.setColorAt(0.4, Qt.yellow)
        gradient.setColorAt(0.6, Qt.green)
        gradient.setColorAt(0.8, Qt.blue)
        gradient.setColorAt(1.0, Qt.darkBlue)
        return gradient

    def _show_legend(self):
        pen = QPen(Qt.transparent)

        gradient = self._make_legend_gradient(
            self.LEGEND_X, self.LEGEND_Y, self.LEGEND_X,
            self.LEGEND_Y + self.legend_height)
        brush = QBrush(gradient)
        self.legend = self.scene.addRect(self.LEGEND_X, self.LEGEND_Y,
                                         self.LEGEND_WIDTH, self.legend_height,
                                         pen, brush)

        reference_gradient = self._make_legend_gradient(
            0, 0, self.LEGEND_WIDTH, 1000)
        base_img = QImage(self.LEGEND_WIDTH, 1000, QImage.Format.Format_ARGB32)
        p = QPainter(base_img)
        p.fillRect(base_img.rect(), reference_gradient)
        self.legend_img = base_img  #reference shade

    def _set_mark_color(self):
        for p in range(self.trace.count):
            color = self._get_mark_color(p, self.trace.count)
            self.trace.set_mark_color(p, color)

    def _at_legend(self, pos):
        x = pos.x()
        y = pos.y()
        if self.TRACE_FUNC_X + self.LEGEND_X < x < self.view.width() and \
           self.TRACE_FUNC_Y < y < self.TRACE_FUNC_Y + self.legend_height:
            return True
        else:
            return False

    def _to_logical_pos(self, pos):
        x_offset = self.view.horizontalScrollBar().value()
        y_offset = self.view.verticalScrollBar().value()
        return QPoint(pos.x() + x_offset, pos.y() + y_offset)

    def _get_position(self, y):
        y_relative = y - self.legend_height

        return int(y_relative // self.trace_func_unit_height)

    def _get_bbl_from_y(self, y):
        position = self._get_position(y)
        return self.trace.get_bbl_from_position(position)

    def _get_func_from_func_name(self, func_name):
        return self.workspace.instance.kb.functions.function(name=func_name)

    def _get_func_from_y(self, y):
        position = self._get_position(y)
        func_name = self.trace.get_func_name_from_position(position)
        return self._get_func_from_func_name(func_name)
示例#25
0
    def __init__(self, main_window, parent_script, config=None):
        super(Flow, self).__init__()

        # SHORTCUTS
        place_new_node_shortcut = QShortcut(QKeySequence('Shift+P'), self)
        place_new_node_shortcut.activated.connect(
            self.place_new_node_by_shortcut)
        move_selected_nodes_left_shortcut = QShortcut(
            QKeySequence('Shift+Left'), self)
        move_selected_nodes_left_shortcut.activated.connect(
            self.move_selected_nodes_left)
        move_selected_nodes_up_shortcut = QShortcut(QKeySequence('Shift+Up'),
                                                    self)
        move_selected_nodes_up_shortcut.activated.connect(
            self.move_selected_nodes_up)
        move_selected_nodes_right_shortcut = QShortcut(
            QKeySequence('Shift+Right'), self)
        move_selected_nodes_right_shortcut.activated.connect(
            self.move_selected_nodes_right)
        move_selected_nodes_down_shortcut = QShortcut(
            QKeySequence('Shift+Down'), self)
        move_selected_nodes_down_shortcut.activated.connect(
            self.move_selected_nodes_down)
        select_all_shortcut = QShortcut(QKeySequence('Ctrl+A'), self)
        select_all_shortcut.activated.connect(self.select_all)
        copy_shortcut = QShortcut(QKeySequence.Copy, self)
        copy_shortcut.activated.connect(self.copy)
        cut_shortcut = QShortcut(QKeySequence.Cut, self)
        cut_shortcut.activated.connect(self.cut)
        paste_shortcut = QShortcut(QKeySequence.Paste, self)
        paste_shortcut.activated.connect(self.paste)

        # UNDO/REDO
        self.undo_stack = QUndoStack(self)
        self.undo_action = self.undo_stack.createUndoAction(self, 'undo')
        self.undo_action.setShortcuts(QKeySequence.Undo)
        self.redo_action = self.undo_stack.createRedoAction(self, 'redo')
        self.redo_action.setShortcuts(QKeySequence.Redo)

        undo_shortcut = QShortcut(QKeySequence.Undo, self)
        undo_shortcut.activated.connect(self.undo_activated)
        redo_shortcut = QShortcut(QKeySequence.Redo, self)
        redo_shortcut.activated.connect(self.redo_activated)

        # GENERAL ATTRIBUTES
        self.parent_script = parent_script
        self.all_node_instances: [NodeInstance] = []
        self.all_node_instance_classes = main_window.all_node_instance_classes  # ref
        self.all_nodes = main_window.all_nodes  # ref
        self.gate_selected: PortInstanceGate = None
        self.dragging_connection = False
        self.ignore_mouse_event = False  # for stylus - see tablet event
        self.last_mouse_move_pos: QPointF = None
        self.node_place_pos = QPointF()
        self.left_mouse_pressed_in_flow = False
        self.mouse_press_pos: QPointF = None
        self.tablet_press_pos: QPointF = None
        self.auto_connection_gate = None  # stores the gate that we may try to auto connect to a newly placed NI
        self.panning = False
        self.pan_last_x = None
        self.pan_last_y = None
        self.current_scale = 1
        self.total_scale_div = 1

        # SETTINGS
        self.algorithm_mode = Flow_AlgorithmMode()
        self.viewport_update_mode = Flow_ViewportUpdateMode()

        # CREATE UI
        scene = QGraphicsScene(self)
        scene.setItemIndexMethod(QGraphicsScene.NoIndex)
        scene.setSceneRect(0, 0, 10 * self.width(), 10 * self.height())

        self.setScene(scene)
        self.setCacheMode(QGraphicsView.CacheBackground)
        self.setViewportUpdateMode(QGraphicsView.BoundingRectViewportUpdate)
        self.setRenderHint(QPainter.Antialiasing)
        self.setTransformationAnchor(QGraphicsView.AnchorUnderMouse)
        self.setDragMode(QGraphicsView.RubberBandDrag)
        scene.selectionChanged.connect(self.selection_changed)
        self.setAcceptDrops(True)

        self.centerOn(
            QPointF(self.viewport().width() / 2,
                    self.viewport().height() / 2))

        # NODE CHOICE WIDGET
        self.node_choice_proxy = FlowProxyWidget(self)
        self.node_choice_proxy.setZValue(1000)
        self.node_choice_widget = NodeChoiceWidget(
            self, main_window.all_nodes)  # , main_window.node_images)
        self.node_choice_proxy.setWidget(self.node_choice_widget)
        self.scene().addItem(self.node_choice_proxy)
        self.hide_node_choice_widget()

        # ZOOM WIDGET
        self.zoom_proxy = FlowProxyWidget(self)
        self.zoom_proxy.setFlag(QGraphicsItem.ItemIgnoresTransformations, True)
        self.zoom_proxy.setZValue(1001)
        self.zoom_widget = FlowZoomWidget(self)
        self.zoom_proxy.setWidget(self.zoom_widget)
        self.scene().addItem(self.zoom_proxy)
        self.set_zoom_proxy_pos()

        # STYLUS
        self.stylus_mode = ''
        self.current_drawing = None
        self.drawing = False
        self.drawings = []
        self.stylus_modes_proxy = FlowProxyWidget(self)
        self.stylus_modes_proxy.setFlag(
            QGraphicsItem.ItemIgnoresTransformations, True)
        self.stylus_modes_proxy.setZValue(1001)
        self.stylus_modes_widget = FlowStylusModesWidget(self)
        self.stylus_modes_proxy.setWidget(self.stylus_modes_widget)
        self.scene().addItem(self.stylus_modes_proxy)
        self.set_stylus_proxy_pos()
        self.setAttribute(Qt.WA_TabletTracking)

        # DESIGN THEME
        Design.flow_theme_changed.connect(self.theme_changed)

        if config:
            config: dict

            # algorithm mode
            if config.keys().__contains__('algorithm mode'):
                if config['algorithm mode'] == 'data flow':
                    self.parent_script.widget.ui.algorithm_data_flow_radioButton.setChecked(
                        True)
                    self.algorithm_mode.mode_data_flow = True
                else:  # 'exec flow'
                    self.parent_script.widget.ui.algorithm_exec_flow_radioButton.setChecked(
                        True)
                    self.algorithm_mode.mode_data_flow = False

            # viewport update mode
            if config.keys().__contains__('viewport update mode'):
                if config['viewport update mode'] == 'sync':
                    self.parent_script.widget.ui.viewport_update_mode_sync_radioButton.setChecked(
                        True)
                    self.viewport_update_mode.sync = True
                else:  # 'async'
                    self.parent_script.widget.ui.viewport_update_mode_async_radioButton.setChecked(
                        True)
                    self.viewport_update_mode.sync = False

            node_instances = self.place_nodes_from_config(config['nodes'])
            self.connect_nodes_from_config(node_instances,
                                           config['connections'])
            if list(config.keys()).__contains__(
                    'drawings'
            ):  # not all (old) project files have drawings arr
                self.place_drawings_from_config(config['drawings'])
            self.undo_stack.clear()
class HumanVisualizationWidget(QGraphicsView):
    def __init__(self, parent=None):
        super(HumanVisualizationWidget, self).__init__(parent)
        self._scene = QGraphicsScene(self)
        self.setScene(self._scene)
        # circle = QGraphicsEllipseItem( 10, 10, 10 ,10)
        # self._scene.addItem(circle)
        self.setTransformationAnchor(QGraphicsView.AnchorUnderMouse)
        self.setResizeAnchor(QGraphicsView.AnchorUnderMouse)
        self._boxes = []
        self._humans = {}

    def load_inner_model(self, file):
        import xml.etree.cElementTree as ET
        tree = ET.ElementTree(file=file)
        root = tree.getroot()
        transforms = tree.findall(".//transform[plane]")
        walls = {}
        for trans in transforms:
            if 'id' in trans.attrib and 'pared' in trans.attrib['id']:
                print("Pared:", trans.attrib['id'])
                current_wall = [0] * 7
                # "wall5": [x, y, width, height, posx, posy, 0]
                if 'tx' in trans.attrib:
                    # print trans.attrib['tx']
                    current_wall[4] = int(float(trans.attrib['tx']))
                if 'ty' in trans.attrib:
                    # print trans.attrib['ty']
                    current_wall[5] = int(float(trans.attrib['tz']))
                # current_wall =
                planes = trans.findall('plane')
                for plane in planes:
                    if 'id' in plane.attrib and 'muro' in plane.attrib['id']:
                        # if 'nx' in plane.attrib:
                        # 	print plane.attrib['nx']
                        # if 'nz' in plane.attrib:
                        # 	print plane.attrib['nz']
                        if 'size' in plane.attrib:
                            # print int(float(plane.attrib['size'].split(',')[0])
                            current_wall[2] = int(
                                float(plane.attrib['size'].split(',')[0])) / 2.
                            # print int(float(plane.attrib['size'].split(',')[1])
                            current_wall[3] = int(
                                float(plane.attrib['size'].split(',')[1])) / 2.
                            if current_wall[2] < current_wall[3]:
                                current_wall[2] = 200
                            else:
                                current_wall[3] = 200
                walls[trans.attrib['id']] = current_wall
        for id in sorted(walls.keys()):
            object = walls[id]
            # rect = QRectF(-float(object[2]) / 2, -float(object[3]) / 2, float(object[2]), float(object[3]))
            rect = QRectF(0, 0, float(object[2]), float(object[3]))

            border = QPen(QColor("black"))
            fill = QBrush(QColor("black"))
            box = self._scene.addRect(rect, border, fill)

            self._scene.addEllipse(
                QRectF(float(object[4]), float(object[5]), 10, 10),
                QPen(QColor("green")), QBrush(QColor("green")))
            box.setPos(float(object[4]), float(object[5]))
            box.setRotation(float(object[6]))
            self._boxes.append(box)
            self._scene.update()
            QApplication.processEvents()
            sleep(1)

    def load_custom_json_world(self, file):

        if not os.path.isfile(file):
            print("Error reading world file, check config params:", file)
            return False

        with open(file, "r") as read_file:
            json_data = json.load(read_file)

        types_colors = {
            "tables": "SandyBrown",
            "roundTables": "Khaki",
            "walls": "Brown",
            "points": "Blue"
        }
        self.clear()
        for type, color in types_colors.items():
            if type in json_data:
                tables = json_data[type]
                for object in tables.values():
                    rect = QRectF(-float(object[2]) / 2, -float(object[3]) / 2,
                                  float(object[2]), float(object[3]))
                    border = QPen(QColor(color))
                    fill = QBrush(QColor(color))
                    if type == "roundTables":
                        box = self._scene.addEllipse(rect, border, fill)
                    else:
                        box = self._scene.addRect(rect, border, fill)

                    box.setPos(float(object[4]), float(object[5]))
                    box.setRotation(float(object[6]))
                    self._boxes.append(box)

    def load_json_world(self, file):

        if not os.path.isfile(file):
            print("Error reading world file, check config params:", file)
            return False

        with open(file, "r") as read_file:
            json_data = json.load(read_file)

            polygon_points = []
        paths_count = 0
        for item in json_data:
            if 'json_geometry' in item:
                geometry = item['json_geometry']
                if geometry['type'] == 'Polygon':
                    for coord in geometry['coordinates'][0]:

                        if isinstance(coord, list) and (
                            (isinstance(coord, list) and len(coord) == 2) or
                            (len(coord) == 3 and coord[3] == 0)):
                            current_point = QPointF(coord[0], coord[1])
                            polygon_points.append(current_point)
                        else:
                            print("Unknown coord", geometry["coordinates"][0])
                    polygon = QPolygonF(polygon_points)
                    path = QPainterPath()
                    path.addPolygon(polygon)
                    contour = QGraphicsPathItem(path)
                    # r = lambda: random.randint(0, 255)
                    # next_color = '#%02X%02X%02X' % (r(), r(), r())
                    contour.setPen(QPen(QColor("red"), 0.1))

                    contour.setBrush(QBrush(Qt.transparent))
                    # if paths_count == 4:
                    print(item['json_featuretype'])
                    self._scene.addItem(contour)
                    paths_count += 1
        self.update()

    def clear(self):
        for human in self._humans.values():
            self._scene.removeItem(human)
        self._humans = {}
        # self._scene.setSceneRect(QRectF(0,0,400,400))

    def resizeEvent(self, event):
        # skip initial entry
        self.own_resize()
        super(HumanVisualizationWidget, self).resizeEvent(event)

    def own_resize(self):
        self.fitInView(self._scene.itemsBoundingRect(), Qt.KeepAspectRatio)
        self._scene.setSceneRect(self._scene.itemsBoundingRect())

    def add_human_by_pos(self, id, pos):
        x, y = pos
        human = QGraphicsEllipseItem(0, 0, 200, 200)
        self._scene.addItem(human)
        human.setBrush(QBrush(Qt.black, style=Qt.SolidPattern))
        human_text = QGraphicsTextItem(str(pos))
        font = QFont("Helvetica [Cronyx]", 40, QFont.Bold)
        human_text.setFont(font)
        human_text.setParentItem(human)
        human.setPos(pos[0], pos[1])
        self._humans[id] = human
        human.setZValue(30)

    def move_human(self, id, pos):
        x, y = pos
        human = self._humans[id]
        human.setPos(x, y)

    def set_human_color(self, id, color):
        if id in self._humans:
            self._humans[id].setBrush(color)
示例#27
0
class TestGUI(QMainWindow):
    def __init__(self):
        self.app = QApplication(sys.argv)
        ui_file = QFile("testgui.ui")
        ui_file.open(QFile.ReadOnly)

        loader = QUiLoader()
        self.window = loader.load(ui_file)
        ui_file.close()
        self.scene_gt = QGraphicsScene()
        self.scene_gt.setSceneRect(-2000, -3000, 4000, 6000)

        self.view_gt = QGraphicsView(self.scene_gt, self.window.scene_gt)
        self.view_gt.scale(-0.1, 0.1)

        self.view_gt.resize(self.window.scene_gt.geometry().width(),
                            self.window.scene_gt.geometry().height())

        self.personPos_gt = self.scene_gt.addEllipse(
            QRectF(-200, -200, 400, 400), QPen(QColor("LightGreen")),
            QBrush(QColor("LightGreen")))
        self.personPos_gt.setFlag(QGraphicsItem.ItemIsMovable)
        self.personPos_gt.setPos(0, 0)
        self.personAng_gt = self.scene_gt.addRect(QRectF(-10, 0, 20, 300),
                                                  QPen(QColor("Green")),
                                                  QBrush(QColor("Green")))
        self.personAng_gt.setFlag(QGraphicsItem.ItemIsMovable)
        self.personAng_gt.setPos(0, 0)

        self.scene_cc = QGraphicsScene()
        self.scene_cc.setSceneRect(-2000, -3000, 4000, 6000)

        self.view_cc = QGraphicsView(self.scene_cc, self.window.scene_cc)
        self.view_cc.scale(-0.1, 0.1)

        self.view_cc.resize(self.window.scene_cc.geometry().width(),
                            self.window.scene_cc.geometry().height())

        self.personPos_cc = self.scene_cc.addEllipse(
            QRectF(-200, -200, 400, 400), QPen(QColor("Red")),
            QBrush(QColor("Red")))
        self.personPos_cc.setFlag(QGraphicsItem.ItemIsMovable)
        self.personPos_cc.setPos(0, 0)
        self.personAng_cc = self.scene_cc.addRect(QRectF(-10, 0, 20, 300),
                                                  QPen(QColor("Black")),
                                                  QBrush(QColor("Black")))
        self.personAng_cc.setFlag(QGraphicsItem.ItemIsMovable)
        self.personAng_cc.setPos(0, 0)

        self.scene_nn = QGraphicsScene()
        self.scene_nn.setSceneRect(-2000, -3000, 4000, 6000)

        self.view_nn = QGraphicsView(self.scene_nn, self.window.scene_nn)
        self.view_nn.scale(-0.1, 0.1)

        self.view_nn.resize(self.window.scene_nn.geometry().width(),
                            self.window.scene_nn.geometry().height())

        self.personPos_nn = self.scene_nn.addEllipse(
            QRectF(-200, -200, 400, 400), QPen(QColor("LightBlue")),
            QBrush(QColor("LightBlue")))
        self.personPos_nn.setFlag(QGraphicsItem.ItemIsMovable)
        self.personPos_nn.setPos(0, 0)
        self.personAng_nn = self.scene_nn.addRect(QRectF(-10, 0, 20, 300),
                                                  QPen(QColor("Blue")),
                                                  QBrush(QColor("Blue")))
        self.personAng_nn.setFlag(QGraphicsItem.ItemIsMovable)
        self.personAng_nn.setPos(0, 0)

        self.loadData(sys.argv[1])

        self.window.instantScrollBar.valueChanged.connect(self.changeInstant)

        self.it = 0
        self.timer = QTimer()
        self.timer.timeout.connect(self.compute)
        self.timer.start(150)

        self.window.show()

        r = self.app.exec_()
        sys.exit(r)

    def loadData(self, filename):
        test_dataset = graph_generator.CalibrationDataset(filename, 'run', '1')
        with open(sys.argv[1], 'r') as f:
            raw = f.read()
        raw = list(raw)

        raws = ''.join(raw)
        data = json.loads(raws)['data_set']

        model = trackerapi.TrackerAPI('.', test_dataset)

        self.x_gt = []
        self.x_cc = []
        self.x_nn = []
        self.z_gt = []
        self.z_cc = []
        self.z_nn = []
        self.a_gt = []
        self.a_cc = []
        self.a_nn = []

        try:
            with open('kk', 'rb') as f:
                results = pickle.load(f)
        except:
            results = [x for x in model.predict()]
            with open('kk', 'wb') as f:
                pickle.dump(results, f, pickle.HIGHEST_PROTOCOL)

        eX_cc = []
        eZ_cc = []
        eA_cc = []
        eX_nn = []
        eZ_nn = []
        eA_nn = []

        self.trajectory = []

        s = 0
        ang_prev = 0
        for i in range(int(len(results))):

            n_joints = 0
            for cam in range(len(data[i]['superbody'])):
                n_joints += len(data[i]['superbody'][cam]['joints'])

            if n_joints < 3:
                continue

            s += 1
            if s < 2 or s % 1 != 0:
                continue

            self.x_gt.append(data[i]['superbody'][0]['ground_truth'][0])
            self.z_gt.append(data[i]['superbody'][0]['ground_truth'][2])
            self.a_gt.append(data[i]['superbody'][0]['ground_truth'][3] *
                             180. / math.pi)

            self.trajectory.append(QPointF(self.x_gt[-1], self.z_gt[-1]))

            x_cc = 0
            z_cc = 0
            ncams = 0
            for cam in range(0, len(data[i]['superbody'])):
                x_cc += data[i]['superbody'][cam]['world'][0]
                z_cc += data[i]['superbody'][cam]['world'][2]
                ncams += 1

            self.x_cc.append(x_cc / ncams)
            self.z_cc.append(z_cc / ncams)

            s_cc = 0
            c_cc = 0
            ncams = 0
            for cam in range(0, len(data[i]['superbody'])):
                joints = data[i]['superbody'][cam]["joints"]
                if ("right_shoulder" in joints and "left_shoulder"
                        in joints) or ("right_hip" in joints
                                       and "left_hip" in joints):
                    s_cc = math.sin(data[i]['superbody'][cam]['world'][3])
                    c_cc = math.cos(data[i]['superbody'][cam]['world'][3])
                    ncams += 1

            if ncams > 0:
                a_cc = math.atan2(s_cc / ncams, c_cc / ncams)
                ang_prev = a_cc
            else:
                a_cc = ang_prev

            self.a_cc.append(a_cc * 180. / math.pi)

            self.x_nn.append(results[i][0] * 4000)
            self.z_nn.append(results[i][2] * 4000)
            self.a_nn.append(
                math.atan2(results[i][3] / 0.7, results[i][4] / 0.7) * 180. /
                math.pi)
            eX_cc.append(abs(self.x_gt[-1] - self.x_cc[-1]))
            eZ_cc.append(abs(self.z_gt[-1] - self.z_cc[-1]))
            eAng = 180 - abs(abs(self.a_gt[-1] - self.a_cc[-1]) - 180)
            if eAng < 0:
                eAng = 360 + eAng
            eA_cc.append(eAng)

            eX_nn.append(abs(self.x_gt[-1] - self.x_nn[-1].item()))
            eZ_nn.append(abs(self.z_gt[-1] - self.z_nn[-1].item()))
            eAng = 180 - abs(abs(self.a_gt[-1] - self.a_nn[-1]) - 180)
            if eAng < 0:
                eAng = 360 + eAng
            eA_nn.append(eAng)

        array_err_z = np.array(eZ_nn)
        print("len array error", len(array_err_z))

        #        self.window.eX_cc.display(np.array(eX_cc).mean())
        #        self.window.eZ_cc.display(np.array(eZ_cc).mean())
        #        self.window.eA_cc.display(np.array(eA_cc).mean())

        #        self.window.eX_nn.display(np.array(eX_nn).mean())
        #        self.window.eZ_nn.display(np.array(eZ_nn).mean())
        #        self.window.eA_nn.display(np.array(eA_nn).mean())

        self.scene_gt.addPolygon(self.trajectory, QPen(QColor("Black")))
        self.scene_cc.addPolygon(self.trajectory, QPen(QColor("Black")))
        self.scene_nn.addPolygon(self.trajectory, QPen(QColor("Black")))

        self.window.instantScrollBar.setMaximum(len(self.a_gt) - 1)

    def compute(self):
        if self.window.playButton.isChecked():
            if self.it >= len(self.x_gt):
                self.it = 0
            self.movePerson()
            self.it += 1
            self.window.instantScrollBar.setValue(self.it)

    def changeInstant(self, instant):
        self.it = instant
        self.movePerson()

    def movePerson(self):

        self.personPos_gt.setPos(self.x_gt[self.it], self.z_gt[self.it])
        self.personAng_gt.setPos(self.x_gt[self.it], self.z_gt[self.it])
        self.personAng_gt.setRotation(self.a_gt[self.it])

        self.personPos_cc.setPos(self.x_cc[self.it], self.z_cc[self.it])
        self.personAng_cc.setPos(self.x_cc[self.it], self.z_cc[self.it])
        self.personAng_cc.setRotation(self.a_cc[self.it])

        self.personPos_nn.setPos(self.x_nn[self.it], self.z_nn[self.it])
        self.personAng_nn.setPos(self.x_nn[self.it], self.z_nn[self.it])
        self.personAng_nn.setRotation(self.a_nn[self.it])
class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        self.listaparticulas = ListaParticulas()
        self.listadistances = ListaDistances()

        self.ui.pbGuardar.clicked.connect(self.click)
        self.ui.pbMostrar.clicked.connect(self.mostrar)
        self.ui.pbLimpiar.clicked.connect(self.clear)
        self.ui.actionGuardar.triggered.connect(self.guardarArchivo)
        self.ui.actionAbrir.triggered.connect(self.abrir)
        self.ui.pbVisualizar.clicked.connect(self.visualizar)
        self.ui.pbOrdenarDistancia.clicked.connect(self.ordenar_distancia)
        self.ui.pbOrdenarVelocidad.clicked.connect(self.ordenar_velocidad)
        self.ui.aVerPuntos.triggered.connect(self.ver_puntos)
        self.ui.aPuntosCercanos.triggered.connect(self.puntos_cercanos)
        self.ui.pbMostrarGrafo.clicked.connect(self.mostrarGrafo)
        self.ui.aRecorridoProfundidad.triggered.connect(self.recorridoProfundidad)
        self.ui.aRecorridoAnchura.triggered.connect(self.recorridoAnchura)
        self.ui.aPrim.triggered.connect(self.prim)
        self.ui.aKruskal.triggered.connect(self.kruskal)
        self.ui.aMostrar.triggered.connect(self.mostrarGrafoOriginal)

    @Slot()
    def mostrar(self):
        distance = Distance()
        #self.listaparticulas.mostrar()
        for particula in self.listaparticulas.lista:
            self.ui.plainTextEdit.insertPlainText(str(particula))
            v1 = float(int(particula.destinoX) - int(particula.origenX))
            v2 = float(int(particula.destinoY) - int(particula.origenY))
            distancia = float(math.sqrt((v1) ** 2 + (v2) ** 2))
            self.ui.plainTextEdit.insertPlainText(" -> Distancia: " + str(distancia) + '\n\n')


            distance.id = distancia
            distance.colorR = particula.colorR
            distance.colorG = particula.colorG
            distance.colorB = particula.colorB
            self.listadistances.agregar(distance)


    @Slot()
    def visualizar(self):
        self.scene = QGraphicsScene()
        self.scene.setSceneRect(0, 0, 500, 500)
        self.ui.graphicsView.setScene(self.scene)

        self.pen = QPen()
        self.pen.setColor(QColor(0, 0, 0))
        self.pen.setWidth(3)

        self.scene.addLine(0, 0, 499, 0, self.pen)
        self.scene.addLine(0, 499, 499, 499, self.pen)
        self.scene.addLine(0, 0, 0, 499, self.pen)
        self.scene.addLine(499, 0, 499, 499, self.pen)
        
        for particula in self.listaparticulas.lista:
            self.pen.setColor(QColor(particula.colorR, particula.colorG, particula.colorB))
            self.scene.addLine(particula.origenX, particula.origenY, particula.destinoX, particula.destinoY, self.pen)

            self.scene.addEllipse(particula.origenX, particula.origenY, 5, 5, self.pen, QBrush(QColor(50, 100, 0)))
            self.scene.addEllipse(particula.destinoX, particula.destinoY, 5, 5, self.pen, QBrush(QColor(100, 0, 0)))
    @Slot()
    def click(self):
        id = self.ui.leID.text()
        origenX = self.ui.leORIGENx.text()
        origenY = self.ui.leORIGENy.text()
        destinoX = self.ui.leDESTINOx.text()
        destinoY = self.ui.leDESTINOy.text()
        colorR = self.ui.leCOLORr.text()
        colorG = self.ui.leCOLORg.text()
        colorB = self.ui.leCOLORb.text()
        velocidad = self.ui.leVELOCIDAD.text()
        v1= float(int(destinoX)-int(origenX))
        v2 = float(int(destinoY)-int(origenY))
        distancia = float(math.sqrt((v1)**2 + (v2)**2))
        print(id,origenX,origenY,destinoX,destinoY,colorR,colorG,colorB,velocidad, distancia)

        particula = Particula()
        particula.id = int(id)
        particula.origenX = int(origenX)
        particula.origenY = int(origenY)
        particula.destinoX = int(destinoX)
        particula.destinoY = int(destinoY)
        particula.colorR = int(colorR)
        particula.colorG = int(colorG)
        particula.colorB = int(colorB)
        particula.velocidad = int(velocidad)
        self.ui.lcdDistancia.display(distancia)

        self.listaparticulas.agregar(particula)

        msg = QMessageBox.information(self,'Éxito', 'Se agregó paquete con éxito')
        #clear()

    @Slot()
    def clear(self):
        self.ui.leID.clear()
        self.ui.leORIGENx.clear()
        self.ui.leORIGENy.clear()
        self.ui.leDESTINOx.clear()
        self.ui.leDESTINOy.clear()
        self.ui.leCOLORr.clear()
        self.ui.leCOLORg.clear()
        self.ui.leCOLORb.clear()
        self.ui.leVELOCIDAD.clear()
    @Slot()
    def abrir(self):
        print('abrir')
        file = QFileDialog.getOpenFileName(self, 'Abrir archivo', '.', 'JSON (*.json)')
        self.listaparticulas.recuperar(file[0])

    @Slot()
    def ordenar_distancia(self):
        print('click')
        self.listaparticulas.ordenar_distancia()

        self.scene = QGraphicsScene()
        self.scene.setSceneRect(0, 0, 400, 1000)
        self.ui.graphicsView.setScene(self.scene)

        self.pen = QPen()
        self.pen.setColor(QColor(0,0,0))
        self.pen.setWidth(3)

        i = 1
        for particula in self.listaparticulas.lista:
            self.pen.setColor(QColor(particula.colorR, particula.colorG, particula.colorB))
            v1 = float(int(particula.destinoX) - int(particula.origenX))
            v2 = float(int(particula.destinoY) - int(particula.origenY))
            distancia = float(math.sqrt((v1) ** 2 + (v2) ** 2))
            self.scene.addLine(0, i, distancia, i, self.pen)
            i = i+1


    @Slot()
    def ordenar_velocidad(self):
        print('click')
        self.listaparticulas.ordenar_velocidad()

        self.scene = QGraphicsScene()
        self.scene.setSceneRect(0, 0, 400, 1000)
        self.ui.graphicsView.setScene(self.scene)

        self.pen = QPen()
        self.pen.setColor(QColor(0,0,0))
        self.pen.setWidth(3)

        i = 1
        for particula in self.listaparticulas.lista:
            self.pen.setColor(QColor(particula.colorR, particula.colorG, particula.colorB))
            self.scene.addLine(0, i, particula.velocidad, i, self.pen)
            i = i+1

    @Slot()
    def guardarArchivo(self):
        file = QFileDialog.getSaveFileName(self, 'Guardar archivo...', '.', 'JSON(*.json)')
        print(file)
        self.listaparticulas.guardar(file[0])

    @Slot()
    def ver_puntos(self):

        self.scene = QGraphicsScene()
        #self.scene.setSceneRect(0, 0, 400, 1000)
        self.ui.graphicsView.setScene(self.scene)

        self.pen = QPen()
        self.pen.setColor(QColor(0, 0, 0))
        self.pen.setWidth(3)

        listaPuntos = list()

        for particula in self.listaparticulas.lista:
            self.pen.setColor(QColor(particula.colorR, particula.colorG, particula.colorB))
            self.scene.addEllipse(particula.origenX, particula.origenY, 3, 3, self.pen, QBrush(QColor(particula.colorR,particula.colorG, particula.colorB)))
            self.scene.addEllipse(particula.destinoX, particula.destinoY, 3, 3, self.pen, QBrush(QColor(particula.colorR, particula.colorG, particula.colorB)))
            origen = (particula.origenX,particula.origenY)
            destino = (particula.destinoX, particula.destinoY)
            listaPuntos.append(origen)
            listaPuntos.append(destino)

        #print(listaPuntos)

    @Slot()
    def puntos_cercanos(self):

        self.scene = QGraphicsScene()
        self.ui.graphicsView.setScene(self.scene)

        self.pen = QPen()
        self.pen.setWidth(1)

        listaPuntos = list()
        listaColores = list()

        for particula in self.listaparticulas.lista:
            self.pen.setColor(QColor(particula.colorR, particula.colorG, particula.colorB))
            self.scene.addEllipse(particula.origenX, particula.origenY, 3, 3, self.pen, QBrush(QColor(particula.colorR, particula.colorG, particula.colorB)))
            self.scene.addEllipse(particula.destinoX, particula.destinoY, 3, 3, self.pen, QBrush(QColor(particula.colorR, particula.colorG, particula.colorB)))
            origen = (particula.origenX, particula.origenY)
            destino = (particula.destinoX, particula.destinoY)
            origenColores = (particula.colorR,particula.colorG, particula.colorB)
            destinoColores = (particula.colorR, particula.colorG, particula.colorB)
            listaPuntos.append(origen)
            listaPuntos.append(destino)
            listaColores.append(origenColores)
            listaColores.append(destinoColores)

        #print(listaColores)
        #print(listaPuntos)
        for i in range(0, len(listaPuntos)):
            auxI = listaPuntos[i]
            distancia = 1000000000000000

            for y in range(0, len(listaPuntos)):
                auxY = listaPuntos[y]

                if (auxI[0] != auxY[0] or auxI[1] != auxY[1]):
                    v1 = float(int(auxY[0]) - int(auxI[0]))
                    v2 = float(int(auxY[1]) - int(auxI[1]))
                    distanciaActual = float(math.sqrt((v1) ** 2 + (v2) ** 2))

                    #print('distancia: ', distanciaActual)

                    if (distanciaActual <= distancia):
                        distancia = distanciaActual
                        colores = listaColores[i-1]
                        auxR = colores[0]
                        auxG = colores[1]
                        auxB = colores[2]
                        x = auxY[0]
                        z = auxY[1]

                if (y == (len(listaPuntos)-1)):

                    self.pen.setColor(QColor(auxR, auxG, auxB))
                    #print('ACTUAL: ',auxI[0],auxI[1])
                    #print('MÁS CERCANO ', x, z)
                    self.pen.setWidth(1)
                    self.scene.addLine(auxI[0], auxI[1], x, z , self.pen)

    @Slot()
    def mostrarGrafo(self):
        grafo = dict()

        for particula in self.listaparticulas.lista:
            pOrigen = str(particula.origenX) + ('.') + str(particula.origenY)
            pDestino = str(particula.destinoX) + ('.') + str(particula.destinoY)

            v1 = float(int(particula.destinoX) - int(particula.origenX))
            v2 = float(int(particula.destinoY) - int(particula.origenY))
            distancia = float(math.sqrt((v1) ** 2 + (v2) ** 2))

            origen = pOrigen
            destino = pDestino
            peso = int(distancia)

            if origen in grafo:
                grafo[origen].append((destino, peso))
            else:
                grafo[origen] = [(destino, peso)]
            if destino in grafo:
                grafo[destino].append((origen, peso))
            else:
                grafo[destino] = [(origen, peso)]

        cadena = pprint.pformat(grafo, width=40)
        self.ui.plainTextEdit.insertPlainText(str(cadena))

    @Slot()
    def recorridoProfundidad(self):
        grafo = dict()

        for particula in self.listaparticulas.lista:
            pOrigen = str(particula.origenX) + ('.') + str(particula.origenY)
            pDestino = str(particula.destinoX) + ('.') + str(particula.destinoY)

            origen = pOrigen
            destino = pDestino

            if origen in grafo:
                grafo[origen].append(destino)
            else:
                grafo[origen] = [destino]
            if destino in grafo:
                grafo[destino].append(origen)
            else:
                grafo[destino] = [origen]

        visitados = []
        pila = []
        eleccion = self.ui.origenGrafo.text()
        pila.append(eleccion)

        if eleccion in grafo.keys():
            while pila:
                eleccion = pila.pop()
                if eleccion not in visitados:
                    visitados.append(eleccion)
                for vecino in grafo[eleccion]:
                    if vecino not in visitados:
                        pila.append(vecino)
            self.ui.plainTextEdit.insertPlainText(str(visitados))

    @Slot()
    def recorridoAnchura(self):
        grafo = dict()

        for particula in self.listaparticulas.lista:
            pOrigen = str(particula.origenX) + ('.') + str(particula.origenY)
            pDestino = str(particula.destinoX) + ('.') + str(particula.destinoY)

            origen = pOrigen
            destino = pDestino

            if origen in grafo:
                grafo[origen].append(destino)
            else:
                grafo[origen] = [destino]
            if destino in grafo:
                grafo[destino].append(origen)
            else:
                grafo[destino] = [origen]

        cadena = pprint.pformat(grafo, width=40)
        print(cadena)
        # self.ui.plainTextEdit.insertPlainText(str(cadena))

        visitados = []
        cola = []
        eleccion = self.ui.origenGrafo.text()
        #eleccion = "72.321"
        cola.insert(0, eleccion)
        visitados.append(eleccion)

        if eleccion in grafo.keys():
            while cola:
                eleccion = cola.pop()
                if eleccion not in visitados:
                    visitados.append(eleccion)
                for vecino in grafo[eleccion]:
                    if vecino not in visitados:
                        cola.insert(0, vecino)

            print("=========Resultados=========")
            print("Visitados:", visitados)
            print("Cola:", cola)
            self.ui.plainTextEdit.insertPlainText(str(visitados))
            # os.system("pause")
        else:
            print("No existe")


    @Slot()
    def prim(self):
        grafo = dict()

        for particula in self.listaparticulas.lista:
            pOrigen = str(particula.origenX) + ('.') + str(particula.origenY)
            pDestino = str(particula.destinoX) + ('.') + str(particula.destinoY)

            v1 = float(int(particula.destinoX) - int(particula.origenX))
            v2 = float(int(particula.destinoY) - int(particula.origenY))
            distancia = float(math.sqrt((v1) ** 2 + (v2) ** 2))

            origen = pOrigen
            destino = pDestino
            peso = int(distancia)

            if origen in grafo:
                grafo[origen].append((destino, peso))
            else:
                grafo[origen] = [(destino, peso)]
            if destino in grafo:
                grafo[destino].append((origen, peso))
            else:
                grafo[destino] = [(origen, peso)]

        cadena = pprint.pformat(grafo, width=40)
        #print(cadena)

        visitados = []
        grafoResultante = dict()
        colaPrioridad = []
        eleccion = self.ui.origenGrafo.text()
        #eleccion = "400.200"
        visitados.append(eleccion)
        for vecino in grafo[eleccion]:
            adya = (eleccion,) + vecino
            if adya not in colaPrioridad:
                colaPrioridad.insert(0, adya)

        while len(colaPrioridad) != 0:
            aux = 10000000000000
            for adyacente in colaPrioridad:
                if adyacente[1] not in visitados:
                    if adyacente[0] == visitados[-1]:
                        pesoD = adyacente[2]
                        if pesoD < aux:
                            aux = pesoD
                            eliminado = adyacente

            if len(colaPrioridad) != 0:
                if eliminado in colaPrioridad:
                    colaPrioridad.remove(eliminado)
                else:
                    colaPrioridad.clear()

            if eliminado[1] not in visitados:
                visitados.append(eliminado[1])

                for adyacente in grafo[eliminado[1]]:
                    adya = (eliminado[1],) + adyacente
                    if adya not in colaPrioridad:
                        colaPrioridad.insert(0, adya)
                grafoResultante[eliminado[0]] = [(eliminado[1], eliminado[2])]

        self.scene = QGraphicsScene()
        self.scene.setSceneRect(0, 0, 600, 600)
        self.ui.graphicsView.setScene(self.scene)

        self.pen = QPen()

        longitud = len(grafoResultante)
        contador = 0

        for item in grafoResultante.items():
            #print(item)
            puntoO = item[0]
            puntoD = item[1][0][0]
            #print('Punto O', puntoO)
            #print('Punto D',puntoD)
            origenX = int(puntoO.split(".", 2)[0])
            origenY = int(puntoO.split(".", 2)[1])
            destinoX = int(puntoD.split(".", 2)[0])
            destinoY = int(puntoD.split(".", 2)[0])
            self.scene.addEllipse(origenX, origenY, 5, 5, self.pen, QBrush(QColor(50, 100, 0)))
            contador = contador +1
            if contador == longitud:
                self.scene.addEllipse(int(item[1][0][0].split(".", 2)[0]), int(item[1][0][0].split(".", 2)[1]), 5, 5, self.pen, QBrush(QColor(50, 100, 0)))
            self.scene.addLine(int(item[0].split(".", 2)[0]), int(item[0].split(".", 2)[1]),int(item[1][0][0].split(".", 2)[0]), int(item[1][0][0].split(".", 2)[1]))

    @Slot()
    def mostrarGrafoOriginal(self):

        self.scene = QGraphicsScene()
        self.scene.setSceneRect(0, 0, 500, 500)
        self.ui.graphicsView.setScene(self.scene)

        self.pen = QPen()
        self.pen.setColor(QColor(0, 100, 0))
        self.pen.setWidth(3)

        #self.scene.addLine(0, 0, 499, 0, self.pen)
        #self.scene.addLine(0, 499, 499, 499, self.pen)
        #self.scene.addLine(0, 0, 0, 499, self.pen)
        #self.scene.addLine(499, 0, 499, 499, self.pen)

        for particula in self.listaparticulas.lista:
            #self.pen.setColor(QColor(particula.colorR, particula.colorG, particula.colorB))
            self.scene.addLine(particula.origenX, particula.origenY, particula.destinoX, particula.destinoY, self.pen)

            self.scene.addEllipse(particula.origenX, particula.origenY, 5, 5, self.pen, QBrush(QColor(50, 100, 0)))
            self.scene.addEllipse(particula.destinoX, particula.destinoY, 5, 5, self.pen, QBrush(QColor(100, 0, 0)))

    @Slot()
    def kruskal(self):

        def MAKE_SET(x):
            return [x]

        def FIND_SET(x, list):
            i = 0
            for element in list:
                try:
                    index= element.index(x)
                    return i
                except:
                    pass
                    #print("This is an error message!")
                i = i + 1
        def UNION(index_u, index_v,lista):
            L = lista[index_u]
            T = lista[index_v]

            lista.remove(L)
            lista.remove(T)

            final_list = list(set(L + T))
            lista.append(final_list)

            return lista

        grafoResultante = []
        colaPrioridad = []
        disjointSet = []

        for particula in self.listaparticulas.lista:
            pOrigen = str(particula.origenX) + ('.') + str(particula.origenY)
            pDestino = str(particula.destinoX) + ('.') + str(particula.destinoY)

            v1 = float(int(particula.destinoX) - int(particula.origenX))
            v2 = float(int(particula.destinoY) - int(particula.origenY))
            distancia = float(math.sqrt((v1) ** 2 + (v2) ** 2))

            origen = pOrigen
            destino = pDestino
            peso = int(distancia)

            arista = [origen,destino,peso]
            colaPrioridad.append(arista)

            disjointSet.append(MAKE_SET(origen))
            disjointSet.append(MAKE_SET(destino))


        colaPrioridad.sort(key=lambda x: x[2])
        disjointSet = [ii for n, ii in enumerate(disjointSet) if ii not in disjointSet[:n]]

        i = 0
        print(disjointSet)
        if len(colaPrioridad) != 0:

            for element in colaPrioridad:
                index_u = FIND_SET(element[0], disjointSet)
                index_v = FIND_SET(element[1], disjointSet)


                if FIND_SET(element[0],disjointSet) != FIND_SET(element[1],disjointSet):
                    grafoResultante.append(element)
                    disjointSet = UNION(index_u,index_v, disjointSet)
                i = i + 1

            print(disjointSet)

        print('  -> AEM ', grafoResultante)

        self.scene = QGraphicsScene()
        self.scene.setSceneRect(0, 0, 600, 600)
        self.ui.graphicsView.setScene(self.scene)

        self.pen = QPen()

        for item in grafoResultante:
            puntoO = item[0]
            puntoD = item[1]

            origenX = int(puntoO.split(".", 2)[0])
            origenY = int(puntoO.split(".", 2)[1])
            destinoX = int(puntoD.split(".", 2)[0])
            destinoY = int(puntoD.split(".", 2)[1])

            self.scene.addEllipse(origenX, origenY, 5, 5, self.pen, QBrush(QColor(100, 100, 0)))
            self.scene.addEllipse(destinoX, destinoY, 5, 5, self.pen, QBrush(QColor(100, 100, 0)))
            self.scene.addLine(int(item[0].split(".", 2)[0]), int(item[0].split(".", 2)[1]), int(item[1].split(".", 2)[0]), int(item[1].split(".", 2)[1]))