Example #1
0
    def drawIconWithShadow(icon, rect, p, iconMode, radius, color, offset):
        cache = QPixmap()
        pixmapName = "icon {0} {1} {2}".format(icon.cacheKey(), iconMode, rect.height())

        if not QPixmapCache.find(pixmapName, cache):
            px = icon.pixmap(rect.size())
            cache = QPixmap(px.size() + QSize(radius * 2, radius * 2))
            cache.fill(Qt.transparent)

            cachePainter = QPainter(cache)
            if iconMode == QIcon.Disabled:
                im = px.toImage().convertToFormat(QImage.Format_ARGB32)
                for y in range(im.height()):
                    scanLine = im.scanLine(y)
                    for x in range(im.width()):
                        pixel = scanLine
                        intensity = qGray(pixel)
                        scanLine = qRgba(intensity, intensity, intensity, qAlpha(pixel))
                        scanLine += 1
                px = QPixmap.fromImage(im)

            # Draw shadow
            tmp = QImage(px.size() + QSize(radius * 2, radius * 2 + 1), QImage.Format_ARGB32_Premultiplied)
            tmp.fill(Qt.transparent)

            tmpPainter = QPainter(tmp)
            tmpPainter.setCompositionMode(QPainter.CompositionMode_Source)
            tmpPainter.drawPixmap(QPoint(radius, radius), px)
            tmpPainter.end()

            # blur the alpha channel
            blurred = QImage(tmp.size(), QImage.Format_ARGB32_Premultiplied)
            blurred.fill(Qt.transparent)
            blurPainter = QPainter(blurred)
            # todo : blur image
            blurPainter.end()

            tmp = blurred

            # blacken the image
            tmpPainter.begin(tmp)
            tmpPainter.setCompositionMode(QPainter.CompositionMode_SourceIn)
            tmpPainter.fillRect(tmp.rect(), color)
            tmpPainter.end()

            tmpPainter.begin(tmp)
            tmpPainter.setCompositionMode(QPainter.CompositionMode_SourceIn)
            tmpPainter.fillRect(tmp.rect(), color)
            tmpPainter.end()

            # draw the blurred drop shadow...
            cachePainter.drawImage(QRect(0, 0, cache.rect().width(), cache.rect().height()), tmp)

            # Draw the actual pixmap...
            cachePainter.drawPixmap(QPoint(radius, radius) + offset, px)
            QPixmapCache.insert(pixmapName, cache)

        targetRect = cache.rect()
        targetRect.moveCenter(rect.center())
        p.drawPixmap(targetRect.topLeft() - offset, cache)
Example #2
0
    def requestImage(self, name, rsize, size):
        """@reimp @public
    @param[in]  providerId  unicode  unused
    @param[out]  rsize  QSize
    @param[in]  size  QSize
    @return  QImage not None

    virtual QImage requestImage(const QString &id, QSize *size, const QSize &requestedSize)
    """
        ret = QImage(rc.image_path(name))
        if ret.isNull():
            derror("failed to load image: '%s'" % name)
        elif ret.size() != size:
            ret = (
                ret.scaled(size, Qt.KeepAspectRatio, Qt.SmoothTransformation)
                if not size.isEmpty() else ret.scaledToWidth(
                    size.width(), Qt.SmoothTransformation) if size.width() > 0
                else ret.scaledToHeight(size.height(), Qt.SmoothTransformation)
                if size.height() > 0 else ret)
        rsize.setWidth(ret.width())
        rsize.setHeight(ret.height())
        return ret
