Exemplo n.º 1
0
class TakeDragGame(QWidget):
    def __init__(self, parent=None):
        super(TakeDragGame, self).__init__(parent)

        # This is always the same
        self.dot2 = QGraphicsTextItem(':')
        self.dot1 = QGraphicsTextItem(':')
        self.animations = []
        self.digits = []
        self.main_layout = QHBoxLayout()
        self.setLayout(self.main_layout)
        self.scene = QGraphicsScene()
        self.scene.setSceneRect(0, 0, 600, 400)
        self.view = QGraphicsView()
        self.view.setScene(self.scene)
        # TODO: Check if its better with opengl or not
        # self.view.setViewport(QtOpenGL.QGLWidget())
        self.main_layout.addWidget(self.view)
        # self.setWindowState(Qt.WindowMaximized)
        self.view.setAlignment(Qt.AlignTop | Qt.AlignLeft)
        self.image_bank = None
        self.create_and_add_images()

        # self.scene.setBackgroundBrush(QBrush(Qt.red, Qt.SolidPattern))

        # self.populate()
        # self.animator = QTimer()
        # self.animator.timeout.connect(self.animate)
        # self.animate()

    def create_and_add_images(self):
        self.load_images_json_file()
        self.add_background_to_image()
        self.add_background_from_image()
        if self.image_bank is not None:
            for image_id in self.image_bank.keys():
                if "clothes" in self.image_bank[image_id]["categories"]:
                    image_path = self.image_bank[image_id]["path"]
                    new_image = DraggableItem(image_path, self.background_from_image)
                    new_image.moved_signal.moved.connect(self.item_moved)
                    self.image_bank[image_id]["widget"] = new_image
                    newpos_x = self.background_from_image.boundingRect().width() / 2 - new_image.boundingRect().width() / 2
                    newpos_y = self.background_from_image.boundingRect().height() / 2 - new_image.boundingRect().height() / 2
                    new_image.setPos(newpos_x, newpos_y)
                    # self.scene.addItem(new_image)
                    new_image.setZValue(30)

    def item_moved(self, pos):
        widget = self.sender().get_parent()
        print widget.zValue()
        print self.background_from_image.zValue()
        print self.background_to_image.zValue()
        item_br = widget.sceneBoundingRect()
        if self.background_from_image.sceneBoundingRect().contains(item_br):
            widget.setParentItem(self.background_from_image)
            newpos_x = self.background_from_image.boundingRect().width() / 2 - widget.boundingRect().width() / 2
            newpos_y = self.background_from_image.boundingRect().height() / 2 - widget.boundingRect().height() / 2
            # self.background_to_image.stackBefore(self.background_from_image)
            widget.setPos(newpos_x, newpos_y)
        elif self.background_to_image.sceneBoundingRect().contains(item_br):
            widget.setParentItem(self.background_to_image)
            newpos_x = self.background_to_image.boundingRect().width() / 2 - widget.boundingRect().width() / 2
            newpos_y = self.background_to_image.boundingRect().height() / 2 - widget.boundingRect().height() / 2
            # self.background_from_image.stackBefore(self.background_to_image)
            widget.setPos(newpos_x, newpos_y)



    def load_images_json_file(self):
        with open(os.path.join(CURRENT_PATH, './resources/images.json')) as f:
            self.image_bank = json.load(f)

    def add_background_from_image(self, ):
        assert self.image_bank is not None, "Images need to be loaded before calling this method (try load_images_json_file)"
        if "Background from" in self.image_bank:
            background_from_pixmap = QPixmap(self.image_bank["Background from"]["path"])
            self.background_from_image = QGraphicsPixmapItem(background_from_pixmap)
            self.scene.addItem(self.background_from_image)
            self.background_from_image.setZValue(2)

    def add_background_to_image(self, ):
        assert self.image_bank is not None, "Images need to be loaded before calling this method (try load_images_json_file)"
        if "Background to" in self.image_bank:
            background_to_pixmap = QPixmap(self.image_bank["Background to"]["path"])
            self.background_to_image = QGraphicsPixmapItem(background_to_pixmap)
            self.scene.addItem(self.background_to_image)
            self.background_to_image.setZValue(2)

    def resizeEvent(self, event):
        view_size = self.view.size()
        new_background_height = (1.5 / 4.) * view_size.height()
        background_to_pixmap = QPixmap(self.image_bank["Background to"]["path"])
        background_to_pixmap = background_to_pixmap.scaled(new_background_height, new_background_height,
                                                           Qt.KeepAspectRatio)
        if not self.background_to_image:
            self.background_to_image = QGraphicsPixmapItem(background_to_pixmap)
        else:
            self.background_to_image.setPixmap(background_to_pixmap)
        sugested_x_position = int(2 * (view_size.width() / 3.))
        if sugested_x_position < 0:
            sugested_x_position = 0
        sugested_y_position = int(view_size.height() / 2. - background_to_pixmap.size().height() / 2)
        if sugested_y_position < 0:
            sugested_y_position = 0
        self.background_to_image.setPos(sugested_x_position, sugested_y_position)

        #####################
        new_background_height = (2.2 / 4.) * view_size.height()
        background_from_pixmap = QPixmap(self.image_bank["Background from"]["path"])
        background_from_pixmap = background_from_pixmap.scaled(new_background_height, new_background_height,
                                                               Qt.KeepAspectRatio)
        if not self.background_to_image:
            self.background_from_image = QGraphicsPixmapItem(background_from_pixmap)
        else:
            self.background_from_image.setPixmap(background_from_pixmap)

        sugested_x_position = int(view_size.width() / 5. - background_from_pixmap.size().height() / 2)
        if sugested_x_position < 0:
            sugested_x_position = 0
        sugested_y_position = int(view_size.height() / 2. - background_from_pixmap.size().height() / 2)
        if sugested_y_position < 0:
            sugested_y_position = 0
        self.background_from_image.setPos(sugested_x_position, sugested_y_position)

        ####
        new_widget_height = (1 / 4.) * view_size.height()
        if self.image_bank is not None:
            for image_id in self.image_bank.keys():
                if "clothes" in self.image_bank[image_id]["categories"]:
                    widget = self.image_bank[image_id]["widget"]
                    pixmap = widget.pixmap
                    pixmap = pixmap.scaled(new_widget_height, new_widget_height,
                                           Qt.KeepAspectRatio)
                    widget.setPixmap(pixmap)
                    print widget.moved_flag
                    if not widget.moved_flag:
                        newpos_x = self.background_from_image.boundingRect().width() / 2 - widget.boundingRect().width() / 2
                        newpos_y = self.background_from_image.boundingRect().height() / 2 - widget.boundingRect().height() / 2
                        widget.setPos(newpos_x, newpos_y)

        super(TakeDragGame, self).resizeEvent(event)
