Beispiel #1
0
    def _draw_horizontal_ruler(self, painter, text, y_value, color):

        y = y_value * self.y_factor

        pen = QPen()
        pen.setCapStyle(Qt.SquareCap)
        pen.setColor(color)

        qp = QPainterPath()

        r = QRect(1,1,1000,1000)
        bb = painter.boundingRect(r,Qt.AlignLeft,text)
        bb = QRect(self.x_base,self.y_base - y - bb.height(), bb.width() + 2, bb.height())

        # print("{} {} {} {}".format(bb.x(),bb.y(),bb.width(),bb.height()))

        fill_color = QColor(0,0,0)
        fill_color.setAlpha(128)
        brush = QBrush(fill_color)

        painter.fillRect(bb,brush)

        qp.moveTo(self.x_base,self.y_base - y)
        qp.lineTo(self.total_width + self.x_base, self.y_base - y)

        painter.setPen(pen)
        painter.drawPath(qp)

        text_pen = QPen()
        text_pen.setCapStyle(Qt.RoundCap)
        text_pen.setColor(color) # alpha=255=fully opaque
        text_pen.setWidth(1)

        painter.setPen(text_pen)
        painter.drawText(self.x_base,self.y_base - y - 5,text)
Beispiel #2
0
    def _draw_box_under_text(self,painter,x,y,text):
        r = QRect(1,1,1000,1000)
        bb = painter.boundingRect(r,Qt.AlignLeft,text)
        bb = QRect(x,y - bb.height() +2 , bb.width() + 2, bb.height())

        # print("{} {} {} {}".format(bb.x(),bb.y(),bb.width(),bb.height()))

        fill_color = QColor(0,0,0)
        fill_color.setAlpha(170)
        brush = QBrush(fill_color)

        painter.fillRect(bb,brush)
Beispiel #3
0
  def __layoutActions(self):
    if self._layout == None:
      self._layout = dict()
      actions = self.actions()
      count = len(actions)
      angleStep = 2.0*math.pi/float(count)
      angle = 0
      fontMetrics = QtGui.QFontMetrics(self.font())
      radius = 120
      bounds = QRect()
      for a in actions:
        r = fontMetrics.boundingRect(a.text()).adjusted(-8, -8, 8, 8)
        r = r.translated(radius*math.cos(angle), radius*math.sin(angle))
        r = r.translated(-r.width()/2, -r.height()/2)
        r = r.translated(self.width()/2, self.height()/2)
        self._layout[a] = r
        bounds |= r
        angle += angleStep

      bounds = bounds.adjusted(-self._lineWidth, -self._lineWidth, self._lineWidth, self._lineWidth)
      for a in self._layout.keys():
        r = self._layout[a]
        r.translate(-bounds.x(), -bounds.y())

      self.resize(bounds.width(), bounds.height())
Beispiel #4
0
 def scene_item_rects_updated(self, items):
     """The user moved or resized items in the scene
     """
     debug_print('GraphicsItemView.item_rects_updated')
     for index, item in izip(self.indexes_of_items(items), items):
         # item.sceneBoundingRect() is the items rects in the correct
         # coordinates system
         debug_print('Row [{0}] updated'.format(index.row()))
         rect = item.sceneBoundingRect()
         # Cumbersome conversion to ints
         rect = QRect(rect.left(), rect.top(), rect.width(), rect.height())
         self.model().setData(index, rect, RectRole)
 def scene_item_rects_updated(self, items):
     """The user moved or resized items in the scene
     """
     debug_print('GraphicsItemView.item_rects_updated')
     for index, item in izip(self.indexes_of_items(items), items):
         # item.sceneBoundingRect() is the items rects in the correct
         # coordinates system
         debug_print('Row [{0}] updated'.format(index.row()))
         rect = item.sceneBoundingRect()
         # Cumbersome conversion to ints
         rect = QRect(rect.left(), rect.top(), rect.width(), rect.height())
         self.model().setData(index, rect, RectRole)
Beispiel #6
0
    def set_rect(self, new_rect):
        """Sets a new QRect in integer coordinates
        """

        # Cumbersome conversion to ints
        current = self.sceneBoundingRect()
        current = QRect(current.left(), current.top(),
                        current.width(), current.height())
        if current != new_rect:
            msg = 'Update rect for [{0}] from [{1}] to [{2}]'
            debug_print(msg.format(self, current, new_rect))
            self.prepareGeometryChange()

            # setrect() expects floating point rect
            self.setRect(QRectF(new_rect))
