def computeGfxNodeSizes(self): # compute heights of header and properties headerFontMetric = QtGui.QFontMetricsF(self.headerFont) propFontMetric = QtGui.QFontMetricsF(self.propertyFont) headerFontHeight = headerFontMetric.height() propFontHeight = propFontMetric.height() # find the largest width input and output text # min is 10 widthsInput = [10] for prop in self.node.inputProps: widthsInput.append(propFontMetric.width(prop.name)) widthsOutput = [10] for prop in self.node.outputProps: widthsOutput.append(propFontMetric.width(prop.name)) maxInputWidth = max(widthsInput) maxOutputWidth = max(widthsOutput) # little offset and connectionBox dimensions propBoxSize = propFontHeight * 0.75 # compute total height and width totalHeight = headerFontHeight + propBoxSize totalHeight += max( [len(self.node.inputProps), len(self.node.outputProps)]) * 2 * propBoxSize totalWidth = self.edgeSeparator + propBoxSize totalWidth += propBoxSize * 0.5 + maxInputWidth totalWidth += propBoxSize * 0.5 + self.inputOutputSeparator + propBoxSize * 0.5 totalWidth += maxOutputWidth + propBoxSize * 0.5 totalWidth += propBoxSize + self.edgeSeparator totalWidthHeader = self.edgeSeparator + propBoxSize totalWidthHeader += propBoxSize * 0.5 + headerFontMetric.width( self.node.name) + propBoxSize * 0.5 totalWidthHeader += propBoxSize + self.edgeSeparator # clamp to header width totalWidth = max([totalWidthHeader, totalWidth]) # preview size self.previewPixmapSizeStartP = (10, totalHeight + 10) self.previewPixmapWidth = totalWidth - 20 self.previewPixmapHeight = totalWidth - 20 if self.node.gfxNode: # TODO: refactor if self.node.gfxNode.previewPixmapEnabled: totalHeight += totalWidth # store computed stuff self.rect = QtCore.QRectF(0, 0, totalWidth, totalHeight) self.shadowRect = QtCore.QRectF(5, 5, totalWidth, totalHeight) self.propBoxSize = propBoxSize self.headerFontHeight = headerFontHeight self.headerHeight = propBoxSize self.maxInputWidth = maxInputWidth self.maxOutputWidth = maxOutputWidth
def setupSceneItems(self): if Colors.showFps: self.fpsLabel = DemoTextItem("FPS: --", Colors.buttonFont(), QtCore.Qt.white, -1, self.scene, None, DemoTextItem.DYNAMIC_TEXT) self.fpsLabel.setZValue(1000) self.fpsLabel.setPos( Colors.stageStartX, 600 - QtGui.QFontMetricsF(Colors.buttonFont()).height() - 5) self.mainSceneRoot = QtGui.QGraphicsWidget() self.scene.addItem(self.mainSceneRoot) self.companyLogo = ImageItem( QtGui.QImage(':/images/trolltech-logo.png'), 1000, 1000, self.scene, None, True, 0.5) self.qtLogo = ImageItem(QtGui.QImage(':/images/qtlogo_small.png'), 1000, 1000, self.scene, None, True, 0.5) self.companyLogo.setZValue(100) self.qtLogo.setZValue(100) self.pausedLabel = DemoTextItem("PAUSED", Colors.buttonFont(), QtCore.Qt.white, -1, self.scene, None) self.pausedLabel.setZValue(100) fm = QtGui.QFontMetricsF(Colors.buttonFont()) self.pausedLabel.setPos(Colors.stageWidth - fm.width("PAUSED"), 590 - fm.height()) self.pausedLabel.setRecursiveVisible(False)
def __init__(self, text, font, pen, position, maxSize, alignment=QtCore.Qt.AlignVCenter | QtCore.Qt.AlignLeft): super(TitleShape, self).__init__(position, maxSize) self.font = QtGui.QFont(font) self.text = QtCore.QString(text) self.pen = pen self.alignment = alignment fm = QtGui.QFontMetricsF(self.font) self.textRect = fm.boundingRect( QtCore.QRectF(QtCore.QPointF(0, 0), maxSize), self.alignment, self.text) textWidth = max(fm.width(self.text), self.textRect.width()) textHeight = max(fm.height(), self.textRect.height()) scale = min(maxSize.width() / textWidth, maxSize.height() / textHeight) self.font.setPointSizeF(self.font.pointSizeF() * scale) fm = QtGui.QFontMetricsF(self.font) self.textRect = fm.boundingRect( QtCore.QRectF(QtCore.QPointF(0, 0), maxSize), self.alignment, self.text) self.baselineStart = QtCore.QPointF( self.textRect.left(), self.textRect.bottom() - fm.descent())
def paint(self, painter, option, widget=None): rect = QtCore.QRectF(-(ModelerGraphicItem.BOX_WIDTH + 2)/2, -(ModelerGraphicItem.BOX_HEIGHT + 2)/2, ModelerGraphicItem.BOX_WIDTH + 2, ModelerGraphicItem.BOX_HEIGHT + 2) painter.setPen(QtGui.QPen(QtCore.Qt.gray, 1)) painter.setBrush(QtGui.QBrush(QtCore.Qt.white, QtCore.Qt.SolidPattern)) painter.drawRect(rect) font = QtGui.QFont("Verdana", 8) painter.setFont(font) if self.isSelected(): painter.setPen(QtGui.QPen(QtCore.Qt.blue)) else: painter.setPen(QtGui.QPen(QtCore.Qt.black)) fm = QtGui.QFontMetricsF(font) text = self.getAdjustedText(self.text) w = fm.width(QtCore.QString(text)) h = fm.height() pt = QtCore.QPointF(-w/2, h/2) painter.drawText(pt, text) if isinstance(self.element, GeoAlgorithm): if self.elementIndex in self.model.deactivated: painter.setPen(QtGui.QPen(QtCore.Qt.red)) w = fm.width(QtCore.QString("[deactivated]")) pt = QtCore.QPointF(-w/2, h+h/2) painter.drawText(pt, "[deactivated]") painter.drawPixmap(-10 , -(ModelerGraphicItem.BOX_HEIGHT )/3,self.pixmap)
def paint(self, painter, option, widget=None): rect = QtCore.QRectF(-(ModelerGraphicItem.BOX_WIDTH + 2) / 2.0, -(ModelerGraphicItem.BOX_HEIGHT + 2) / 2.0, ModelerGraphicItem.BOX_WIDTH + 2, ModelerGraphicItem.BOX_HEIGHT + 2) painter.setPen(QtGui.QPen(QtCore.Qt.gray, 1)) color = QtGui.QColor(125, 232, 232) if isinstance(self.element, Parameter): color = QtGui.QColor(179, 179, 255) elif isinstance(self.element, GeoAlgorithm): color = QtCore.Qt.white painter.setBrush(QtGui.QBrush(color, QtCore.Qt.SolidPattern)) painter.drawRect(rect) font = QtGui.QFont("Verdana", 8) painter.setFont(font) painter.setPen(QtGui.QPen(QtCore.Qt.black)) if self.isSelected(): painter.setPen(QtGui.QPen(QtCore.Qt.blue)) if isinstance(self.element, GeoAlgorithm): if self.elementIndex in self.model.deactivated: painter.setPen(QtGui.QPen(QtCore.Qt.lightGray)) fm = QtGui.QFontMetricsF(font) text = self.getAdjustedText(self.text) h = fm.height() pt = QtCore.QPointF(-(ModelerGraphicItem.BOX_WIDTH) / 2 + 25, h / 2.0) painter.drawText(pt, text) painter.setPen(QtGui.QPen(QtCore.Qt.black)) if isinstance(self.element, GeoAlgorithm): h = -(fm.height() * 1.2) h = h - ModelerGraphicItem.BOX_HEIGHT / 2.0 + 5 pt = QtCore.QPointF(-(ModelerGraphicItem.BOX_WIDTH) / 2 + 25, h) painter.drawText(pt, "In") i = 1 if not self.inputFolded: for param in self.element.parameters: text = self.getAdjustedText(param.description) h = -(fm.height() * 1.2) * (i + 1) h = h - ModelerGraphicItem.BOX_HEIGHT / 2.0 + 5 pt = QtCore.QPointF( -(ModelerGraphicItem.BOX_WIDTH) / 2 + 33, h) painter.drawText(pt, text) i += 1 i = 1 h = (fm.height() * 1.2) h = h + ModelerGraphicItem.BOX_HEIGHT / 2.0 pt = QtCore.QPointF(-(ModelerGraphicItem.BOX_WIDTH) / 2 + 25, h) painter.drawText(pt, "Out") if not self.outputFolded: for out in self.element.outputs: text = self.getAdjustedText(out.description) h = (fm.height() * 1.2) * (i + 1) h = h + ModelerGraphicItem.BOX_HEIGHT / 2.0 pt = QtCore.QPointF( -(ModelerGraphicItem.BOX_WIDTH) / 2 + 33, h) painter.drawText(pt, text) i += 1 if self.pixmap: painter.drawPixmap(-(ModelerGraphicItem.BOX_WIDTH / 2.0) + 3, -8, self.pixmap)
def paint(self, painter, option, widget=None): rect = QtCore.QRectF(-(ModelerGraphicItem.BOX_WIDTH + 2) / 2.0, -(ModelerGraphicItem.BOX_HEIGHT + 2) / 2.0, ModelerGraphicItem.BOX_WIDTH + 2, ModelerGraphicItem.BOX_HEIGHT + 2) painter.setPen(QtGui.QPen(QtCore.Qt.gray, 1)) color = QtGui.QColor(125, 232, 232) if isinstance(self.element, ModelerParameter): color = QtGui.QColor(179, 179, 255) elif isinstance(self.element, Algorithm): color = QtCore.Qt.white painter.setBrush(QtGui.QBrush(color, QtCore.Qt.SolidPattern)) painter.drawRect(rect) font = QtGui.QFont('Verdana', 8) painter.setFont(font) painter.setPen(QtGui.QPen(QtCore.Qt.black)) text = self.getAdjustedText(self.text) if isinstance(self.element, Algorithm) and not self.element.active: painter.setPen(QtGui.QPen(QtCore.Qt.gray)) text = text + "\n(deactivated)" elif self.isSelected(): painter.setPen(QtGui.QPen(QtCore.Qt.blue)) fm = QtGui.QFontMetricsF(font) text = self.getAdjustedText(self.text) h = fm.height() pt = QtCore.QPointF(-ModelerGraphicItem.BOX_WIDTH / 2 + 25, h / 2.0) painter.drawText(pt, text) painter.setPen(QtGui.QPen(QtCore.Qt.black)) if isinstance(self.element, Algorithm): h = -(fm.height() * 1.2) h = h - ModelerGraphicItem.BOX_HEIGHT / 2.0 + 5 pt = QtCore.QPointF(-ModelerGraphicItem.BOX_WIDTH / 2 + 25, h) painter.drawText(pt, 'In') i = 1 if not self.element.paramsFolded: for param in self.element.algorithm.parameters: if not param.hidden: text = self.getAdjustedText(param.description) h = -(fm.height() * 1.2) * (i + 1) h = h - ModelerGraphicItem.BOX_HEIGHT / 2.0 + 5 pt = QtCore.QPointF( -ModelerGraphicItem.BOX_WIDTH / 2 + 33, h) painter.drawText(pt, text) i += 1 h = fm.height() * 1.2 h = h + ModelerGraphicItem.BOX_HEIGHT / 2.0 pt = QtCore.QPointF(-ModelerGraphicItem.BOX_WIDTH / 2 + 25, h) painter.drawText(pt, 'Out') if not self.element.outputsFolded: for i, out in enumerate(self.element.algorithm.outputs): text = self.getAdjustedText(out.description) h = fm.height() * 1.2 * (i + 2) h = h + ModelerGraphicItem.BOX_HEIGHT / 2.0 pt = QtCore.QPointF(-ModelerGraphicItem.BOX_WIDTH / 2 + 33, h) painter.drawText(pt, text) if self.pixmap: painter.drawPixmap(-(ModelerGraphicItem.BOX_WIDTH / 2.0) + 3, -8, self.pixmap)
def reposition(self): fm = QtGui.QFontMetricsF(self._font, self) rect = fm.boundingRect(QtCore.QRectF(self.rect()), QtCore.Qt.AlignCenter, str(self._value)) self._xpos = -rect.width()/2.0 self._ypos = rect.height()/2.0 - fm.descent() self.update()
def rescale(self): fm = QtGui.QFontMetricsF(self._font, self) maxRect = fm.boundingRect(QtCore.QRectF(self.rect()), QtCore.Qt.AlignCenter, str(self._maximum)) xscale = float(self.width())/maxRect.width() yscale = float(self.height())/maxRect.height() self._scale = min(xscale, yscale)
def addClassToLegend(self, theColour, theMin=None, theMax=None, theCategory=None, theLabel=None): """Add a class to the current legend. If the legend is not defined, a new one will be created. A legend is just an image file with nicely rendered classes in it. Args: * theColour - **Required** colour for the class as a QColor * theMin - Optional minimum value for the class * theMax - Optional maximum value for the class\ * theCategory - Optional category name (will be used in lieu of min/max) * theLabel - Optional text label for the class Returns: None Raises: Throws an exception if the class could not be added for some reason.. """ LOGGER.debug('InaSAFE Map Legend addClassToLegend called') self.extendLegend() myOffset = self.legendImage.height() - self.legendIncrement myPainter = QtGui.QPainter(self.legendImage) myBrush = QtGui.QBrush(theColour) myPainter.setBrush(myBrush) myPainter.setPen(theColour) myWhitespace = 2 # white space above and below each class icon mySquareSize = self.legendIncrement - (myWhitespace * 2) myLeftIndent = 10 myPainter.drawRect( QtCore.QRectF(myLeftIndent, myOffset + myWhitespace, mySquareSize, mySquareSize)) myPainter.setPen(QtGui.QColor(0, 0, 0)) # outline colour myLabelX = myLeftIndent + mySquareSize + 10 myFontWeight = QtGui.QFont.Normal myItalicsFlag = False myFont = QtGui.QFont('verdana', self.legendFontSize, myFontWeight, myItalicsFlag) myFontMetrics = QtGui.QFontMetricsF(myFont, self.legendImage) myFontHeight = myFontMetrics.height() myCenterVerticalPadding = (self.legendIncrement - myFontHeight) / 2 myExtraVerticalSpace = 8 # hack to get label centered on graphic myOffset += myCenterVerticalPadding + myExtraVerticalSpace myPainter.setFont(myFont) myLabel = '' if theLabel: myLabel = theLabel if theMin is not None and theMax is not None: myLabel += ' [' + str(theMin) + ', ' + str(theMax) + ']' if theCategory is not None: myLabel = ' (' + theCategory + ')' myPainter.drawText(myLabelX, myOffset + 25, myLabel)
def drawLogo(self): self.painter.save() self.painter.setPen(self.foreground) self.painter.setBrush(self.foreground) logostr = QString(self.logo) fm = QtGui.QFontMetricsF(self.font()) w = fm.size(Qt.TextSingleLine, logostr).width() self.painter.drawText(-w / 2, -30, logostr) self.painter.restore()
def boundingRect(self): font = QtGui.QFont("Verdana", 8) fm = QtGui.QFontMetricsF(font) numParams = 0 if self.inputFolded else len(self.element.parameters) numOutputs = 0 if self.outputFolded else len(self.element.outputs) numElements = numParams + numOutputs + 3 h = (fm.height() * 1.2) * numElements rect = QtCore.QRectF(-(ModelerGraphicItem.BOX_WIDTH + 2)/2, -(ModelerGraphicItem.BOX_HEIGHT + 2)/2, ModelerGraphicItem.BOX_WIDTH + 2, ModelerGraphicItem.BOX_HEIGHT + h) return rect
def buildCommentSize(self, comment): if not comment: self.commentSize = QtCore.QSize() return fontMetrics = QtGui.QFontMetricsF(self.titleFont) lineHeight = fontMetrics.lineSpacing() width = fontMetrics.width(comment) lines = math.ceil(width/100) self.commentSize = QtCore.QSize(100, (fontMetrics.lineSpacing()*lines - fontMetrics.leading()))
def boundingRect(self): font = QtGui.QFont('Verdana', 8) fm = QtGui.QFontMetricsF(font) numParams = (0 if self.inputFolded else len(self.element.parameters)) numOutputs = (0 if self.outputFolded else len(self.element.outputs)) hUp = fm.height() * 1.2 * (numParams + 2) hDown = fm.height() * 1.2 * (numOutputs + 2) rect = QtCore.QRectF(-(ModelerGraphicItem.BOX_WIDTH + 2) / 2, -(ModelerGraphicItem.BOX_HEIGHT + 2) / 2 - hUp, ModelerGraphicItem.BOX_WIDTH + 2, ModelerGraphicItem.BOX_HEIGHT + hDown + hUp) return rect
def polygon(self): font = QtGui.QFont("Verdana", 8) fm = QtGui.QFontMetricsF(font) numElements = len(self.element.parameters) + len(self.element.outputs) + 3 h = (fm.height() * 1.2) * numElements pol = QtGui.QPolygonF([ QtCore.QPointF(-(ModelerGraphicItem.BOX_WIDTH + 2)/2, -(ModelerGraphicItem.BOX_HEIGHT + 2)/2), QtCore.QPointF(-(ModelerGraphicItem.BOX_WIDTH + 2)/2, (ModelerGraphicItem.BOX_HEIGHT + 2)/2 + h), QtCore.QPointF((ModelerGraphicItem.BOX_WIDTH + 2)/2, (ModelerGraphicItem.BOX_HEIGHT + 2)/2 + h), QtCore.QPointF((ModelerGraphicItem.BOX_WIDTH + 2)/2, -(ModelerGraphicItem.BOX_HEIGHT + 2)/2), QtCore.QPointF(-(ModelerGraphicItem.BOX_WIDTH + 2)/2, -(ModelerGraphicItem.BOX_HEIGHT + 2)/2)]) return pol
def getAdjustedText(self, text): font = QtGui.QFont("Verdana", 8) fm = QtGui.QFontMetricsF(font) w = fm.width(text) if w < self.BOX_WIDTH - 25 - FlatButtonGraphicItem.WIDTH: return text text = text[0:-3] + "..." w = fm.width(text) while (w > self.BOX_WIDTH - 25 - FlatButtonGraphicItem.WIDTH): text = text[0:-4] + "..." w = fm.width(text) return text
def getLinkPointForParameter(self, paramIndex): offsetX = 25 if self.inputFolded: paramIndex = -1 offsetX = 17 font = QtGui.QFont("Verdana", 8) fm = QtGui.QFontMetricsF(font) if isinstance(self.element, GeoAlgorithm): h = -(fm.height() * 1.2) * (paramIndex + 2) - fm.height() / 2.0 + 8 h = h - ModelerGraphicItem.BOX_HEIGHT / 2.0 else: h = 0 return QtCore.QPointF(-(ModelerGraphicItem.BOX_WIDTH) / 2 + offsetX, h)
def getLinkPointForOutput(self, outputIndex): if isinstance(self.element, GeoAlgorithm): numParams = 0 if self.inputFolded else len(self.element.parameters) outputIndex = outputIndex if not self.outputFolded else -1 text = self.getAdjustedText(self.element.outputs[outputIndex].description) font = QtGui.QFont("Verdana", 8) fm = QtGui.QFontMetricsF(font) w = fm.width(QtCore.QString(text)) h = (fm.height() * 1.2) * (outputIndex + 3 + numParams) - fm.height() / 2.0 y = h + ModelerGraphicItem.BOX_HEIGHT / 2.0 + 2 x = -(ModelerGraphicItem.BOX_WIDTH)/2 + 33 + w + 5 if not self.outputFolded else 10 return QtCore.QPointF(x, y) else: return QtCore.QPointF(0, 0)
def drawProposition(self, proposition): ## DEBUG #print(">> drawProposition", proposition) if self.squareSizeOld != self.squareSize: self.calcOffset(self.size()) self.lastProposition = proposition self.image.fill(self.BG_COLOR) painter = QtGui.QPainter(self.image) ## draw bounding square painter.setPen(QtGui.QPen(QtCore.Qt.black)) painter.setBrush(QtGui.QColor(255, 255, 255, 255)) a = self.squareSize * self.squareScale painter.drawRect(self.squareOffset.x(), self.squareOffset.y(), a, a) # draw square size font = QtGui.QFont() font.setPointSizeF(12) metrics = QtGui.QFontMetricsF(font) painter.setFont(font) text = "size: " + str(self.squareSize) rect = metrics.boundingRect(text) painter.drawText(self.image.width() - rect.width(), self.image.height(), text) ## draw proposition squares if proposition != None: color = QtGui.QColor() random.seed(4) for x, y, a in re.findall('\( *(\d+) *, *(\d+) *, *(\d+) *\)', proposition): text = str(a) x = int(x) * self.squareScale + self.squareOffset.x() y = int(y) * self.squareScale + self.squareOffset.y() a = int(a) * self.squareScale color.setHsv( random.randrange(0, 360, 20), # hue random.randrange(190, 250, 30), # saturation random.randrange(160, 220, 30), # value 190) # alpha painter.setBrush(color) painter.setPen(QtGui.QPen(QtCore.Qt.black)) painter.drawRect(x, y, a, a) fontRect = metrics.boundingRect(text) painter.setPen(QtGui.QPen(QtCore.Qt.white)) painter.drawText(x - (fontRect.width() - a) / 2 - 1, y + (fontRect.height() + a) / 2 - 3, text) self.update()
def __init__(self, layoutInfo): """Set up a QFont object and initialize instance values. 'layoutInfo' is a dictionary containing the required info """ # Now it's a little complicated because the font needs to have a # special platform independent resolution/size. As Qt4 does # font metrics based on the display device resolution, we need # to know what that is. So a QFont is constructed based on a # QPicture, whose resolution can then be read. At first I # tried using QPrinter as the device, but this didn't work on # a Windows computer without a printer. global QP, fontscale if not QP: QP = QtGui.QPicture() # This was the first attempt, and worked well within one # platform, but on Linux there seems to be some inaccuracy # in the point size(!?) # res = QP.logicalDpiX() # fontscale = float(RESOLUTION) / res # This seems to help the inconsistency of font sizes # between Windows and Linux. It's not perfect, but # that may be impossible to attain. qf = QtGui.QFont() qf.setPointSize(1000) poi = QtGui.QFontInfo(qf).pointSizeF() qf.setPixelSize(1000) pix = QtGui.QFontInfo(qf).pointSizeF() fontscale = float(RESOLUTION) * pix / poi / 72 family = layoutInfo[u"family"] QtGui.QFont.__init__(self, family) self.setPointSizeF(float(layoutInfo[u"points"]) * fontscale) self.setWeight(int(layoutInfo[u"weight"])) self.setStretch(int(float(layoutInfo[u"stretch"]) * 100)) self.setItalic(layoutInfo[u"style"] == u"1") self.setUnderline(layoutInfo[u"underline"] == u"1") self.metric = QtGui.QFontMetricsF(self, QP) self.spWidth = self.getWidth(u" ") self.lineSpacing = self.metric.lineSpacing() * pts2mm \ * float(layoutInfo[u"lineSpacing"]) self.colour = getColour(layoutInfo[u"colour"]) # Check whether the desired font was chosen fi = QtGui.QFontInfo(self) if (fi.family() != self.family()): warning(_("Font not available: '%s'") % family)
def drawNumbericValue(self): self.painter.save() color = QtGui.QColor(150, 150, 200) pen = self.painter.pen() pen.setWidth(3) self.painter.setPen(pen) self.painter.setPen(color) self.painter.drawRect(-30, 30, 60, 14) cpustr = QString("%1").arg(self.value) fm = QtGui.QFontMetricsF(self.font()) w = fm.size(Qt.TextSingleLine, cpustr).width() self.painter.setPen(self.foreground) self.painter.drawText(-w / 2, 42, cpustr) self.painter.restore()
def boundingRect(self): font = QtGui.QFont('Verdana', 8) fm = QtGui.QFontMetricsF(font) unfolded = isinstance(self.element, Algorithm) and not self.element.paramsFolded numParams = len(self.element.algorithm.parameters) if unfolded else 0 unfolded = isinstance(self.element, Algorithm) and not self.element.outputsFolded numOutputs = len(self.element.algorithm.outputs) if unfolded else 0 hUp = fm.height() * 1.2 * (numParams + 2) hDown = fm.height() * 1.2 * (numOutputs + 2) rect = QtCore.QRectF(-(ModelerGraphicItem.BOX_WIDTH + 2) / 2, -(ModelerGraphicItem.BOX_HEIGHT + 2) / 2 - hUp, ModelerGraphicItem.BOX_WIDTH + 2, ModelerGraphicItem.BOX_HEIGHT + hDown + hUp) return rect
def getLinkPointForOutput(self, outputIndex): if isinstance(self.element, Algorithm): outputIndex = (outputIndex if not self.element.outputsFolded else -1) text = self.getAdjustedText( self.element.algorithm.outputs[outputIndex].description) font = QtGui.QFont('Verdana', 8) fm = QtGui.QFontMetricsF(font) w = fm.width(text) h = fm.height() * 1.2 * (outputIndex + 1) + fm.height() / 2.0 y = h + ModelerGraphicItem.BOX_HEIGHT / 2.0 + 5 x = (-ModelerGraphicItem.BOX_WIDTH / 2 + 33 + w + 5 if not self.element.outputsFolded else 10) return QtCore.QPointF(x, y) else: return QtCore.QPointF(0, 0)
def buildDisplayName(self, name): p = re.compile(r'([A-Z]*[a-z0-9]*_*~*)') nameList = p.findall(name) partLength = 0 self.displayName = '' fontMetrics = QtGui.QFontMetricsF(self.titleFont) for i, part in enumerate(nameList): self.displayName += part partLength += len(part) if partLength > 13: self.displayName += '\n' partLength = 0 self.displayName = self.displayName.strip() nLine = self.displayName.count('\n')+1 self.fontSize = fontMetrics.size(QtCore.Qt.TextSingleLine, self.name) self.lineHeight = fontMetrics.height() self.fontSize.setHeight((fontMetrics.lineSpacing()*nLine - fontMetrics.leading()))
def drawForeground(self, painter, rect): print "In drawForeground:" print rect.x(), rect.y() axisOffset = 10 right = self.width() - 2 * axisOffset bottom = self.height() - 2 * axisOffset painter.setWorldMatrixEnabled(False) painter.setRenderHint(QtGui.QPainter.Antialiasing) painter.setPen(self.axisPen) painter.setFont(self.axisFont) painter.drawRect(axisOffset, axisOffset, right, bottom) painter.drawText(axisOffset + 2, bottom + axisOffset - 2, str(self.xSpan)) s = str(self.ySpan) painter.drawText( right - QtGui.QFontMetricsF(self.axisFont).width(s) + 8, axisOffset + self.axisFontHeight - 3, s)
def polygon(self): font = QtGui.QFont("Verdana", 8) fm = QtGui.QFontMetricsF(font) hUp = (fm.height() * 1.2) * (len(self.element.parameters) + 2) hDown = (fm.height() * 1.2) * (len(self.element.outputs) + 2) pol = QtGui.QPolygonF([ QtCore.QPointF(-(ModelerGraphicItem.BOX_WIDTH + 2) / 2, -(ModelerGraphicItem.BOX_HEIGHT + 2) / 2 - hUp), QtCore.QPointF(-(ModelerGraphicItem.BOX_WIDTH + 2) / 2, (ModelerGraphicItem.BOX_HEIGHT + 2) / 2 + hDown), QtCore.QPointF((ModelerGraphicItem.BOX_WIDTH + 2) / 2, (ModelerGraphicItem.BOX_HEIGHT + 2) / 2 + hDown), QtCore.QPointF((ModelerGraphicItem.BOX_WIDTH + 2) / 2, -(ModelerGraphicItem.BOX_HEIGHT + 2) / 2 - hUp), QtCore.QPointF(-(ModelerGraphicItem.BOX_WIDTH + 2) / 2, -(ModelerGraphicItem.BOX_HEIGHT + 2) / 2 - hUp) ]) return pol
def drawScaleNum(self): self.painter.save() self.painter.setPen(self.foreground) startRad = (360 - self.startAngle - 90) * (3.14 / 180) deltaRad = (360 - self.startAngle - self.endAngle) * (3.14 / 180) / self.scaleMajor fm = QtGui.QFontMetricsF(self.font()) for i in xrange(self.scaleMajor + 1): sina = sin(startRad - i * deltaRad) cosa = cos(startRad - i * deltaRad) tmpVal = 1.0 * i * ((self.maxValue - self.minValue) / self.scaleMajor) + self.minValue numstr = QString("%1").arg(tmpVal) w = fm.size(Qt.TextSingleLine, numstr).width() h = fm.size(Qt.TextSingleLine, numstr).height() x = 82 * cosa - w / 2 y = -82 * sina + h / 4 self.painter.drawText(x, y, numstr) self.painter.restore()
def setTitle(self, titleStr): lines = [] currentSize = [] font = self.title.font() fontm = QtGui.QFontMetricsF(font) maxWidth = self.title.width() words = titleStr.split(' ') for i in range(2): lines.append('') currentSize.append(0) for word in words[:]: newSize = currentSize[i] + fontm.width(word) + fontm.width(' ') if newSize < maxWidth: del words[0] lines[i] += word + ' ' currentSize[i] = newSize else: break title = '\n'.join(lines) + ('...' if words else '') self.title.setText(title)
def add_class(self, colour, minimum=None, maximum=None, category=None, label='', class_type=None): """Add a class to the current legend. If the legend is not defined, a new one will be created. A legend is just an image file with nicely rendered classes in it. :param colour: Colour for the class. :type colour: QColor :param minimum: Minimum value for the class. :type minimum: float, int :param maximum: Maximum value for the class. :type maximum: float, int :param category: Category name (will be used in lieu of min/max) :type category: str :param label: Text label for the class. :type label: str :param class_type: One of 'singleSymbol', 'categorizedSymbol', 'graduatedSymbol' or 'rasterStyle' :type class_type: str """ LOGGER.debug('InaSAFE Map Legend addClassToLegend called') self.grow_legend() offset = self.legend_image.height() - self.legend_increment painter = QtGui.QPainter(self.legend_image) brush = QtGui.QBrush(colour) painter.setBrush(brush) painter.setPen(colour) whitespace = 2 # white space above and below each class icon square_size = self.legend_increment - (whitespace * 2) left_indent = 10 painter.drawRect( QtCore.QRectF(left_indent, offset + whitespace, square_size, square_size)) painter.setPen(QtGui.QColor(0, 0, 0)) # outline colour label_x = left_indent + square_size + 10 font_weight = QtGui.QFont.Normal italics_flag = False font = QtGui.QFont('verdana', self.legend_font_size, font_weight, italics_flag) font_metrics = QtGui.QFontMetricsF(font, self.legend_image) font_height = font_metrics.height() center_vertical_padding = (self.legend_increment - font_height) / 2 extra_vertical_space = 8 # hack to get label centered on graphic offset += center_vertical_padding + extra_vertical_space painter.setFont(font) LOGGER.debug('label' + str(label)) LOGGER.debug('minimum ' + str(minimum)) LOGGER.debug('maximum ' + str(maximum)) LOGGER.debug('category ' + str(category)) if label is not None and label != '': pass else: # branches for each style type if class_type == 'singleSymbol': LOGGER.debug('singleSymbol is not impelemented yet') elif class_type == 'categorizedSymbol': if category is not None or category == '': label = str(category) elif (class_type == 'graduatedSymbol' or class_type == 'rasterStyle'): # can be a problem if the min and maximum is not found if minimum is None or maximum is None: LOGGER.debug('Problem caused minimum or maximum is not ' 'found') return else: if float(minimum) - int(minimum) == 0.0: min_string = '%i' % minimum else: min_string = str(minimum) if float(maximum) - int(maximum) == 0.0: max_string = '%i' % maximum else: max_string = str(maximum) label += '[' + min_string + ', ' + max_string + ']' if float(str(minimum)) == float(str(maximum)): # pass because it's not needed return painter.drawText(label_x, offset + 25, label)
def addClassToLegend(self, theColour, theMin=None, theMax=None, theCategory=None, theLabel='', theType=None): """Add a class to the current legend. If the legend is not defined, a new one will be created. A legend is just an image file with nicely rendered classes in it. Args: * theColour - **Required** colour for the class as a QColor * theMin - Optional minimum value for the class * theMax - Optional maximum value for the class\ * theCategory - Optional category name (will be used in lieu of min/max) * theLabel - Optional text label for the class Returns: None Raises: Throws an exception if the class could not be added for some reason.. """ LOGGER.debug('InaSAFE Map Legend addClassToLegend called') self.extendLegend() myOffset = self.legendImage.height() - self.legendIncrement myPainter = QtGui.QPainter(self.legendImage) myBrush = QtGui.QBrush(theColour) myPainter.setBrush(myBrush) myPainter.setPen(theColour) myWhitespace = 2 # white space above and below each class icon mySquareSize = self.legendIncrement - (myWhitespace * 2) myLeftIndent = 10 myPainter.drawRect( QtCore.QRectF(myLeftIndent, myOffset + myWhitespace, mySquareSize, mySquareSize)) myPainter.setPen(QtGui.QColor(0, 0, 0)) # outline colour myLabelX = myLeftIndent + mySquareSize + 10 myFontWeight = QtGui.QFont.Normal myItalicsFlag = False myFont = QtGui.QFont('verdana', self.legendFontSize, myFontWeight, myItalicsFlag) myFontMetrics = QtGui.QFontMetricsF(myFont, self.legendImage) myFontHeight = myFontMetrics.height() myCenterVerticalPadding = (self.legendIncrement - myFontHeight) / 2 myExtraVerticalSpace = 8 # hack to get label centered on graphic myOffset += myCenterVerticalPadding + myExtraVerticalSpace myPainter.setFont(myFont) LOGGER.debug('theLabel' + str(theLabel)) LOGGER.debug('theMin ' + str(theMin)) LOGGER.debug('theMax ' + str(theMax)) LOGGER.debug('theCategory ' + str(theCategory)) if theLabel is not None and theLabel != '': pass else: # branches for each style type if theType == 'singleSymbol': LOGGER.debug('singleSymbol is not impelemented yet') elif theType == 'categorizedSymbol': if theCategory is not None or theCategory == '': theLabel = str(theCategory) elif theType == 'graduatedSymbol' or theType == 'rasterStyle': # can be a problem if the min and theMax is not found if theMin is None or theMax is None: LOGGER.debug('Problem caused theMin or theMax is not ' 'found') return else: if float(theMin) - int(theMin) == 0.0: myMinString = '%i' % theMin else: myMinString = str(theMin) if float(theMax) - int(theMax) == 0.0: myMaxString = '%i' % theMax else: myMaxString = str(theMax) theLabel += '[' + myMinString + ', ' + myMaxString + ']' if float(str(theMin)) == float(str(theMax)): # pass because it's not needed return myPainter.drawText(myLabelX, myOffset + 25, theLabel)
def add_class(self, colour, minimum=None, maximum=None, category=None, label='', class_type=None): """Add a class to the current legend. If the legend is not defined, a new one will be created. A legend is just an image file with nicely rendered classes in it. :param colour: Colour for the class. :type colour: QColor :param minimum: Minimum value for the class. :type minimum: float, int :param maximum: Maximum value for the class. :type maximum: float, int :param category: Category name (will be used in lieu of min/max) :type category: str :param label: Text label for the class. :type label: str :param class_type: One of 'singleSymbol', 'categorizedSymbol', 'graduatedSymbol' or 'rasterStyle' :type class_type: str """ LOGGER.debug('InaSAFE Map Legend addClassToLegend called') self.grow_legend() myOffset = self.legendImage.height() - self.legendIncrement myPainter = QtGui.QPainter(self.legendImage) myBrush = QtGui.QBrush(colour) myPainter.setBrush(myBrush) myPainter.setPen(colour) myWhitespace = 2 # white space above and below each class icon mySquareSize = self.legendIncrement - (myWhitespace * 2) myLeftIndent = 10 myPainter.drawRect( QtCore.QRectF(myLeftIndent, myOffset + myWhitespace, mySquareSize, mySquareSize)) myPainter.setPen(QtGui.QColor(0, 0, 0)) # outline colour myLabelX = myLeftIndent + mySquareSize + 10 myFontWeight = QtGui.QFont.Normal myItalicsFlag = False myFont = QtGui.QFont('verdana', self.legendFontSize, myFontWeight, myItalicsFlag) myFontMetrics = QtGui.QFontMetricsF(myFont, self.legendImage) myFontHeight = myFontMetrics.height() myCenterVerticalPadding = (self.legendIncrement - myFontHeight) / 2 myExtraVerticalSpace = 8 # hack to get label centered on graphic myOffset += myCenterVerticalPadding + myExtraVerticalSpace myPainter.setFont(myFont) LOGGER.debug('label' + str(label)) LOGGER.debug('minimum ' + str(minimum)) LOGGER.debug('maximum ' + str(maximum)) LOGGER.debug('category ' + str(category)) if label is not None and label != '': pass else: # branches for each style type if class_type == 'singleSymbol': LOGGER.debug('singleSymbol is not impelemented yet') elif class_type == 'categorizedSymbol': if category is not None or category == '': label = str(category) elif class_type == 'graduatedSymbol' or class_type == 'rasterStyle': # can be a problem if the min and maximum is not found if minimum is None or maximum is None: LOGGER.debug('Problem caused minimum or maximum is not ' 'found') return else: if float(minimum) - int(minimum) == 0.0: myMinString = '%i' % minimum else: myMinString = str(minimum) if float(maximum) - int(maximum) == 0.0: myMaxString = '%i' % maximum else: myMaxString = str(maximum) label += '[' + myMinString + ', ' + myMaxString + ']' if float(str(minimum)) == float(str(maximum)): # pass because it's not needed return myPainter.drawText(myLabelX, myOffset + 25, label)