Exemplo n.º 2
0
class EditLinksNode(QGraphicsWidget):
    """
    A Node representation with channel anchors.

    `direction` specifies the layout (default `Qt.LeftToRight` will
    have icon on the left and channels on the right).

    """

    def __init__(self, parent=None, direction=Qt.LeftToRight,
                 node=None, icon=None, iconSize=None, **args):
        QGraphicsWidget.__init__(self, parent, **args)
        self.setAcceptedMouseButtons(Qt.NoButton)
        self.__direction = direction

        self.setLayout(QGraphicsLinearLayout(Qt.Horizontal))

        # Set the maximum size, otherwise the layout can't grow beyond its
        # sizeHint (and we need it to grow so the widget can grow and keep the
        # contents centered vertically.
        self.layout().setMaximumSize(QSizeF(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX))

        self.setSizePolicy(QSizePolicy.MinimumExpanding,
                           QSizePolicy.MinimumExpanding)

        self.__iconSize = iconSize or QSize(64, 64)
        self.__icon = icon

        self.__iconItem = QGraphicsPixmapItem(self)
        self.__iconLayoutItem = GraphicsItemLayoutItem(item=self.__iconItem)

        self.__channelLayout = QGraphicsGridLayout()
        self.__channelAnchors = []

        if self.__direction == Qt.LeftToRight:
            self.layout().addItem(self.__iconLayoutItem)
            self.layout().addItem(self.__channelLayout)
            channel_alignemnt = Qt.AlignRight

        else:
            self.layout().addItem(self.__channelLayout)
            self.layout().addItem(self.__iconLayoutItem)
            channel_alignemnt = Qt.AlignLeft

        self.layout().setAlignment(self.__iconLayoutItem, Qt.AlignCenter)
        self.layout().setAlignment(self.__channelLayout,
                                   Qt.AlignVCenter | channel_alignemnt)

        if node is not None:
            self.setSchemeNode(node)

    def setIconSize(self, size):
        """
        Set the icon size for the node.
        """
        if size != self.__iconSize:
            self.__iconSize = QSize(size)
            if self.__icon:
                self.__iconItem.setPixmap(self.__icon.pixmap(size))
                self.__iconLayoutItem.updateGeometry()

    def iconSize(self):
        """
        Return the icon size.
        """
        return QSize(self.__iconSize)

    def setIcon(self, icon):
        """
        Set the icon to display.
        """
        if icon != self.__icon:
            self.__icon = QIcon(icon)
            self.__iconItem.setPixmap(icon.pixmap(self.iconSize()))
            self.__iconLayoutItem.updateGeometry()

    def icon(self):
        """
        Return the icon.
        """
        return QIcon(self.__icon)

    def setSchemeNode(self, node):
        """
        Set an instance of `SchemeNode`. The widget will be initialized
        with its icon and channels.

        """
        self.node = node

        if self.__direction == Qt.LeftToRight:
            channels = node.output_channels()
        else:
            channels = node.input_channels()
        self.channels = channels

        loader = icon_loader.from_description(node.description)
        icon = loader.get(node.description.icon)

        self.setIcon(icon)

        label_template = ('<div align="{align}">'
                          '<b class="channelname">{name}</b><br/>'
                          '<span class="typename">{typename}</span>'
                          '</div>')

        if self.__direction == Qt.LeftToRight:
            align = "right"
            label_alignment = Qt.AlignVCenter | Qt.AlignRight
            anchor_alignment = Qt.AlignVCenter | Qt.AlignLeft
            label_row = 0
            anchor_row = 1
        else:
            align = "left"
            label_alignment = Qt.AlignVCenter | Qt.AlignLeft
            anchor_alignment = Qt.AlignVCenter | Qt.AlignLeft
            label_row = 1
            anchor_row = 0

        self.__channelAnchors = []
        grid = self.__channelLayout

        for i, channel in enumerate(channels):
            text = label_template.format(align=align,
                                         name=escape(channel.name),
                                         typename=escape(channel.type))

            text_item = GraphicsTextWidget(self)
            text_item.setHtml(text)
            text_item.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)

            grid.addItem(text_item, i, label_row,
                         alignment=label_alignment)

            anchor = ChannelAnchor(self, channel=channel,
                                   rect=QRectF(0, 0, 20, 20))

            anchor.setBrush(self.palette().brush(QPalette.Mid))

            layout_item = GraphicsItemLayoutItem(grid, item=anchor)
            grid.addItem(layout_item, i, anchor_row,
                         alignment=anchor_alignment)

            if hasattr(channel, "description"):
                text_item.setToolTip((channel.description))

            self.__channelAnchors.append(anchor)

    def anchor(self, channel):
        """
        Return the anchor item for the `channel` name.
        """
        for anchor in self.__channelAnchors:
            if anchor.channel() == channel:
                return anchor

        raise ValueError(channel.name)

    def paint(self, painter, option, widget=None):
        painter.save()
        palette = self.palette()
        border = palette.brush(QPalette.Mid)
        pen = QPen(border, 1)
        pen.setCosmetic(True)
        painter.setPen(pen)
        painter.setBrush(palette.brush(QPalette.Window))
        brect = self.boundingRect()
        painter.drawRoundedRect(brect, 4, 4)
        painter.restore()
