예제 #1
0
    def draw_word_boxes(self, word_boxes: list) -> None:
        """Sets up and draws translated words and their corresponding frames

        :param word_boxes: list of WordBox namedtuples, each representing a word and frame to be drawn.
                           ex: [WordBox('word'=str, 'geometry'=[(int, int)], WordBox('word'=str, 'geometry'=[(int, int)])

        """

        for wPoly in self.__word_polygons:
            self.__scene.removeItem(wPoly[0])
            self.__scene.removeItem(wPoly[1])

        self.__word_polygons = []

        for word_box in word_boxes:
            points = list(map(lambda x: QPoint(x[0], x[1]), word_box.geometry))

            text = QGraphicsTextItem(word_box.word)
            text.setOpacity(0)
            text.setAcceptHoverEvents(False)

            font = QFont()
            font.setPixelSize(abs(points[0].y() - points[3].y()))
            text.setFont(font)

            w = text.boundingRect().width()
            h = text.boundingRect().height()
            text.setPos(
                points[0].x() + abs(points[0].x() - points[1].x()) / 2 - w / 2,
                points[0].y() + abs(points[0].y() - points[3].y()) / 2 - h / 2)
            frame = WordPolygon(QPolygonF(QPolygon(points)), text)

            self.__word_polygons.append([text, frame])
            self.__scene.addItem(frame)
            self.__scene.addItem(text)
예제 #2
0
    def drawScene(self, scene):
        scaleDpi = 101.0 / 72.0  # (true res for 344x193 mm, 1366x768) / 72
        LLx = self.graph.boundingBox['LLx']
        LLy = self.graph.boundingBox['LLx']
        URx = self.graph.boundingBox['URx']
        URy = self.graph.boundingBox['URy']
        scene.addRect(LLx * scaleDpi, LLy * scaleDpi, URx * scaleDpi,
                      URy * scaleDpi)
        scale = 96  # maybe this is because GV uses 96 dpi and operates in inches
        for node in self.graph.nodesPtr:
            ng = self.graph.nodeGeometry(node)
            x = ng['centerX'] * scaleDpi
            y = (self.graph.boundingBox['URy'] - ng['centerY']) * scaleDpi
            rx = (ng['width'] / 2) * scale
            ry = (ng['height'] / 2) * scale
            el = NodeShape(x - rx, y - ry, 2 * rx, 2 * ry)
            label = self.graph.nodeLabel(node)
            lbl = QGraphicsTextItem(self.tr(label), el)
            # TODO: text positioniong
            lbl.setAcceptHoverEvents(False)
            # TODO: try to make child.event()
            lbl.setPos(x, y)
            scene.addItem(el)

        for edge in self.graph.edgesGeom:
            # TODO: edges hover
            spl = edge[0]
            if not spl['sflag']:
                start = spl['points'][0]
            else:
                start = spl['sarrowtip']
            if not spl['eflag']:
                end = spl['points'][-1]
            else:
                end = spl['earrowtip']
            x1 = start['x'] * scaleDpi
            y1 = (self.graph.boundingBox['URy'] - start['y']) * scaleDpi
            x2 = end['x'] * scaleDpi
            y2 = (self.graph.boundingBox['URy'] - end['y']) * scaleDpi
            scene.addLine(x1, y1, x2, y2)
