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)
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)
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())
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 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))
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 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))
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())
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()
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
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()
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()