class BubbleShape(Shape): def __init__(self): def initHandle(handle): self.handles.append(handle) QObject.connect(handle, SIGNAL("moved(QGraphicsObject*)"), self.handleMoved) Shape.__init__(self, BubbleItem(self)) # Item self.item.setFlag(QGraphicsItem.ItemIsSelectable) self.item.setBrush(COLOR) # Text item self.textItem = QGraphicsTextItem(self.item) self.textItem.setTextInteractionFlags(Qt.TextEditorInteraction) QObject.connect(self.textItem.document(), SIGNAL("contentsChanged()"), \ self.adjustSizeFromText) # Handles self.anchorHandle = Handle(self.item, 0, 0) # Position the bubble to the right of the anchor so that it can grow # vertically without overflowing the anchor self.bubbleHandle = Handle(self.item, ANCHOR_THICKNESS, -ANCHOR_THICKNESS) initHandle(self.anchorHandle) initHandle(self.bubbleHandle) self.setHandlesVisible(False) self.adjustSizeFromText() def adjustSizeFromText(self): # Compute text rect self.textItem.adjustSize() if self.textItem.textWidth() < MIN_TEXT_WIDTH: self.textItem.setTextWidth(MIN_TEXT_WIDTH) textSize = self.textItem.document().size() rect = QRectF(self.bubbleHandle.pos(), textSize) rect.adjust(0, 0, 2*MARGIN, 2*MARGIN) # Position textItem in text rect self.textItem.setPos(rect.left() + MARGIN, rect.top() + MARGIN) # Compute path path = QPainterPath() path.addRoundedRect(rect, BUBBLE_RADIUS, BUBBLE_RADIUS) path = path.united(createAnchorPath(rect.center(), self.anchorHandle.pos())) path.translate(0.5, 0.5) self.item.setPath(path) def handleMoved(self, handle): self.adjustSizeFromText()