Beispiel #7
0
 def scene_box_added(self, rect):
     """The user added a box
     """
     m = self.model()
     row = len(self._rows)
     if not m.insertRow(row):
         raise InselectError('Could not insert row')
     else:
         # Cumbersome conversion to ints
         rect = QRect(rect.left(), rect.top(), rect.width(), rect.height())
         if not m.setData(m.index(row, 0), rect, RectRole):
             raise InselectError('Could not set rect')
         else:
             # Select the new box
             self.scene.clearSelection()
             item = self.items_of_rows([row]).next()
             item.setSelected(True)
             item.update()
 def scene_box_added(self, rect):
     """The user added a box
     """
     m = self.model()
     row = len(self._rows)
     if not m.insertRow(row):
         raise InselectError('Could not insert row')
     else:
         # Cumbersome conversion to ints
         rect = QRect(rect.left(), rect.top(), rect.width(), rect.height())
         if not m.setData(m.index(row, 0), rect, RectRole):
             raise InselectError('Could not set rect')
         else:
             # Select the new box
             self.scene.clearSelection()
             item = self.items_of_rows([row]).next()
             item.setSelected(True)
             item.update()
Beispiel #9
0
    def dataChanged(self, topLeft, bottomRight):
        """QAbstractItemView virtual
        """
        debug_print('GraphicsItemView.dataChanged', topLeft.row(),
                    bottomRight.row())

        for row in xrange(topLeft.row(), 1 + bottomRight.row()):
            # new is a QRect - integer coordinates
            new = self.model().index(row, 0).data(RectRole)

            # Cumbersome conversion to ints
            item = self._rows[row]
            current = item.sceneBoundingRect()
            current = QRect(current.left(), current.top(), current.width(),
                            current.height())
            if current != new:
                msg = 'Update rect for [{0}] from [{1}] to [{2}]'
                debug_print(msg.format(row, current, new))
                item.prepareGeometryChange()

                # setrect() expects floating point rect
                item.setRect(QRectF(new))
Beispiel #10
0
 def paintEvent(self, event):
     painter = QStylePainter(self)
     painter.setPen(self.palette().color(QPalette.Text))
     # Draw the combobox frame, focus rect, selected etc.
     opt = QStyleOptionComboBox()
     self.initStyleOption(opt)
     opt.currentText = ""  # Don't draw the raw HTML
     painter.drawComplexControl(QStyle.CC_ComboBox, opt)
     # Draw the icon and text
     painter.drawControl(QStyle.CE_ComboBoxLabel, opt)
     # Draw the HTML
     self.label.setText(self.currentText())
     self.label.adjustSize()
     pixmap = QPixmap(self.label.width(), self.label.height())
     pixmap.fill(Qt.transparent)
     self.label.render(pixmap, renderFlags=QWidget.RenderFlags(0))
     rect = QRect(opt.rect)
     y = (rect.height() - self.label.height()) / 2
     rect.setX(self.fontMetrics().width("n"))
     rect.setY(y)
     rect.setHeight(pixmap.height())
     rect.setWidth(pixmap.width())
     painter.drawPixmap(rect, pixmap, pixmap.rect())