class CircuitItem(QGraphicsItem):
    """Graphical wrapper around the engine Circuit class."""

    textH = 12
    """Height of text."""
    ioH = 20
    """Height between to I/O pins."""
    ioW = 15
    """Length of I/O pins."""
    radius = 10
    """Radius of I/O pin heads."""

    def __init__(self, circuit):
        super(CircuitItem, self).__init__()
        self.setFlag(QGraphicsItem.ItemIsMovable)
        self.setFlag(QGraphicsItem.ItemIsSelectable)
        self.setFlag(QGraphicsItem.ItemSendsGeometryChanges)
        imgDir = filePath('icons/')
        self.data = circuit
        """The real info. The class CircuitItem is just a graphical container
        around it. data is saved / loaded to / from file.
        """
        self.image = QImage(imgDir + circuit.__class__.__name__ + '.png')
        """The graphical representation of our item on screen."""
        if not self.image:
            self.image = QImage(imgDir + 'Default.png')
            self.showCategory = True
        self.showName = True
        """Is the item's name shown on screen?"""
        self.showCategory = False
        """Is the item's category (circuit class) shown on screen?"""
        self.name = QGraphicsSimpleTextItem(self)
        # that won't rotate when the PlugItem is rotated by the user.
        self.name.setFlag(QGraphicsItem.ItemIgnoresTransformations)
        self.name.setText(self.data.name)
        self.category = QGraphicsSimpleTextItem(self)
        self.category.setFlag(QGraphicsItem.ItemIgnoresTransformations)
        self.category.setText(self.data.category)
        self.setupPaint()

    def boundingRect(self):
        """Qt requires overloading this when overloading QGraphicsItem."""
        W = 2 * self.radius + 2 * self.ioW + self.imgW
        ni = self.data.nb_inputs()
        no = self.data.nb_outputs()
        t = (1 - int(max(ni, no) / 2)) * self.ioH - self.radius / 2
        b = (1 + int(max(ni, no) / 2)) * self.ioH + self.radius / 2
        return (
            QRectF(-self.ioW - self.radius, t, W, b - t) if max(ni, no) > 1
            else QRectF(-self.ioW - self.radius, 0, W, self.image.height()))

    def handleAtPos(self, pos):
        """Is there an interactive handle where the mouse is? Return it."""
        for i in range(self.nIn):
            if self.inputPaths[i].contains(pos):
                return self.data.inputList[i]
        for i in range(self.nOut):
            if self.outputPaths[i].contains(pos):
                return self.data.outputList[i]

    def itemChange(self, change, value):
        """Warning view it will soon have to correct pos."""
        if change == QGraphicsItem.ItemPositionHasChanged:
            # Restart till we stop moving.
            self.scene().views()[0].timer.start()
        return QGraphicsItem.itemChange(self, change, value)

    def paint(self, painter, option, widget):
        """Draws the item."""
        painter.setPen(QPen(QColor('black'), 2))
        ni = self.data.nb_inputs()
        no = self.data.nb_outputs()
        for i in range(1 - int(ni / 2), 2 + int(ni / 2)):
            if i != 1 or ni % 2:
                painter.drawLine(-self.ioW, i * self.ioH, 0, i * self.ioH)
        for i in range(1 - int(no / 2), 2 + int(no / 2)):
            if i != 1 or no % 2:
                painter.drawLine(
                    self.imgW, i * self.ioH, self.imgW + self.ioW,
                    i * self.ioH)
        painter.drawImage(QRectF(0, 0, self.imgW, self.imgH), self.image)
        for i in range(ni):
            painter.drawPath(self.inputPaths[i])
        painter.drawLine(
            0, (1 - int(ni / 2)) * self.ioH, 0, (1 + int(ni / 2)) * self.ioH)
        for i in range(no):
            painter.drawPath(self.outputPaths[i])
        painter.drawLine(
            self.imgW,
            (1 - int(no / 2)) * self.ioH,
            self.imgW,
            (1 + int(no / 2)) * self.ioH)
        # Default selection box doesn't work; simple reimplementation.
        if option.state & QStyle.State_Selected:
            pen = QPen(Qt.black, 1, Qt.DashLine)
            painter.setPen(pen)
            painter.drawRect(self.boundingRect())

    def setCategoryVisibility(self, isVisible):
        """Show/Hide circuit category (mostly useful for user circuits)."""
        self.showCategory = isVisible
        self.setupPaint()

    def setNameVisibility(self, isVisible):
        """Shows/Hide the item name in the graphical view."""
        self.showName = isVisible
        self.setupPaint()

    def setNbInputs(self, nb):
        """Add/Remove inputs (for logical gates)."""
        if nb > self.data.nb_inputs():
            for x in range(nb - self.data.nb_inputs()):
                Plug(True, None, self.data)
        elif nb < self.data.nb_inputs():
            for x in range(self.data.nb_inputs() - nb):
                self.data.remove_input(self.data.inputList[0])
        self.setupPaint()

    def setupPaint(self):
        """Offscreen rather than onscreen redraw (few changes)."""
        self.nIn = self.data.nb_inputs()
        self.nOut = self.data.nb_outputs()
        # 3 sections with different heights must be aligned :
        self.imgH = self.image.size().height()   # central (png image)
        self.imgW = self.image.size().width()
        self.inH = (self.nIn - 1) * self.ioH + 2 * self.radius  # inputs
        self.outH = (self.nOut - 1) * self.ioH + 2 * self.radius    # outputs
        # therefore we calculate a vertical offset for each section :
        self.maxH = max(self.imgH, self.inH, self.outH)
        self.imgOff = (
            0 if self.maxH == self.imgH else (self.maxH - self.imgH) / 2.)
        self.inOff = (
            0 if self.maxH == self.inH else (self.maxH - self.inH) / 2.)
        self.outOff = (
            0 if self.maxH == self.outH else (self.maxH - self.outH) / 2.)
        # i/o mouseover detection. Create once, use on each mouseMoveEvent.
        self.inputPaths = []
        self.outputPaths = []
        ni = self.data.nb_inputs()
        no = self.data.nb_outputs()
        for i in range(1 - int(ni / 2), 2 + int(ni / 2)):
            if i != 1 or ni % 2:
                path = QPainterPath()
                path.addEllipse(
                    -self.ioW - self.radius, i * self.ioH - self.radius / 2,
                    self.radius, self.radius)
                self.inputPaths.append(path)
        for i in range(1 - int(no / 2), 2 + int(no / 2)):
            if i != 1 or no % 2:
                path = QPainterPath()
                path.addEllipse(
                    self.imgW + self.ioW, i * self.ioH - self.radius / 2,
                    self.radius, self.radius)
                self.outputPaths.append(path)
        self.name.setVisible(self.showName)
        self.category.setVisible(self.showCategory)
        if self.showName or self.showCategory:
            br = self.mapToScene(self.boundingRect())
            w = self.boundingRect().width()
            h = self.boundingRect().height()
            realX = min([i.x() for i in br])
            realY = min([i.y() for i in br])
            firstY = realY + (w if self.rotation() % 180 else h) + 1
            secondY = firstY + self.textH
            if self.showName:
                self.name.setBrush(QColor('red'))
                self.name.setText(self.data.name)
                self.name.setPos(self.mapFromScene(realX, firstY))
            if self.showCategory:
                self.category.setBrush(QColor('green'))
                self.category.setText(
                    self.data.category if self.data.category
                    else self.data.__class__.__name__)
                self.category.setPos(self.mapFromScene(
                    realX, secondY if self.showName else firstY))
        self.prepareGeometryChange()    # Must be called (cf Qt doc)
        self.update()       # Force onscreen redraw after changes.