Exemplo n.º 3
0
class ProbabilitiesItem(orangeqt.PlotItem):
    """
        Displays class probabilities in the background

        :param classifier: The classifier for which the probabilities are calculated
        :type classifier: orange.P2NN

        :param granularity: The size of individual cells
        :type granularity: int

        :param scale: The data scale factor
        :type scale: float

        :param spacing: The space between cells
        :param spacing: int

        :param rect: The rectangle into which to draw the probabilities. If unspecified, the entire plot is used.
        :type rect: QRectF
    """
    def __init__(self, classifier, granularity, scale, spacing, rect=None):
        orangeqt.PlotItem.__init__(self)
        self.classifier = classifier
        self.rect = rect
        self.granularity = granularity
        self.scale = scale
        self.spacing = spacing
        self.pixmap_item = QGraphicsPixmapItem(self)
        self.set_in_background(True)
        self.setZValue(ProbabilitiesZValue)

    def update_properties(self):
        ## Mostly copied from OWScatterPlotGraph
        if not self.plot():
            return

        if not self.rect:
            x, y = self.axes()
            self.rect = self.plot().data_rect_for_axes(x, y)
        s = self.graph_transform().mapRect(self.rect).size().toSize()
        if not s.isValid():
            return
        rx = s.width()
        ry = s.height()

        rx -= rx % self.granularity
        ry -= ry % self.granularity

        p = self.graph_transform().map(QPointF(
            0, 0)) - self.graph_transform().map(self.rect.topLeft())
        p = p.toPoint()

        ox = p.x()
        oy = -p.y()

        if self.classifier.classVar.is_continuous:
            imagebmp = orangeom.potentialsBitmap(self.classifier, rx, ry, ox,
                                                 oy, self.granularity,
                                                 self.scale)
            palette = [
                qRgb(255. * i / 255., 255. * i / 255., 255 - (255. * i / 255.))
                for i in range(255)
            ] + [qRgb(255, 255, 255)]
        else:
            imagebmp, nShades = orangeom.potentialsBitmap(
                self.classifier, rx, ry, ox, oy, self.granularity, self.scale,
                self.spacing)
            palette = []
            sortedClasses = get_variable_values_sorted(
                self.classifier.domain.classVar)
            for cls in self.classifier.classVar.values:
                color = self.plot().discPalette.getRGB(
                    sortedClasses.index(cls))
                towhite = [255 - c for c in color]
                for s in range(nShades):
                    si = 1 - float(s) / nShades
                    palette.append(
                        qRgb(*tuple(
                            [color[i] + towhite[i] * si for i in (0, 1, 2)])))
            palette.extend(
                [qRgb(255, 255, 255) for i in range(256 - len(palette))])

        self.potentialsImage = QImage(imagebmp, rx, ry, QImage.Format_Indexed8)
        self.potentialsImage.setColorTable(
            ColorPaletteDlg.signedPalette(palette
                                          ) if qVersion() < "4.5" else palette)
        self.potentialsImage.setNumColors(256)
        self.pixmap_item.setPixmap(QPixmap.fromImage(self.potentialsImage))
        self.pixmap_item.setPos(self.graph_transform().map(
            self.rect.bottomLeft()))

    def data_rect(self):
        return self.rect if self.rect else QRectF()
Exemplo n.º 4
0
class ProbabilitiesItem(orangeqt.PlotItem):
    """
        Displays class probabilities in the background

        :param classifier: The classifier for which the probabilities are calculated
        :type classifier: orange.P2NN

        :param granularity: The size of individual cells
        :type granularity: int

        :param scale: The data scale factor
        :type scale: float

        :param spacing: The space between cells
        :param spacing: int

        :param rect: The rectangle into which to draw the probabilities. If unspecified, the entire plot is used.
        :type rect: QRectF
    """

    def __init__(self, classifier, granularity, scale, spacing, rect=None):
        orangeqt.PlotItem.__init__(self)
        self.classifier = classifier
        self.rect = rect
        self.granularity = granularity
        self.scale = scale
        self.spacing = spacing
        self.pixmap_item = QGraphicsPixmapItem(self)
        self.set_in_background(True)
        self.setZValue(ProbabilitiesZValue)

    def update_properties(self):
        ## Mostly copied from OWScatterPlotGraph
        if not self.plot():
            return

        if not self.rect:
            x, y = self.axes()
            self.rect = self.plot().data_rect_for_axes(x, y)
        s = self.graph_transform().mapRect(self.rect).size().toSize()
        if not s.isValid():
            return
        rx = s.width()
        ry = s.height()

        rx -= rx % self.granularity
        ry -= ry % self.granularity

        p = self.graph_transform().map(QPointF(0, 0)) - self.graph_transform().map(self.rect.topLeft())
        p = p.toPoint()

        ox = p.x()
        oy = -p.y()

        if isinstance(self.classifier.classVar, ContinuousVariable):
            imagebmp = orangeom.potentialsBitmap(self.classifier, rx, ry, ox, oy, self.granularity, self.scale)
            palette = [qRgb(255.0 * i / 255.0, 255.0 * i / 255.0, 255 - (255.0 * i / 255.0)) for i in range(255)] + [
                qRgb(255, 255, 255)
            ]
        else:
            imagebmp, nShades = orangeom.potentialsBitmap(
                self.classifier, rx, ry, ox, oy, self.granularity, self.scale, self.spacing
            )
            palette = []
            sortedClasses = get_variable_values_sorted(self.classifier.domain.classVar)
            for cls in self.classifier.classVar.values:
                color = self.plot().discPalette.getRGB(sortedClasses.index(cls))
                towhite = [255 - c for c in color]
                for s in range(nShades):
                    si = 1 - float(s) / nShades
                    palette.append(qRgb(*tuple([color[i] + towhite[i] * si for i in (0, 1, 2)])))
            palette.extend([qRgb(255, 255, 255) for i in range(256 - len(palette))])

        self.potentialsImage = QImage(imagebmp, rx, ry, QImage.Format_Indexed8)
        self.potentialsImage.setColorTable(ColorPaletteDlg.signedPalette(palette) if qVersion() < "4.5" else palette)
        self.potentialsImage.setNumColors(256)
        self.pixmap_item.setPixmap(QPixmap.fromImage(self.potentialsImage))
        self.pixmap_item.setPos(self.graph_transform().map(self.rect.bottomLeft()))

    def data_rect(self):
        return self.rect if self.rect else QRectF()