Beispiel #11
0
class PaletteWidget(QtGui.QWidget):

    # Colour changed signal
    changed = QtCore.Signal()

    @property
    def colour(self):
        return QtGui.QColor.fromHsvF(self._hue, self._saturation, self._value)
    @colour.setter
    def colour(self, value):
        # If this is an integer, assume is RGBA
        if type(value) is int:
            r = (value & 0xff000000) >> 24
            g = (value & 0xff0000) >> 16
            b = (value & 0xff00) >> 8
            value = QtGui.QColor.fromRgb(r,g,b)
        self._set_colour(value)

    def __init__(self, parent = None):
        super(PaletteWidget, self).__init__(parent)
        self._hue = 1.0
        self._saturation = 1.0
        self._value = 1.0
        self._hue_width = 24
        self._gap = 8
        self._colour = QtGui.QColor.fromHslF(self._hue, 1.0, 1.0)
        self._calculate_bounds()
        self._draw_palette()

    # Calculate the sizes of various bits of our UI
    def _calculate_bounds(self):
        width = self.width()
        height = self.height()
        # Hue palette
        self._hue_rect = QRect(
            width-self._hue_width, 0, self._hue_width, height)
        # Shades palette
        self._shades_rect = QRect(
            0, 0, width-(self._hue_width+self._gap), height)

    # Render our palette to an image
    def _draw_palette(self):

        # Create an image with a white background
        self._image = QtGui.QImage(QtCore.QSize(self.width(), self.height()),
            QtGui.QImage.Format.Format_RGB32)
        self._image.fill(QtGui.QColor.fromRgb(0xff, 0xff, 0xff))

        # Draw on our image with no pen
        qp = QtGui.QPainter()
        qp.begin(self._image)
        qp.setPen(QtCore.Qt.NoPen)

        # Render hues
        rect = self._hue_rect
        for x in xrange(rect.x(), rect.x()+rect.width()):
            for y in xrange(rect.y(), rect.y()+rect.height(), 8):
                h = float(y)/rect.height()
                s = 1.0
                v = 1.0
                c = QtGui.QColor.fromHsvF(h, s, v)
                qp.setBrush(c)
                qp.drawRect(x, y, 8, 8)

        # Render hue selection marker
        qp.setBrush(QtGui.QColor.fromRgb(0xff, 0xff, 0xff))
        qp.drawRect(rect.x(), self._hue * rect.height(),
            rect.width(), 2)

        # Render shades
        rect = self._shades_rect
        width = float(rect.width())
        steps = int(round(width / 8.0))
        step_size = width / steps
        x = rect.x()
        while x < rect.width()+rect.x():
            w = int(round(step_size))
            for y in xrange(rect.y(), rect.y()+rect.height(), 8):
                h = self._hue
                s = 1-float(y)/rect.height()
                v = float(x)/rect.width()
                c = QtGui.QColor.fromHsvF(h, s, v)
                qp.setBrush(c)
                qp.drawRect(x, y, w, 8)
            x += w
            width -= w
            steps -= 1
            if steps > 0:
                step_size = width / steps

        # Render colour selection marker
        qp.setBrush(QtGui.QColor.fromRgb(0xff, 0xff, 0xff))
        qp.drawRect(rect.x(), (1-self._saturation)*rect.height(), rect.width(), 1)
        qp.drawRect(self._value*rect.width(), rect.y(), 1, rect.height())

        qp.end()

    def paintEvent(self, event):
        # Render our palette image to the screen
        qp = QtGui.QPainter()
        qp.begin(self)
        qp.drawImage(QPoint(0,0), self._image)
        qp.end()

    def mousePressEvent(self, event):
        mouse = QPoint(event.pos())
        if event.buttons() & QtCore.Qt.LeftButton:
            # Click on hues?
            if self._hue_rect.contains(mouse.x(), mouse.y()):
                y = mouse.y()
                c = QtGui.QColor.fromHsvF(
                    float(y)/self.height(), self._saturation, self._value)
                self.colour = c
            # Click on colours?
            elif self._shades_rect.contains(mouse.x(), mouse.y()):
                # calculate saturation and value
                x = mouse.x()
                y = mouse.y()
                c = QtGui.QColor.fromHsvF(
                    self._hue, 1-float(y)/self._shades_rect.height(),
                    float(x)/self._shades_rect.width())
                self.colour = c

    def mouseMoveEvent(self, event):
        if event.buttons() & QtCore.Qt.LeftButton:
            self.mousePressEvent(event)

    def resizeEvent(self, event):
        self._calculate_bounds()
        self._draw_palette()

    # Set the current colour
    def _set_colour(self, c):
        h, s, v, _ = c.getHsvF()
        self._hue = h
        self._saturation = s
        self._value = v
        self._draw_palette()
        self.repaint()
        self.changed.emit()