Example #4
0
from PySide.QtCore import QCoreApplication
from PySide.QtGui import QImage

if __name__ == "__main__":
    app = QCoreApplication([])
    img = QImage("lenna.png")
    w, h = img.size().width(), img.size().width()
    for p in ((x, y) for x in range(w) for y in range(h)):
        colour = img.pixel(p[0], p[1])  # AARRGGBB
        r = (colour >> 16) & 0xFF
        g = (colour >> 8)  & 0xFF
        b =  colour        & 0xFF
        avg = round((r + g + b) / 3)    # Naïve method (no colour weighting)
        new_colour = 0xff000000 + (avg << 16) + (avg << 8) + avg
        img.setPixel(p[0], p[1], new_colour)
    img.save("output.png")
Example #5
0
from PySide.QtCore import QCoreApplication
from PySide.QtGui import QImage

if __name__ == "__main__":
    app = QCoreApplication([])
    img = QImage("lenna.png")
    w, h = img.size().width(), img.size().width()
    for p in ((x, y) for x in range(w) for y in range(h)):
        colour = img.pixel(p[0], p[1])  # AARRGGBB
        r = (colour >> 16) & 0xFF
        g = (colour >> 8) & 0xFF
        b = colour & 0xFF
        avg = round((r + g + b) / 3)  # Naïve method (no colour weighting)
        new_colour = 0xff000000 + (avg << 16) + (avg << 8) + avg
        img.setPixel(p[0], p[1], new_colour)
    img.save("output.png")