예제 #3
0
파일: items.py 프로젝트: saltekar2000/sloth
class BaseItem(QAbstractGraphicsShapeItem):
    """
    Base class for visualization items.
    """

    cycleValuesOnKeypress = {}
    hotkeys = {}
    defaultAutoTextKeys = []

    def __init__(self, model_item=None, prefix="", parent=None):
        """
        Creates a visualization item.
        """
        QAbstractGraphicsShapeItem.__init__(self, parent)
        self.setFlags(QGraphicsItem.ItemIsSelectable
                      | QGraphicsItem.ItemIsMovable
                      | QGraphicsItem.ItemSendsGeometryChanges
                      | QGraphicsItem.ItemSendsScenePositionChanges)

        self._model_item = model_item
        if self._model_item is not None:
            self._model_item.model().dataChanged.connect(self.onDataChanged)

        # initialize members
        self._prefix = prefix
        self._auto_text_keys = self.defaultAutoTextKeys[:]
        self._text = ""
        self._text_bg_brush = None
        self._text_item = QGraphicsTextItem(self)
        self._text_item.setPos(0, 0)
        self._text_item.setAcceptHoverEvents(False)
        self._text_item.setFlags(QGraphicsItem.ItemIgnoresTransformations)
        self._text_item.setHtml(self._compile_text())
        self._valid = True

        if len(self.cycleValuesOnKeypress) > 0:
            logging.warning(
                "cycleValueOnKeypress is deprecated and will be removed in the future. "
                + "Set BaseItem.hotkeys instead with cycleValue()")

        self.changeColor()

    def changeColor(self):
        if self._model_item is not None:
            c = self._model_item.getColor()
            if c is not None:
                self.setColor(c)
                return
        self.setColor(Qt.yellow)

    def onDataChanged(self, indexFrom, indexTo):
        # FIXME why is this not updated, when changed graphically via attribute box ?
        #print "onDataChanged", self._model_item.index(), indexFrom, indexTo, indexFrom.parent()
        if indexFrom == self._model_item.index():
            self.changeColor()
            #print "hit"
            # self._text_item.setHtml(self._compile_text())

    def modelItem(self):
        """
        Returns the model item of this items.
        """
        return self._model_item

    def index(self):
        """
        Returns the index of this item.
        """
        return self._model_item.index()

    def prefix(self):
        """
        Returns the key prefix of the item.
        """
        return self._prefix

    def setPen(self, pen):
        pen = QPen(pen)  # convert to pen if argument is a QColor
        QAbstractGraphicsShapeItem.setPen(self, pen)
        self._text_item.setDefaultTextColor(pen.color())

    def setText(self, text=""):
        """
        Sets a text to be displayed on this item.
        """
        self._text = text
        self._text_item.setHtml(self._compile_text())

    def text(self):
        return self._text

    def setTextBackgroundBrush(self, brush=None):
        """
        Sets the brush to be used to fill the background region
        behind the text. Set to None to not draw a background
        (leave transparent).
        """
        self._text_bg_brush = brush

    def textBackgroundBrush(self):
        """
        Returns the background brush for the text region.
        """
        return self._text_bg_brush

    def setAutoTextKeys(self, keys=None):
        """
        Sets the keys for which the values from the annotations
        are displayed automatically as text.
        """
        self._auto_text_keys = keys or []
        self._text_item.setHtml(self._compile_text())

    def autoTextKeys(self):
        """
        Returns the list of keys for which the values from
        the annotations are displayed as text automatically.
        """
        return self._auto_text_keys

    def isValid(self):
        """
        Return whether this graphics item is valid, i.e. has
        a matching, valid model item connected to it.  An item is
        by default valid, will only be set invalid on failure.
        """
        return self._valid

    def setValid(self, val):
        self._valid = val

    def _compile_text(self):
        text_lines = []
        if self._text != "" and self._text is not None:
            text_lines.append(self._text)
        for key in self._auto_text_keys:
            text_lines.append("%s: %s" % \
                    (key, self._model_item.get(key, "")))
        return '<br/>'.join(text_lines)

    def dataChanged(self):
        self.dataChange()
        self._text_item.setHtml(self._compile_text())
        self.update()

    def dataChange(self):
        pass

    def updateModel(self, ann=None):
        if ann is not None:
            self._model_item.update(ann)

    def boundingRect(self):
        return QRectF(0, 0, 0, 0)

    def setColor(self, color):
        self.setPen(color)
        self.setBrush(color)
        self.update()

    def paint(self, painter, option, widget=None):
        pass

    def itemChange(self, change, value):
        if change == QGraphicsItem.ItemPositionHasChanged:
            self.updateModel()
        return QAbstractGraphicsShapeItem.itemChange(self, change, value)

    def keyPressEvent(self, event):
        """
        This handles the value cycling as defined in cycleValuesOnKeypress.
        """
        if str(event.text()) in self.cycleValuesOnKeypress:
            itemkey, valuelist = self.cycleValuesOnKeypress[str(event.text())]
            if isinstance(itemkey, IgnorePrefix):
                itemkey = itemkey.value
            else:
                itemkey = self.prefix() + itemkey
            if len(valuelist) > 0:
                oldvalue = self._model_item.get(itemkey, None)
                if oldvalue is None:
                    nextindex = 0
                else:
                    try:
                        nextindex = valuelist.index(oldvalue) + 1
                        nextindex %= len(valuelist)
                    except ValueError:
                        nextindex = 0
                newvalue = valuelist[nextindex]
                if newvalue is None:
                    if oldvalue is not None:
                        self._model_item.delete(itemkey)
                else:
                    self._model_item[itemkey] = valuelist[nextindex]
                self.dataChanged()
                event.accept()
        elif str(event.text()) in self.hotkeys:
            self.hotkeys[str(event.text())](self)
            event.accept()