Beispiel #12
0
class PackedRect:
    """ Given p and a starting rect, draw
        a subrectangle that takes <= p% of the
        area of the starting rect. Repeat for p1,p2...
        as long as there continues to be room in the parent rect"""  
    
    def __init__(self, parentRect, percentageItems):
        self.parentRect = self.leftoverRect = QRect()
        self.percItems = sorted(percentageItems, key=lambda pItem: pItem.getLocalPercentage(), reverse = True)
        self.parentRect = QRect(parentRect)
        self.reset()
        self.percs = []
        
    def __iter__(self):
        return self
        
    def next(self):
        perc = 0
        if self.currPercItem < len(self.percItems) and not self.isEmpty():
            while perc == 0:
                if self.currPercItem < len(self.percItems):
                    percItem = self.percItems[self.currPercItem]
                    perc = percItem.getLocalPercentage()
                else:
                    raise StopIteration()
                self.currPercItem += 1
            
            return (percItem, self.nextRect(perc))
        else:
            raise StopIteration()
        
        
    def reset(self):
        import copy
        self.lastFlipPercentage = 100
        self.currPercItem = 0
        self.leftoverRect = QRect(self.parentRect)
        
    def __updateDirectionToPreferSquareness(self, neededArea):
        """ Pick a direction that will give a more square 
            result for the next rectangle, but strongly
            bias toward horizontal. Its important for there
            to be consistency in this algorithm and not 
            have it depend on any weird side effects """
        biasTowardHoriz = 1.5
        (width, height) = (self.leftoverRect.width(),self.leftoverRect.height())
        (width, height) = self.__calculaceGivingUpWidth(neededArea, width, height)
        widthDiff = abs(width-height) 
        (width, height) = (self.leftoverRect.width(),self.leftoverRect.height())
        (width, height) = self.__calculateGivingUpHeight(neededArea, width, height)
        heightDiff = abs(width-height)
        if widthDiff < (heightDiff * biasTowardHoriz):
            return Direction.Horizontal
        else:
            return Direction.Vertical
        
            
    def isEmpty(self):
        return self.leftoverRect.isEmpty()
    
    def __isNeededAreaMoreThanLeftover(self, neededArea):
        leftoverArea = self.leftoverRect.width() * self.leftoverRect.height()
        return (neededArea + 0.01) > leftoverArea

        
            
    @validRectReturned
    def __giveUpAllRemainingArea(self):
        """ Return all remaining leftover space and empty
            the leftover rect"""
        assert not self.leftoverRect.isEmpty()
        remaining = QRect(self.leftoverRect)
        self.leftoverRect.setWidth(-1)
        self.leftoverRect.setHeight(-1)
        assert self.leftoverRect.isEmpty()
        return remaining
    
    def __calculateGivingUpHeight(self, neededArea, width, height):
        height = neededArea / width
        height = ceil(height)
        return (width, height)
        
    def __calculaceGivingUpWidth(self, neededArea, width, height):
        width = neededArea / height
        width = ceil(width)
        return (width, height)
        
    
    def __giveUpLeftoverHeight(self, neededArea, width, height):
        """ Sacrifice some height from the leftover rect for the needed area"""
        (width, height) = self.__calculateGivingUpHeight(neededArea, width, height)
        self.leftoverRect.setY(self.leftoverRect.y() + height)
        return (width, height)
        
    def __giveUpLeftoverWidth(self, neededArea, width, height):
        """ Sacrifice some width from the leftover rect for the needed area"""
        (width, height) = self.__calculaceGivingUpWidth(neededArea, width, height)
        self.leftoverRect.setX(self.leftoverRect.x() + width)
        return (width, height)
    
    @validRectReturned    
    def __giveUpSomeLeftoverSpace(self, neededArea):
        """ Sacrifice some leftover space to represent the neededARea"""
        thisDir = self.__updateDirectionToPreferSquareness(neededArea)
        giveUpFns = [self.__giveUpLeftoverWidth, self.__giveUpLeftoverHeight] 
        fn = giveUpFns[thisDir]
        newRect = QRect()
        newRect.setTopLeft(self.leftoverRect.topLeft())
        (width, height) = (self.leftoverRect.width(), self.leftoverRect.height())
        
        (width, height) = fn(neededArea, width, height)
      
        if not self.leftoverRect.isValid() and not self.leftoverRect.isEmpty():
            print "Failure with the following input"
            print "W/H %i/%i" % (width, height)
            print "ParentRect %s" % repr(self.parentRect)
            print "Leftover %s" % repr(self.leftoverRect)
            print "Percentages %s" % repr(self.percs)

            assert False
        
        newRect.setHeight(height)
        newRect.setWidth(width)
        return newRect

        
    @validRectReturned
    def nextRect(self, percentage):
        """ Get the next rect from leftoverRect, update
            leftoverRect with whats leftover """
        self.percs.append(percentage)
        if self.isEmpty():
            raise ValueError("This guy is empty pR: %s perc: %s" % (self.parentRect, self.percs))
        neededArea = (self.parentRect.width() * self.parentRect.height()) * (percentage/100.0)
        if self.__isNeededAreaMoreThanLeftover(neededArea):
            return self.__giveUpAllRemainingArea()
        
        return self.__giveUpSomeLeftoverSpace(neededArea)
    
    def __repr__(self):
        return "PackedRect(%s)" % repr(self.parentRect) 

    def __str__(self):
        return self.__repr__() + " Leftover(%s)" % repr(self.leftoverRect)