Exemplo n.º 5
0
class Scene(QGraphicsScene):
    def __init__(self, lblXY, spinId, spinX, spinY, btnAddEdge, btnDeleteEdge, spinCommRange, spinEnvX, spinEnvY, comboChannelType):
        super(self.__class__, self).__init__()
        
        self.net = pymote.Network()
        self.net_dict = {} #for keeping pairs of net_node and scene_node
        
        self.comm_range = 200
        self.curr_id = 1
        self.node_size = 15
        self.node_color = QtCore.Qt.blue
        self.pressed_color = QtCore.Qt.red
        
        self.lblXY = lblXY #shows x,y position on scene
        self.spinId = spinId
        self.spinId.setEnabled(False)
        self.spinX = spinX
        self.spinY = spinY
        self.btnAddEdge = btnAddEdge
        self.btnDeleteEdge = btnDeleteEdge
        self.spinEnvX = spinEnvX
        self.spinEnvY = spinEnvY
        self.comboChannelType = comboChannelType
        self.hide_btn_edge() #on start: auto edge mode selected -> buttons add and delete edge not needed
        self.hide_pressed_item_data() #on start: no item is pressed -> hide item data
        
        self.spinCommRange = spinCommRange
        self.spinCommRange.setValue(self.comm_range)
        
        self.f_show_radius = False
        self.f_auto_edge = True
        self.f_move = False 
        self.f_moved = False
        self.f_show_env = True
        self.f_opening_net = False
        
        self.option = 0
        self.edge_option = 0
        self.last_pressed_node = 0
        self.radius = 0
        
        self.environment = pymote.Environment()
        self.scene_env = 0
        self.envX = 600
        self.envY = 600
        
        self.channel_type = self.comboChannelType.currentText()
        
        self.setSceneRect(QtCore.QRectF(0, -self.envY, self.envX, self.envY))
    
    def ini_scene(self):
        self.clear()
        
        new_net = pymote.Network()
        self.net = new_net
        self.net_dict.clear()
        
        self.curr_id = 1
        self.option = 0
        self.edge_option = 0
        self.last_pressed_node = 0
        self.radius = 0
        
        self.environment = pymote.Environment()
        self.scene_env = 0
    
    def get_net(self):
        return self.net
        
    def hide_pressed_item_data(self):
        #self.spinId.setEnable(False)
        self.spinId.setValue(0)
        self.spinX.setEnabled(False)
        self.spinX.setValue(0)
        self.spinY.setEnabled(False)
        self.spinY.setValue(0)
        
    def show_pressed_item_data(self):
        #self.spinId.setEnable(True)
        self.spinId.setValue(self.last_pressed_node.node_id)
        self.spinX.setEnabled(True)
        self.spinX.setValue(self.last_pressed_node.get_X())
        self.spinY.setEnabled(True)
        self.spinY.setValue(-self.last_pressed_node.get_Y())
    
    def hide_btn_edge(self):
        self.btnAddEdge.setEnabled(False)
        self.btnDeleteEdge.setEnabled(False)
    
    def show_btn_edge(self):
        self.btnAddEdge.setEnabled(True)
        self.btnDeleteEdge.setEnabled(True)
    
    def auto_add_edge(self, toggle):
        if toggle.isChecked() == True:
            self.f_auto_edge = True
            self.hide_btn_edge()
            
            self.delete_all_edges()            
            self.net.recalculate_edges()
            self.draw_all_edges()
        else:
            self.f_auto_edge = False
            self.show_btn_edge()
    
    def show_radius(self, toggle):
        if toggle.isChecked() == True:
            self.f_show_radius = True
            if self.last_pressed_node != 0 and self.option == 0:
                self.draw_radius(self.last_pressed_node.get_X() + self.node_size/2, self.last_pressed_node.get_Y() + self.node_size/2, self.comm_range)
        else:
            self.f_show_radius = False
            if self.radius != 0:
                self.delete_radius()
    
    def show_env(self, toggle):
        if toggle.isChecked() == True:
            self.f_show_env =True
            if self.scene_env != 0:
                self.scene_env.show()
        else:
            self.f_show_env = False
            if self.scene_env != 0:
                self.delete_env()
    
    def draw_radius(self, x, y, comm_range):
        self.radius = Radius(x, y, comm_range)
        self.addItem(self.radius)             
    
    def delete_radius(self):
        self.removeItem(self.radius)
        self.radius = 0

