Пример #1
0
 def createItem(self, width, height):
     self._item = RoundRectItem(0, 0, width, height)
     self._item.setBrush(QtGui.QColor('light blue'))
     '''
Пример #2
0
class EditorItem(QtGui.QGraphicsWidget):
    '''
    Graphical representation of the data-model.
    '''
    def __init__(self,
                 index,
                 parent=None):
        super(EditorItem, self).__init__(parent)

        # Perhaps need an ItemDelegate/StyledItemDelegate
        # which transforms data from editor to model and back

        # perhaps just point this to the ItemModel()?
        self.modelindex = index
        self.dataMapper = QtGui.QDataWidgetMapper()
        self.dataMapper.setModel(self.modelindex.model())
        self.dataMapper.setOrientation(QtCore.Qt.Vertical)

        self.dataMapper.setRootIndex(self.modelindex)
        self.dataMapper.setCurrentIndex(1)

        self.delegate = EditorItemDelegate(self)
        self.dataMapper.setItemDelegate(self.delegate)

        self.itemWidget = EditorItemWidget(None, self)
        self.dataMapper.addMapping(self.itemWidget, 0)

        # graphics item which represents
        self._item = None
        # text label of this item
        item = self.modelindex.model().getModel(self.modelindex)
        self._label = TextItem(item['Name'], parent=self)

        self.loadResources()
        # self.setAcceptDrops(True)
        self.setAcceptHoverEvents(True)
        self.initializeFlags()
        self.updateGraphicsItem()

    def viewModel(self):
        return self.scene().viewModel()

    def updateLabel(self, width, height):
        self._label.updateGeometry()
        '''
        self._label.setAlignment(
            self.viewModel()[item.kind()]['text horizontal alignment'],
            self.viewModel()[item.kind()]['text vertical alignment']
        )
        self._label.setPos(
            self.viewModel()['text location'],
            self.pos(),
            width,
            height
        )
        '''

    def createItem(self, width, height):
        self._item = RoundRectItem(0, 0, width, height)
        self._item.setBrush(QtGui.QColor('light blue'))
        '''
        draw_style = self.viewModel()['draw style']
        if self.viewModel()['icon'] and draw_style == 'icon':
            self._item = QtGui.QGraphicsPixmapItem()
            self._item.setPixmap(
                QtGui.QPixmap(self.viewModel()['icon']).scaled(width,height)
            )
        else:
            if draw_style == 'rect':
                self._item = QtGui.QGraphicsRectItem(0,0,width,height)
            elif draw_style == 'ellipse':
                self._item = QtGui.QGraphicsEllipseItem(0,0,width,height)
            elif draw_style == 'round rect':
                self._item = RoundRectItem(0,0,width,height)
            if self._item:
                self._item.setBrush(QtGui.QColor(self.viewModel()['color']))
        '''

    def loadResources(self):
        self.setLayout(layout_create('horizontal'))
        '''
        new_layout = layout_create(self.viewModel()['layout style'])
        if type(self.layout()) != type(new_layout):
            new_layout.fromLayout(self.layout())
            self.setLayout(new_layout)
        '''
        sh = self.sizeHint(QtCore.Qt.SizeHint(), QtCore.QSizeF())
        width = sh.width()
        height = sh.height()
        self.updateLabel(width, height)
        self.createItem(width, height)

    def paint(self, painter, option, widget=None):
        super(EditorItem, self).paint(painter, option, widget)
        if self._item:
            self._item.paint(painter, option, widget)

    def boundingRect(self):
        minx = 0
        miny = 0
        maxx = 0
        maxy = 0
        if self._item:
            brect = self._item.boundingRect()
            minx = min(brect.x(),minx)
            miny = min(brect.y(),miny)
            maxx = max(maxx, brect.x() + brect.width())
            maxy = max(maxy, brect.y() + brect.height())
        if self._label:
            brect = self._label.boundingRect()
            minx = min(brect.x(), minx)
            miny = min(brect.y(), miny)
            maxx = max(maxx, brect.x() + brect.width())
            maxy = max(maxy, brect.y() + brect.height())
        retRect = QtCore.QRectF(minx, miny, maxx-minx, maxy-miny)
        return retRect

    def sizeHint(self, which, constraint):
        shw = 0
        shh = 0
        sh = self.layout().sizeHint(which, constraint)
        shw = sh.width()
        shh = sh.height()
        shw = max(shw, self.boundingRect().width())
        shh = max(shh, self.boundingRect().height())
        return QtCore.QSizeF(
            max(shw, 50),  # self.viewModel()['width']),
            max(shh, 50)  # self.viewModel()['height'])
        )
        
    def updateGraphicsItem(self):
        # self.layout().activate()
        self.prepareGeometryChange()
        sh = self.sizeHint(QtCore.Qt.SizeHint(), QtCore.QSizeF())
        width = sh.width()
        height = sh.height()
        self.updateLabel(width, height)
        self.createItem(width, height)
        self.updateGeometry()
        self.update()

    def updateChild(self, child):
        self.layout().updateItem(child)
        self.updateGraphicsItem()

    def removeChild(self, child):
        # Should this just point down to the underlying model's
        # removeRows() method and then let the updating take effect?
        self.layout().removeItem(child)
        self.updateGraphicsItem()

    def addChild(self, child):
        # Should this just point down to the underlying model's
        # insertRows() method and then let the updating take effect?
        self.layout().addItem(child)
        self.updateGraphicsItem()

    def isMovable(self):
        return bool(self.flags() & QtGui.QGraphicsItem.ItemIsMovable)

    def mouseDoubleClickEvent(self, event):
        QtGui.QGraphicsWidget.mouseDoubleClickEvent(self, event)
        '''
        e = QtGui.QMouseEvent(
            QtCore.QEvent.GraphicsSceneMouseDoubleClick,
            event.screenPos(),
            event.button(),
            event.buttons(),
            event.modifiers()
        )
        self.itemWidget.mouseDoubleClickEvent(e)
        '''
        editor = self.scene().parent().getEditor()
        editor.setDataMapper(self.dataMapper)
        editor.update()
        editor.show()
        editor.raise_()

    def updateAttributes(self, attrs):
        self.loadResources()
        self.updateGraphicsItem()
                
    '''
    BELOW HERE ARE NOT AS RELEVANT RIGHT NOW
    '''
    def initializeFlags(self):
        self.setFlag(QtGui.QGraphicsItem.ItemIsMovable)
        self.setFlag(QtGui.QGraphicsItem.ItemIsSelectable)
        self.setFlag(QtGui.QGraphicsItem.ItemSendsGeometryChanges)
        self.setFlag(QtGui.QGraphicsItem.ItemSendsScenePositionChanges)

    def getAnchors(self):
        a = self.boundingRect()
        anchorList = {
            'bottom left': a.bottomLeft(),
            'bottom right': a.bottomRight(),
            'top left': a.topLeft(),
            'top right': a.topRight(),
            'center left': (a.topLeft() + a.bottomLeft()) / 2.0,
            'center right': (a.topRight() + a.bottomRight()) / 2.0,
            'top center': (a.topLeft() + a.topRight()) / 2.0,
            'bottom center': (a.bottomLeft() + a.bottomRight()) / 2.0
        }
        return anchorList

    def contextMenuEvent(self, event):
        menu = QtGui.QMenu()

        item = self.modelindex.model().getModel(self.modelindex)

        if item.parent and \
           '0' in item.parent.children.get_cardinality_of(type(item)):
            delSelf = QtGui.QAction('Delete', self)
            delSelf.triggered.connect(self.delete)
            menu.addAction(delSelf)

        for a in item.children.allowed():
            addAction = QtGui.QAction('Add new {}'.format(a.__name__), self)
            addAction.triggered.connect(self.addNewItem(a))
            menu.addAction(addAction)
        
        menu.exec_(event.screenPos())

    def addNewItem(self, _type):
        def genericItem(e):
            self.modelindex.model().insertRows(0, 1, self.modelindex, _type)
        return genericItem

    def delete(self, event):
        # What should this method do?
        # Should this just point down to the underlying model's
        # removeRows() method and then let the updating take effect?
        for i in range(self.layout().count()):
            self.layout().itemAt(0).delete(None)
        if self.scene():
            self.scene().removeItem(self)

    def mousePressEvent(self, event):
        QtGui.QGraphicsWidget.mousePressEvent(self, event)

    def mouseMoveEvent(self, event):
        QtGui.QGraphicsWidget.mouseMoveEvent(self, event)

    def mouseReleaseEvent(self, event):
        QtGui.QGraphicsWidget.mouseReleaseEvent(self, event)

    def hoverEnterEvent(self, event):
        QtGui.QGraphicsWidget.hoverEnterEvent(self, event)

    def hoverLeaveEvent(self, event):
        QtGui.QGraphicsWidget.hoverLeaveEvent(self, event)