class EmbDetailsDialog(QDialog):
    """
    Subclass of `QDialog`_

    Class implementing the Details dialog.

    .. sphinx_generate_methods_summary::
       EmbDetailsDialog
    """
    def __init__(self, theScene, parent):
        """
        Default class constructor.

        :param `theScene`: TOWRITE
        :type `theScene`: `QGraphicsScene`_
        :param `parent`: Pointer to a parent widget instance.
        :type `parent`: `QWidget`_
        """
        super(EmbDetailsDialog, self).__init__(parent)

        self.setMinimumSize(750, 550)

        self.getInfo()
        mainWidget = self.createMainWidget()

        buttonBox = QDialogButtonBox(QDialogButtonBox.Ok)
        buttonBox.accepted.connect(self.accept)

        vboxLayoutMain = QVBoxLayout(self)
        vboxLayoutMain.addWidget(mainWidget)
        vboxLayoutMain.addWidget(buttonBox)
        self.setLayout(vboxLayoutMain)

        self.setWindowTitle(self.tr("Embroidery Design Details"))

        QApplication.setOverrideCursor(Qt.ArrowCursor)


    def __del__(self):
        """Class destructor"""
        QApplication.restoreOverrideCursor()

    def getInfo(self):
        """TOWRITE"""
        # TODO: generate a temporary pattern from the scene data.

        # TODO: grab this information from the pattern
        self.stitchesTotal = 5 # TODO: embStitchList_count(pattern->stitchList, TOTAL)
        self.stitchesReal  = 4 # TODO: embStitchList_count(pattern->stitchList, NORMAL)
        self.stitchesJump  = 3 # TODO: embStitchList_count(pattern->stitchList, JUMP)
        self.stitchesTrim  = 2 # TODO: embStitchList_count(pattern->stitchList, TRIM)
        self.colorTotal    = 1 # TODO: embThreadList_count(pattern->threadList, TOTAL)
        self.colorChanges  = 0 # TODO: embThreadList_count(pattern->threadList, CHANGES)

        self.boundingRect = QRect() #TODO/FIXME#
        self.boundingRect.setRect(0, 0, 50, 100) # TODO: embPattern_calcBoundingBox(pattern)

    def createMainWidget(self):
        """
        TOWRITE

        :return: TOWRITE
        :rtype: `QScrollArea`_
        """
        widget = QWidget(self)

        # Misc
        groupBoxMisc = QGroupBox(self.tr("General Information"), widget)

        labelStitchesTotal = QLabel(self.tr("Total Stitches:"), self)
        labelStitchesReal  = QLabel(self.tr("Real Stitches:"),  self)
        labelStitchesJump  = QLabel(self.tr("Jump Stitches:"),  self)
        labelStitchesTrim  = QLabel(self.tr("Trim Stitches:"),  self)
        labelColorTotal    = QLabel(self.tr("Total Colors:"),   self)
        labelColorChanges  = QLabel(self.tr("Color Changes:"),  self)
        labelRectLeft      = QLabel(self.tr("Left:"),           self)
        labelRectTop       = QLabel(self.tr("Top:"),            self)
        labelRectRight     = QLabel(self.tr("Right:"),          self)
        labelRectBottom    = QLabel(self.tr("Bottom:"),         self)
        labelRectWidth     = QLabel(self.tr("Width:"),          self)
        labelRectHeight    = QLabel(self.tr("Height:"),         self)

        fieldStitchesTotal = QLabel(u'%s' % (self.stitchesTotal), self)
        fieldStitchesReal  = QLabel(u'%s' % (self.stitchesReal),  self)
        fieldStitchesJump  = QLabel(u'%s' % (self.stitchesJump),  self)
        fieldStitchesTrim  = QLabel(u'%s' % (self.stitchesTrim),  self)
        fieldColorTotal    = QLabel(u'%s' % (self.colorTotal),    self)
        fieldColorChanges  = QLabel(u'%s' % (self.colorChanges),  self)
        fieldRectLeft      = QLabel(u'%s' % (str(self.boundingRect.left())   + " mm"), self)
        fieldRectTop       = QLabel(u'%s' % (str(self.boundingRect.top())    + " mm"), self)
        fieldRectRight     = QLabel(u'%s' % (str(self.boundingRect.right())  + " mm"), self)
        fieldRectBottom    = QLabel(u'%s' % (str(self.boundingRect.bottom()) + " mm"), self)
        fieldRectWidth     = QLabel(u'%s' % (str(self.boundingRect.width())  + " mm"), self)
        fieldRectHeight    = QLabel(u'%s' % (str(self.boundingRect.height()) + " mm"), self)

        gridLayoutMisc = QGridLayout(groupBoxMisc)
        gridLayoutMisc.addWidget(labelStitchesTotal,  0, 0, Qt.AlignLeft)
        gridLayoutMisc.addWidget(labelStitchesReal,   1, 0, Qt.AlignLeft)
        gridLayoutMisc.addWidget(labelStitchesJump,   2, 0, Qt.AlignLeft)
        gridLayoutMisc.addWidget(labelStitchesTrim,   3, 0, Qt.AlignLeft)
        gridLayoutMisc.addWidget(labelColorTotal,     4, 0, Qt.AlignLeft)
        gridLayoutMisc.addWidget(labelColorChanges,   5, 0, Qt.AlignLeft)
        gridLayoutMisc.addWidget(labelRectLeft,       6, 0, Qt.AlignLeft)
        gridLayoutMisc.addWidget(labelRectTop,        7, 0, Qt.AlignLeft)
        gridLayoutMisc.addWidget(labelRectRight,      8, 0, Qt.AlignLeft)
        gridLayoutMisc.addWidget(labelRectBottom,     9, 0, Qt.AlignLeft)
        gridLayoutMisc.addWidget(labelRectWidth,     10, 0, Qt.AlignLeft)
        gridLayoutMisc.addWidget(labelRectHeight,    11, 0, Qt.AlignLeft)
        gridLayoutMisc.addWidget(fieldStitchesTotal,  0, 1, Qt.AlignLeft)
        gridLayoutMisc.addWidget(fieldStitchesReal,   1, 1, Qt.AlignLeft)
        gridLayoutMisc.addWidget(fieldStitchesJump,   2, 1, Qt.AlignLeft)
        gridLayoutMisc.addWidget(fieldStitchesTrim,   3, 1, Qt.AlignLeft)
        gridLayoutMisc.addWidget(fieldColorTotal,     4, 1, Qt.AlignLeft)
        gridLayoutMisc.addWidget(fieldColorChanges,   5, 1, Qt.AlignLeft)
        gridLayoutMisc.addWidget(fieldRectLeft,       6, 1, Qt.AlignLeft)
        gridLayoutMisc.addWidget(fieldRectTop,        7, 1, Qt.AlignLeft)
        gridLayoutMisc.addWidget(fieldRectRight,      8, 1, Qt.AlignLeft)
        gridLayoutMisc.addWidget(fieldRectBottom,     9, 1, Qt.AlignLeft)
        gridLayoutMisc.addWidget(fieldRectWidth,     10, 1, Qt.AlignLeft)
        gridLayoutMisc.addWidget(fieldRectHeight,    11, 1, Qt.AlignLeft)
        gridLayoutMisc.setColumnStretch(1,1)
        groupBoxMisc.setLayout(gridLayoutMisc)

        # TODO: Color Histogram

        # Stitch Distribution
        # groupBoxDist = QGroupBox(self.tr("Stitch Distribution"), widget)

        # TODO: Stitch Distribution Histogram

        # Widget Layout
        vboxLayoutMain = QVBoxLayout(widget)
        vboxLayoutMain.addWidget(groupBoxMisc)
        # vboxLayoutMain.addWidget(groupBoxDist)
        vboxLayoutMain.addStretch(1)
        widget.setLayout(vboxLayoutMain)

        scrollArea = QScrollArea(self)
        scrollArea.setWidgetResizable(True)
        scrollArea.setWidget(widget)
        return scrollArea