#    def search_node_by_id(self):
#        f_found = False
#        
#        if self.last_pressed_node != 0:
#            if self.last_pressed_node.node_id != self.spinId.value(): 
#                self.last_pressed_node.setBrush(self.node_color)
#                for n in self.items():
#                    if isinstance(n, Node):
#                        if n.node_id == self.spinId.value():
#                            if self.radius != 0 and self.f_show_radius:
#                                size = n.comm_range
#                                self.radius.setRect(n.get_X() - size, n.get_Y() - size, size * 2, size * 2)
#                            self.last_pressed_node = n
#                            n.setBrush(self.pressed_color)
#                            self.spinX.setValue(n.get_X())
#                            self.spinY.setValue(-n.get_Y())
#                            f_found = True
#            
#                if not f_found:
#                    self.last_pressed_node = 0
#                    self.spinX.setValue(0)
#                    self.spinY.setValue(0)
#                    if self.radius != 0:
#                        self.delete_radius()
        
    def change_node_x(self):
        if self.last_pressed_node != 0 and not self.f_move:
            if self.last_pressed_node.get_X() != self.spinX.value():
                self.spin_value_changed(True)
            
    def change_node_y(self):
        if self.last_pressed_node != 0 and not self.f_move:
            if -self.last_pressed_node.get_Y() != self.spinY.value():
                self.spin_value_changed(False)
    
    def spin_value_changed(self, f_isX):
        if not self.f_auto_edge:
            self.move_edges(self.last_pressed_node, self.spinX.value(), self.spinY.value())    
        if self.f_auto_edge and not self.f_moved: #delete edges before node is moved
            edges = list()
            for edge in self.last_pressed_node.edges:
                edges.append(edge)
            
            for edge in edges:
                self._delete_edge(edge, True)   
        
        if f_isX:        
            self.last_pressed_node.setX(self.spinX.value() - self.last_pressed_node.get_iniX())
            self.last_pressed_node.node_label.setX(self.spinX.value())
        else:
            self.last_pressed_node.setY(-self.spinY.value() - self.last_pressed_node.get_iniY())
            self.last_pressed_node.node_label.setY(-self.spinY.value())
            
        net_node, n = self.get_nodes_from_net(self.last_pressed_node, 0)
        self.net.pos[net_node] = [self.spinX.value(), self.spinY.value()]
        
        if self.f_auto_edge and not self.f_moved:
            self.net.recalculate_edges([self.last_pressed_node.net_node])
            self.draw_recalc_edges(self.last_pressed_node.net_node)
    
    def change_comm_range(self):
        self.comm_range = self.spinCommRange.value()
        if self.last_pressed_node != 0:            
            self.last_pressed_node.set_comm_range(self.comm_range)
            
            net_node, n = self.get_nodes_from_net(self.last_pressed_node, 0)
            net_node.commRange = self.comm_range
            
        if self.radius != 0:
            size = self.comm_range
            self.radius.setRect(self.radius.get_iniX() - size, self.radius.get_iniY() - size, size * 2, size * 2)
    
    def change_node_env_x(self):
        self.envX = self.spinEnvX.value()
        #TODO: dodati promjenu velicine env u net.env
        self.setSceneRect(QtCore.QRectF(0, -self.envY, self.envX, self.envY))
    
    def change_node_env_y(self):
        self.envY = self.spinEnvY.value()
        #TODO: dodati promjenu velicine env u net.env
        self.setSceneRect(QtCore.QRectF(0, -self.envY, self.envX, self.envY))
    
    def change_channel_type(self):
        if self.comboChannelType.currentIndex() == 0:
            self.net.channelType = pymote.channeltype.Udg(self.net.environment)            
        elif self.comboChannelType.currentIndex() == 1:
            self.net.channelType = pymote.channeltype.SquareDisc(self.net.environment)
        if not self.f_opening_net and self.f_auto_edge:
            self.delete_all_edges()
            self.net.recalculate_edges()
            self.draw_all_edges()
            
    def draw_net(self, net):
        self.ini_scene()
        self.net = net
        self.f_opening_net = True
        max_id = 0        
        
        for net_node in net:
            node = self.draw_node(net.pos[net_node][0], net.pos[net_node][1], net_node.id, net_node.commRange, net_node) 
            self.net_dict[net_node] = node
            if net_node.id > max_id:
                max_id = net_node.id
                
        self.curr_id = max_id + 1
        
        self.draw_all_edges()
        
        self.environment = net.environment
        img = Image.fromarray(net.environment.im[::-1, :], 'L')
        img.save('env.png')
        self.draw_env('env.png')
        
        combo_index = -1 
        if isinstance(net.channelType, pymote.channeltype.Udg):
            combo_index = 0
        elif isinstance(net.channelType, pymote.channeltype.SquareDisc):
            combo_index = 1
            
        self.comboChannelType.setCurrentIndex(combo_index)
        self.f_opening_net = False
                
    def draw_node(self, x, y, node_id, comm_range, net_node):
        node_label = Label(str(node_id), x, -y)
        self.addItem(node_label)
        
        node = Node(x - self.node_size/2, -y - self.node_size/2, self.node_size, node_id, node_label, comm_range, net_node)        
        node.setBrush(self.node_color)
        self.addItem(node)
        
        return node

    def draw_edge(self, node1, node2):
        edge = Edge(node1, node2)
        self.addItem(edge)
        
        node1.add_edge_to_list(edge)
        node2.add_edge_to_list(edge)
        
        return edge
    
    def draw_all_edges(self):
        net = self.net
        edges = list()
        for net_node in self.net:
            for n in net.adj[net_node].keys():
                f_draw_edge = True
                for e in edges: #check if edge already drawn
                    if (e[0] == net_node.id and e[1] == n.id) or (e[1] == net_node.id and e[0] == n.id):
                        f_draw_edge = False
                
                if f_draw_edge:
                    node = self.net_dict[net_node]
                    adj_node = self.net_dict[n]
                    self.draw_edge(node, adj_node)
                    edges.append((net_node.id, n.id))
                    
    def delete_all_edges(self):
        for item in self.items():
                if isinstance(item, Edge):
                    self._delete_edge(item, True)
                    
    def draw_recalc_edges(self, net_node):
        node = self.net_dict[net_node]
        
        for n in self.net.adj[net_node].keys():
            adj_node = self.net_dict[n]
            self.draw_edge(node, adj_node)
            
    def open_env(self):
        filters = ['Environment image (*.png)', 'All files (*)']
        selectedFilter = 'Environment image (*.png)'
        filters = ';;'.join(filters)

        fname = QFileDialog.getOpenFileName(
            self.parent(), "Choose a file to open", '', filters, selectedFilter)
        
        if fname:
            try:                
                self.environment.__init__(path = str(fname))
                self.net.environment = self.environment
                self.draw_env(fname)
            except Exception as e:
                print ("Error opening file %s" % str(e)),
                QMessageBox.critical(
                    self, "Error opening file", str(e),
                    QMessageBox.Ok, QMessageBox.NoButton)
    
    def draw_env(self, image):
        if self.scene_env == 0:    
            self.scene_env = QGraphicsPixmapItem()
        else:
            self.removeItem(self.scene_env)
        
        self.scene_env.setPixmap(QPixmap(image))
        
        if self.scene_env != 0:
            self.scene_env.setPos(0, -self.environment.im.shape[1])
        
        self.addItem(self.scene_env)
        self.scene_env.setZValue(-1)
            
        if not self.f_show_env:
            self.scene_env.hide()
        
        self.spinEnvX.setValue(self.environment.im.shape[0])
        self.spinEnvY.setValue(self.environment.im.shape[1])
            
        if self.f_auto_edge:
            self.delete_all_edges()
            self.net.recalculate_edges()
            self.draw_all_edges()
        
    def delete_env(self):
        if self.scene_env != 0:
            self.scene_env.hide()
    
    def option_change(self):
        if self.radius != 0:
            self.delete_radius()
        if self.edge_option != 0:
            self.edge_option = 0
            self.deselect_node()
        if self.last_pressed_node != 0:
            self.deselect_node()
    
    def move_node(self):
        self.option_change()
        self.option = 0    
    
    def add_node(self):
        self.option_change()
        self.option = 1
    
    def _add_node(self, x, y):        
        #add node to network
        net_node = pymote.Node()
        self.net.add_node(net_node, (x, y))
        net_node.id = self.curr_id
        net_node.commRange = self.comm_range
        
        #add node to scene
        node = self.draw_node(x, y, self.curr_id, self.comm_range, net_node)
        self.net_dict[net_node] = node
        
        self.curr_id = self.curr_id + 1
        
        '''when adding new node to network pymote calls recalculate_edges,
        if USE MODEL OF COMMUNICATON TO AUTO EDGES is not selected
        then we need to remove those edges'''
        if not self.f_auto_edge:
            self.net.adj[net_node].clear()
            for n in self.net:
                if self.net.adj[n].has_key(net_node):
                    del self.net.adj[n][net_node]
        else:
            self.draw_recalc_edges(net_node)
        
    def delete_node(self):
        self.option_change()
        self.option = 2
    
    def _delete_node(self, node):  
        #delete node edges from scene
        edges = list()
        for edge in node.edges:
            edges.append(edge)
            
        for edge in edges:
            self._delete_edge(edge, False)
            
        self.removeItem(node)
        self.removeItem(node.node_label)
        
        #delete node from network
        self.net.remove_node(node.net_node)
        del self.net_dict[node.net_node] 
        
    def add_edge(self):
        self.option_change()
        self.option = 3
            
    def _add_edge(self, pressed_node):
        if pressed_node != 0:
            if self.edge_option == 0:
                self.select_node(pressed_node)
                self.edge_option = 1
              
            if self.edge_option == 1 and self.last_pressed_node != pressed_node and self.last_pressed_node != 0:                   
                self.edge_option = 2
                edge_exists = self.find_edge(pressed_node, self.last_pressed_node)
                if edge_exists != 0: 
                    self.edge_option = 0 
                    self.deselect_node()
                        
            if self.edge_option == 2:
                self.draw_edge(self.last_pressed_node, pressed_node)
                self.edge_option = 0
                
                #add edge to net.adj            
                node1, node2 = self.get_nodes_from_net(self.last_pressed_node, pressed_node)
                if node1 != 0 and node2 != 0:            
                    self.net.adj[node1][node2] = []
                    self.net.adj[node2][node1] = []
                
                self.deselect_node()
                
        elif pressed_node == 0 and self.edge_option == 1:
            self.edge_option = 0
            self.deselect_node()
    
    def delete_edge(self):
        self.option_change()
        self.option = 4
            
    def _delete_edge(self, edge, f_recal_called):
        n1 = edge.node1
        n2 = edge.node2
        
        n1.remove_edge_from_list(edge)
        n2.remove_edge_from_list(edge)
        self.removeItem(edge)
        
        #delete edge from net.adj
        if not f_recal_called:
            node1, node2 = self.get_nodes_from_net(n1, n2)    
            if node1 != 0 and node2 != 0:
                self.delete_edge_from_adj(node1, node2)
                self.delete_edge_from_adj(node2, node1)
    
    def get_nodes_from_net(self, n1, n2):
        node1 = 0
        node2 = 0
        for n in self.net:
            if n.id == n1.node_id: 
                node1 = n
            if n2 != 0:
                if n.id == n2.node_id:
                    node2 = n
        return (node1, node2)
    
    def delete_edge_from_adj(self, node, del_n):
        del self.net.adj[node][del_n]
            
    def find_edge(self, node, n):
        for e in node.edges:
            if (n.get_X() == e.line().x1() and n.get_Y() == e.line().y1()) or (n.get_X() == e.line().x2() and n.get_Y() == e.line().y2()):
                return e
        return 0
    
    def select_node(self, node):
        self.last_pressed_node = node
        node.setBrush(self.pressed_color)
        
        if self.option == 0:
            self.show_pressed_item_data()
            
            if self.f_show_radius:
                self.draw_radius(node.get_X() + self.node_size/2, node.get_Y() + self.node_size/2, self.last_pressed_node.comm_range)
        
    def deselect_node(self):
        self.last_pressed_node.setBrush(self.node_color)
        self.last_pressed_node = 0
        
        self.hide_pressed_item_data()
        
        if self.radius != 0:
            self.delete_radius()
    
    def move_edges(self, node, x, y):
        for edge in node.edges:
            if edge.line().x1() == node.get_X() and edge.line().y1() == node.get_Y():
                edge.setLine(x, y, edge.line().x2(), edge.line().y2())
            else:
                edge.setLine(edge.line().x1(), edge.line().y1(), x, y)
        
    def mousePressEvent(self, e):
        mouseX = e.scenePos().x()
        mouseY = -e.scenePos().y()
        
        pressed_node = 0
        pressed_edge = 0
        
        self.f_move = True
        
        for item in self.items(e.scenePos()):
            if pressed_node == 0 and isinstance(item, Node):
                pressed_node = item
            if pressed_edge == 0 and isinstance(item, Edge):
                pressed_edge = item
        
        #on new mouse press deselect last node (only if option add edge is not selected)
        if self.last_pressed_node != 0:
            if self.edge_option != 1:
                self.deselect_node()
        
        if self.option == 1: #draw node
            self._add_node(mouseX, mouseY)
        
        elif self.option == 2: #delete node
            if pressed_node != 0:
                self._delete_node(pressed_node)
    
        elif self.option == 3: #add edge  
            self._add_edge(pressed_node)
                                
        elif self.option == 4: #delete edge
            if pressed_edge != 0:
                self._delete_edge(pressed_edge, False)
        
        #select new pressed node and save it
        if pressed_node != 0:
            if self.option == 0:
                self.select_node(pressed_node)
                self.spinCommRange.setValue(pressed_node.comm_range)
        else:
            self.last_pressed_node = 0
    
    def mouseMoveEvent(self, e):
        mouseX = e.scenePos().x()
        mouseY = e.scenePos().y()
        
        self.lblXY.setText('x: ' + str(mouseX) + '  y: ' + str(-mouseY))
        
        if self.last_pressed_node != 0 and self.f_move:
            node = self.last_pressed_node
            self.f_moved = True
            
            if self.option == 0:
                #when moving node, move his edges
                if not self.f_auto_edge:
                    self.move_edges(node, mouseX, mouseY)
                    
                #move node
                node.setX(mouseX - node.get_iniX())
                node.setY(mouseY - node.get_iniY())
                node.node_label.setPos(mouseX, mouseY)
                
                net_node, n = self.get_nodes_from_net(node, 0)
                self.net.pos[net_node][0] = mouseX
                self.net.pos[net_node][1] = -mouseY
                
                if self.f_auto_edge:
                    edges = list()
                    for edge in node.edges:
                        edges.append(edge)
                        
                    for edge in edges:
                        self._delete_edge(edge, True)
                
                self.spinX.setValue(mouseX)
                self.spinY.setValue(-mouseY)
                
        #move radius
        if self.f_show_radius and (self.option == 1 or (self.option == 0 and self.last_pressed_node != 0 and self.f_move)):
            if self.radius == 0 and self.option == 1:
                self.draw_radius(mouseX, mouseY, self.comm_range)
            elif self.radius != 0:
                self.radius.setX(mouseX - self.radius.get_iniX())
                self.radius.setY(mouseY - self.radius.get_iniY())
        
    def mouseReleaseEvent(self, e):        
        if self.f_auto_edge and self.last_pressed_node != 0 and self.option == 0 and self.f_moved:
            self.net.recalculate_edges([self.last_pressed_node.net_node])
            self.draw_recalc_edges(self.last_pressed_node.net_node)
            
        self.f_move = False
        self.f_moved = False