Beispiel #14
0
class PaletteWidget(QtGui.QWidget):

    # Color changed signal
    changed = QtCore.Signal()

    @property
    def color(self):
        return QtGui.QColor.fromHsvF(self._hue, self._saturation, self._value)

    @color.setter
    def color(self, value):
        # If this is an integer, assume is RGBA
        if not isinstance(value, QtGui.QColor):
            r = (value & 0xff000000) >> 24
            g = (value & 0xff0000) >> 16
            b = (value & 0xff00) >> 8
            value = QtGui.QColor.fromRgb(r, g, b)
        self._set_color(value)
        self.RGBvalue.setText(value.name())

    def __init__(self, parent=None, RGBvalue=None):
        super(PaletteWidget, self).__init__(parent)
        self._hue = 1.0
        self._saturation = 1.0
        self._value = 1.0
        self._hue_width = 24
        self._gap = 8
        self._color = QtGui.QColor.fromHslF(self._hue, 1.0, 1.0)
        self._calculate_bounds()
        self._draw_palette()
        self.RGBvalue = RGBvalue

    # Calculate the sizes of various bits of our UI
    def _calculate_bounds(self):
        width = self.width()
        height = self.height()
        # Hue palette
        self._hue_rect = QRect(width - self._hue_width, 0, self._hue_width,
                               height)
        # Shades palette
        self._shades_rect = QRect(0, 0, width - (self._hue_width + self._gap),
                                  height)

    # Render our palette to an image
    def _draw_palette(self):

        # Create an image with a white background
        self._image = QtGui.QImage(QtCore.QSize(self.width(), self.height()),
                                   QtGui.QImage.Format.Format_RGB32)
        self._image.fill(QtGui.QColor.fromRgb(0xff, 0xff, 0xff))

        # Draw on our image with no pen
        qp = QtGui.QPainter()
        qp.begin(self._image)
        qp.setPen(QtCore.Qt.NoPen)

        # Render hues
        rect = self._hue_rect
        for x in xrange(rect.x(), rect.x() + rect.width()):
            for y in xrange(rect.y(), rect.y() + rect.height(), 8):
                h = float(y) / rect.height()
                s = 1.0
                v = 1.0
                c = QtGui.QColor.fromHsvF(h, s, v)
                qp.setBrush(c)
                qp.drawRect(x, y, 8, 8)

        # Render hue selection marker
        qp.setBrush(QtGui.QColor.fromRgb(0xff, 0xff, 0xff))
        qp.drawRect(rect.x(), self._hue * rect.height(), rect.width(), 2)

        # Render shades
        rect = self._shades_rect
        width = float(rect.width())
        steps = int(round(width / 8.0))
        step_size = width / steps
        x = rect.x()
        while x < rect.width() + rect.x():
            w = int(round(step_size))
            for y in xrange(rect.y(), rect.y() + rect.height(), 8):
                h = self._hue
                s = 1 - float(y) / rect.height()
                v = float(x) / rect.width()
                c = QtGui.QColor.fromHsvF(h, s, v)
                qp.setBrush(c)
                qp.drawRect(x, y, w, 8)
            x += w
            width -= w
            steps -= 1
            if steps > 0:
                step_size = width / steps

        # Render color selection marker
        qp.setBrush(QtGui.QColor.fromRgb(0xff, 0xff, 0xff))
        qp.drawRect(rect.x(), (1 - self._saturation) * rect.height(),
                    rect.width(), 1)
        qp.drawRect(self._value * rect.width(), rect.y(), 1, rect.height())

        qp.end()

    def paintEvent(self, event):
        # Render our palette image to the screen
        qp = QtGui.QPainter()
        qp.begin(self)
        qp.drawImage(QPoint(0, 0), self._image)
        qp.end()

    def mousePressEvent(self, event):
        mouse = QPoint(event.pos())
        if event.buttons() & QtCore.Qt.LeftButton:
            # Click on hues?
            if self._hue_rect.contains(mouse.x(), mouse.y()):
                y = mouse.y()
                c = QtGui.QColor.fromHsvF(
                    float(y) / self.height(), self._saturation, self._value)
                self.color = c
            # Click on colors?
            elif self._shades_rect.contains(mouse.x(), mouse.y()):
                # calculate saturation and value
                x = mouse.x()
                y = mouse.y()
                c = QtGui.QColor.fromHsvF(
                    self._hue, 1 - float(y) / self._shades_rect.height(),
                    float(x) / self._shades_rect.width())
                self.color = c

    def mouseMoveEvent(self, event):
        if event.buttons() & QtCore.Qt.LeftButton:
            self.mousePressEvent(event)

    def resizeEvent(self, event):
        self._calculate_bounds()
        self._draw_palette()

    # Set the current color
    def _set_color(self, c):
        h, s, v, _ = c.getHsvF()
        self._hue = h
        self._saturation = s
        self._value = v
        self._draw_palette()
        self.repaint()
        self.changed.emit()