Exemplo n.º 6
0
class SlideshowFrame(object):
    def __init__(self, win, rect, filename, metadata):
        self.win = win
        self.rect = rect
        self.filename = filename
        self.metadata = metadata

        if self.metadata:
            self.line1 = self.metadata['Name']
            self.line2 = "%s Mission" % (self.metadata['Mission'])
            self.line3 = "%s" % (self.metadata['Time'])
        else:
            self.line1 = ""
            self.line2 = ""
            self.line3 = ""

        self.image = QGraphicsPixmapItem()
        self.win.scene.addItem(self.image)
        self.image.setTransformationMode(Qt.SmoothTransformation)

        self.use_two_lines = True

        self.fontsize1 = 32
        self.fontsize2 = 26
        self.fontsize3 = 24

        self.font1 = QFont('Times New Roman', self.fontsize1)
        self.font2 = QFont('Times New Roman', self.fontsize2)
        self.font3 = QFont('Times New Roman', self.fontsize3)

        self.title1 = self.win.scene.addText(self.line1, self.font1)
        self.title1.setDefaultTextColor(Qt.white)
        self.title1.setVisible(False)

        self.title2 = self.win.scene.addText(self.line2, self.font2)
        self.title2.setDefaultTextColor(Qt.white)
        self.title2.setVisible(False)

        self.title3 = self.win.scene.addText(self.line3, self.font3)
        self.title3.setDefaultTextColor(Qt.white)
        self.title3.setVisible(False)

        self.reservedHeight = 128
        self.padding = 20

        self.hide()

    def move(self, x, y):
        self.rect = QRectF(x, y, self.rect.width(), self.rect.height())

    def __rotate(self, metadata, origImgSize):
        # Qt only handles orientation properly from v5.5
        try:
            # try directly to get the tag, because sometimes get_tags() returns
            # tags that don't actually are in the file
            rot = metadata['Exif.Image.Orientation']
        except KeyError:
            # guess :-/
            rot = '1'

        # see http://www.daveperrett.com/images/articles/2012-07-28-exif-orientation-handling-is-a-ghetto/EXIF_Orientations.jpg
        # we have to 'undo' the rotations, so the numbers are negative
        if rot == '1':
            rotate = 0
            imgSize = origImgSize
        if rot == '8':
            rotate = -90
            imgSize = QSize(origImgSize.height(), origImgSize.width())
        if rot == '3':
            rotate = -180
            imgSize = origImgSize
        if rot == '6':
            rotate = -270
            imgSize = QSize(origImgSize.height(), origImgSize.width())

        # undo the last rotation and apply the new one
        self.image.setRotation(rotate)

        return imgSize

    def __zoomFit(self, imgSize):

        reservedHeight = self.reservedHeight + self.padding * 2

        hZoom = self.rect.width() / imgSize.width()
        vZoom = (self.rect.height() - reservedHeight) / imgSize.height()
        scale = min(hZoom, vZoom)

        self.image.setScale(scale)

        width = imgSize.width() * scale
        height = imgSize.height() * scale
        self.image.setPos(
            (self.rect.width() - width) / 2 + self.rect.x(),
            (self.rect.height() - reservedHeight - height) / 2 + self.rect.y())

    def layoutText(self):
        reservedHeight = self.reservedHeight + self.padding
        vertical_spacing = (self.reservedHeight -
                            self.title1.boundingRect().height() -
                            self.title2.boundingRect().height() -
                            self.title3.boundingRect().height()) / 3

        x = (self.rect.width() - self.title1.boundingRect().width()) / 2
        y = self.rect.height() - reservedHeight + vertical_spacing
        self.title1.setPos(x + self.rect.x(), y + self.rect.y())

        x = (self.rect.width() - self.title2.boundingRect().width()) / 2
        y = self.rect.height(
        ) - reservedHeight + vertical_spacing * 2 + self.title1.boundingRect(
        ).height()
        self.title2.setPos(x + self.rect.x(), y + self.rect.y())

        x = (self.rect.width() - self.title3.boundingRect().width()) / 2
        y = self.rect.height(
        ) - reservedHeight + vertical_spacing * 3 + self.title1.boundingRect(
        ).height() + self.title2.boundingRect().height()
        self.title3.setPos(x + self.rect.x(), y + self.rect.y())

    def show(self):
        img = QPixmap(self.filename)

        try:
            metadata = GExiv2.Metadata(self.filename)
        except GLib.Error as e:
            print(repr(e))
            return

        self.image.setPixmap(img)
        self.image.setScale(1.0)
        self.image.setRotation(0)

        imgSize = self.__rotate(metadata, img.size())
        self.__zoomFit(imgSize)
        self.layoutText()

        self.title1.setVisible(True)
        self.title2.setVisible(True)
        self.title3.setVisible(True)
        self.image.setVisible(True)

    def hide(self):
        self.title1.setVisible(False)
        self.title2.setVisible(False)
        self.title3.setVisible(False)
        self.image.setVisible(False)
        self.image.setPixmap(QPixmap())

    def showImage(self, file, md):
        self.metadata = md

        try:
            metadata = GExiv2.Metadata(file)
        except GLib.Error as e:
            print(repr(e))
            return

        img = QPixmap(file)

        self.image.setPixmap(img)
        self.image.setScale(1.0)
        self.image.setRotation(0)

        imgSize = self.__rotate(metadata, img.size())

        self.__zoomFit(imgSize)
        self.layoutMetadata()