Beispiel #15
0
    def _drawLeafRow(self, option, painter, index):
        """
        @type painter: QPainter
        @type option: QStyleOptionViewItemV4
        @type index: QModelIndex
        """
        rect = option.rect
        if self.selectionModel().isSelected(index):
            painter.fillRect(rect, Qt.white)
        else:
            painter.fillRect(rect, QColor(Qt.lightGray).lighter(120))
        painter.setPen(Qt.darkGray)
        painter.drawLine(rect.bottomLeft(), rect.bottomRight())
        painter.setPen(QColor(Qt.lightGray).lighter())
        painter.drawLine(rect.topLeft(), rect.topRight())
        ex = index.data(Qt.UserRole)
        painter.setPen(Qt.black)
        painter.save()
        font = painter.font()
        font.setBold(True)
        painter.setFont(font)
        painter.drawText(rect.adjusted(LEFT_MARGIN, 0, 0, -rect.height() / 2), Qt.AlignVCenter, ex.desc)
        painter.restore()
        painter.setPen(Qt.darkGray)
        painter.setRenderHint(QPainter.Antialiasing)
        if self._idToName is not None:
            fromName = self._idToName(ex.fromId)
            fromRect = painter.fontMetrics().boundingRect(fromName)
            painter.setBrush(Qt.lightGray)
            painter.setPen(Qt.transparent)
            bottomRect = rect.adjusted(LEFT_MARGIN, rect.height() / 2, 0, 0)
            fromRect = fromRect.adjusted(-4, -2, 4, 2)
            fromRect = QRect(bottomRect.left(),
                             bottomRect.top(),
                             fromRect.width(),
                             fromRect.height())
            painter.drawRoundedRect(fromRect, 3, 3)
            painter.setPen(Qt.darkGray)
            painter.drawText(fromRect.adjusted(4, 2, -4, -2), Qt.AlignVCenter, fromName)

            painter.save()
            # FIXME: normal check for weekly and income envelopes, colors to constants
            if not ex.manual:
                painter.setBrush(QColor(157, 157, 157))
            elif fromName.startswith("Week_"):
                painter.setBrush(Qt.transparent)
            elif fromName.lower() == u"доход" or fromName.lower() == u"income":
                painter.setBrush(QColor(100, 230, 100))
            else:
                painter.setBrush(QColor(120, 120, 230))
            painter.setPen(Qt.transparent)
            painter.drawRect(QRect(0, rect.top() + 4, 4, rect.height() - 10))
            painter.restore()

            bottomRect = bottomRect.adjusted(fromRect.width() + MARGIN, 0, 0, 0)
            toName = self._idToName(ex.toId)
            toRect = painter.fontMetrics().boundingRect(toName)
            toRect = toRect.adjusted(-4, -2, 4, 2)
            toRect = QRect(bottomRect.left(),
                           bottomRect.top(),
                           toRect.width(),
                           toRect.height())
            painter.setPen(Qt.transparent)
            painter.drawRoundedRect(toRect, 3, 3)
            painter.setPen(Qt.darkGray)
            painter.drawText(toRect.adjusted(4, 2, -4, -2), Qt.AlignVCenter, toName)
        font = painter.font()
        font.setPixelSize(24)
        font.setBold(True)
        painter.save()
        painter.setFont(font)
        painter.drawText(rect.adjusted(rect.width() / 2, 0, -5, 0), Qt.AlignRight | Qt.AlignVCenter,
                         str(int(ex.value)) + u" руб.")
        painter.restore()