Exemplo n.º 7
0
class EditLinksNode(QGraphicsWidget):
    """
    A Node representation with channel anchors.

    `direction` specifies the layout (default `Qt.LeftToRight` will
    have icon on the left and channels on the right).

    """
    def __init__(self,
                 parent=None,
                 direction=Qt.LeftToRight,
                 node=None,
                 icon=None,
                 iconSize=None,
                 **args):
        QGraphicsWidget.__init__(self, parent, **args)
        self.setAcceptedMouseButtons(Qt.NoButton)
        self.__direction = direction

        self.setLayout(QGraphicsLinearLayout(Qt.Horizontal))

        # Set the maximum size, otherwise the layout can't grow beyond its
        # sizeHint (and we need it to grow so the widget can grow and keep the
        # contents centered vertically.
        self.layout().setMaximumSize(QSizeF(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX))

        self.setSizePolicy(QSizePolicy.MinimumExpanding,
                           QSizePolicy.MinimumExpanding)

        self.__iconSize = iconSize or QSize(64, 64)
        self.__icon = icon

        self.__iconItem = QGraphicsPixmapItem(self)
        self.__iconLayoutItem = GraphicsItemLayoutItem(item=self.__iconItem)

        self.__channelLayout = QGraphicsGridLayout()
        self.__channelAnchors = []

        if self.__direction == Qt.LeftToRight:
            self.layout().addItem(self.__iconLayoutItem)
            self.layout().addItem(self.__channelLayout)
            channel_alignemnt = Qt.AlignRight

        else:
            self.layout().addItem(self.__channelLayout)
            self.layout().addItem(self.__iconLayoutItem)
            channel_alignemnt = Qt.AlignLeft

        self.layout().setAlignment(self.__iconLayoutItem, Qt.AlignCenter)
        self.layout().setAlignment(self.__channelLayout,
                                   Qt.AlignVCenter | channel_alignemnt)

        if node is not None:
            self.setSchemeNode(node)

    def setIconSize(self, size):
        """
        Set the icon size for the node.
        """
        if size != self.__iconSize:
            self.__iconSize = QSize(size)
            if self.__icon:
                self.__iconItem.setPixmap(self.__icon.pixmap(size))
                self.__iconLayoutItem.updateGeometry()

    def iconSize(self):
        """
        Return the icon size.
        """
        return QSize(self.__iconSize)

    def setIcon(self, icon):
        """
        Set the icon to display.
        """
        if icon != self.__icon:
            self.__icon = QIcon(icon)
            self.__iconItem.setPixmap(icon.pixmap(self.iconSize()))
            self.__iconLayoutItem.updateGeometry()

    def icon(self):
        """
        Return the icon.
        """
        return QIcon(self.__icon)

    def setSchemeNode(self, node):
        """
        Set an instance of `SchemeNode`. The widget will be initialized
        with its icon and channels.

        """
        self.node = node

        if self.__direction == Qt.LeftToRight:
            channels = node.output_channels()
        else:
            channels = node.input_channels()
        self.channels = channels

        loader = icon_loader.from_description(node.description)
        icon = loader.get(node.description.icon)

        self.setIcon(icon)

        label_template = ('<div align="{align}">'
                          '<b class="channelname">{name}</b><br/>'
                          '<span class="typename">{typename}</span>'
                          '</div>')

        if self.__direction == Qt.LeftToRight:
            align = "right"
            label_alignment = Qt.AlignVCenter | Qt.AlignRight
            anchor_alignment = Qt.AlignVCenter | Qt.AlignLeft
            label_row = 0
            anchor_row = 1
        else:
            align = "left"
            label_alignment = Qt.AlignVCenter | Qt.AlignLeft
            anchor_alignment = Qt.AlignVCenter | Qt.AlignLeft
            label_row = 1
            anchor_row = 0

        self.__channelAnchors = []
        grid = self.__channelLayout

        for i, channel in enumerate(channels):
            text = label_template.format(align=align,
                                         name=escape(channel.name),
                                         typename=escape(channel.type))

            text_item = GraphicsTextWidget(self)
            text_item.setHtml(text)
            text_item.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)

            grid.addItem(text_item, i, label_row, alignment=label_alignment)

            anchor = ChannelAnchor(self,
                                   channel=channel,
                                   rect=QRectF(0, 0, 20, 20))

            anchor.setBrush(self.palette().brush(QPalette.Mid))

            layout_item = GraphicsItemLayoutItem(grid, item=anchor)
            grid.addItem(layout_item,
                         i,
                         anchor_row,
                         alignment=anchor_alignment)

            if hasattr(channel, "description"):
                text_item.setToolTip((channel.description))

            self.__channelAnchors.append(anchor)

    def anchor(self, channel):
        """
        Return the anchor item for the `channel` name.
        """
        for anchor in self.__channelAnchors:
            if anchor.channel() == channel:
                return anchor

        raise ValueError(channel.name)

    def paint(self, painter, option, widget=None):
        painter.save()
        palette = self.palette()
        border = palette.brush(QPalette.Mid)
        pen = QPen(border, 1)
        pen.setCosmetic(True)
        painter.setPen(pen)
        painter.setBrush(palette.brush(QPalette.Window))
        brect = self.boundingRect()
        painter.drawRoundedRect(brect, 4, 4)
        painter.restore()