def rebuild( self, gridRect ): """ Rebuilds the tracker item. """ scene = self.scene() if ( not scene ): return self.setVisible(gridRect.contains(self.pos())) self.setZValue(100) path = QPainterPath() path.moveTo(0, 0) path.lineTo(0, gridRect.height()) tip = '' tip_point = None self._ellipses = [] items = scene.collidingItems(self) self._basePath = QPainterPath(path) for item in items: item_path = item.path() found = None for y in range(int(gridRect.top()), int(gridRect.bottom())): point = QPointF(self.pos().x(), y) if ( item_path.contains(point) ): found = QPointF(0, y - self.pos().y()) break if ( found ): path.addEllipse(found, 6, 6) self._ellipses.append(found) # update the value information value = scene.valueAt(self.mapToScene(found)) tip_point = self.mapToScene(found) hruler = scene.horizontalRuler() vruler = scene.verticalRuler() x_value = hruler.formatValue(value[0]) y_value = vruler.formatValue(value[1]) tip = '<b>x:</b> %s<br/><b>y:</b> %s' % (x_value, y_value) self.setPath(path) self.setVisible(True) # show the popup widget if ( tip ): anchor = XPopupWidget.Anchor.RightCenter widget = self.scene().chartWidget() tip_point = widget.mapToGlobal(widget.mapFromScene(tip_point)) XPopupWidget.showToolTip(tip, anchor = anchor, parent = widget, point = tip_point, foreground = QColor('blue'), background = QColor(148, 148, 255))
def setColor(self, color): """ Sets the color for this widget. :param color | <QColor> || <str> """ self._color = QColor(color) self.setAlternateColor(self._color.darker(110))
def setHighlightColor(self, color): """ Sets the primary color used for highlighting this item. :param color | <QColor> """ self._highlightColor = QColor(color) self.setAlternateHighlightColor(self._highlightColor.darker(110))
def setProgressColor(self, color): """ Sets the color that for the progress bar for this item. :param color | <QColor> """ self._progressColor = QColor(color) self.setAlternateProgressColor(self._progressColor.darker(110))
def setColor(self, color): """ Sets the color for this widget to the inputed color. :param color | <QColor> """ self._color = QColor(color) self.setAlternateColor(self._color.lighter(140))
def __init__(self, rect, slot, name='', toolTip=''): self._rect = rect self._slot = slot self._name = name self._hovered = False self._enabled = True self._customData = {} self._toolTip = toolTip self._style = XNodeHotspot.Style.Invisible self._icon = None self._hoverIcon = None self._color = QColor('white') self._borderColor = QColor('gray') self._visibilityPolicy = XNodeHotspot.VisibilityPolicy.Always
def paintEvent(self, event): """ Handles the drawing for this widget and its selection region. :param event | <QPaintEvent> """ pen = QPen(Qt.DashLine) pen.setColor(QColor('red')) with XPainter(self) as painter: painter.setPen(pen) clr = QColor('black') clr.setAlpha(100) painter.setBrush(clr) painter.drawRect(self._region)
def setBorderColor(self, color): """ Sets the border base color for this renderer to the inputed color. :param color | <QColor> """ self._borderColor = QColor(color)
def setAxisColor(self, color): """ Sets the axis base color for this renderer to the inputed color. :param color | <QColor> """ self._axisColor = QColor(color)
def setAlternateColor(self, color): """ Sets the alternate base color for this renderer to the inputed color. :param color | <QColor> """ self._alternateColor = QColor(color)
def setTextColor(self, color): """ Sets the text color for this instance to the inputed color. :param color | <QColor> """ self.editor().setTextColor(QColor(color))
def setFillColor(self, color): """ Sets the color that will be used for the fill of this item. :param color | <QColor> """ self._fillColor = QColor(color)
def setHighlightColor(self, color): """ Sets the color that will be used for the highlight of this item. :param color | <QColor> """ self._highlightColor = QColor(color)
def setBorderColor(self, color): """ Sets the color that will be used for the border of this item. :param color | <QColor> """ self._borderColor = QColor(color)
def setAlternateHighlightColor(self, color): """ Sets the alternate selection color for this item to the inputed color. :param color | <QColor> """ self._alternateHighlightColor = QColor(color)
def setTextColor(self, color): """ Sets the color that will be used for this widget's text. :param color | <QColor> || <str> """ self._textColor = QColor(color)
def setValidBackground( self, bg ): """ Sets the valid background color for this widget to the inputed color. :param bg | <QColor> """ self._validBackground = QColor(bg)
def fromString(cls, strdata): """ Restores a color set instance from the inputed string data. :param strdata | <str> """ if (not strdata): return None from xml.etree import ElementTree xelem = ElementTree.fromstring(str(strdata)) output = cls(xelem.get('name'), xelem.get('colorGroups').split(',')) for xcolor in xelem: colorName = xcolor.get('name') for xcolorval in xcolor: color = QColor(int(xcolorval.get('red')), int(xcolorval.get('green')), int(xcolorval.get('blue')), int(xcolorval.get('alpha'))) output.setColor(colorName, color, xcolorval.get('group')) return output
def setAlternateColor(self, color): """ Sets the alternate color for this widget to the inputed color. :param color | <QColor> """ self._alternateColor = QColor(color)
def color(self): """ Returns the primary color for this item. :return <QColor> """ return QColor(self._color)
def alternateColor(self): """ Returns the alternate color for this item. :return <QColor> """ return QColor(self._alternateColor)
def setValidForeground( self, fg ): """ Sets the valid foreground color for this widget to the inputed color. :param fg | <QColor> """ self._validForeground = QColor(fg)
def setHintColor(self, color): """ Sets the color used for the hint rendering. :param color | <QColor> """ self._hintColor = QColor(color)
def setColor( self, color ): """ Sets the color for this tracker item to the given color. :param color | <QColor> """ self._color = QColor(color)
def setColor( self, color ): """ Sets the color for this widget to the inputed color. :param color | <QColor> """ self._color = QColor(color) self.setAlternateColor(self._color.lighter(140))
def setTextColor(self, textColor): """ Sets the text color that will be used for this item to the inputed color. :param textColor | <QColor> """ self._textColor = QColor(textColor)
def setProgressColor( self, color ): """ Sets the color that for the progress bar for this item. :param color | <QColor> """ self._progressColor = QColor(color) self.setAlternateProgressColor(self._progressColor.darker(110))
def setHighlightColor( self, color ): """ Sets the primary color used for highlighting this item. :param color | <QColor> """ self._highlightColor = QColor(color) self.setAlternateHighlightColor(self._highlightColor.darker(110))
def setColor( self, color ): """ Sets the color for this widget. :param color | <QColor> || <str> """ self._color = QColor(color) self.setAlternateColor(self._color.darker(110))
def color(self, name, colorGroup=None): """ Returns the color for the given name at the inputed group. If no \ group is specified, the first group in the list is used. :param name | <str> colorGroup | <str> || None :return <QColor> """ if (not colorGroup and self._colorGroups): colorGroup = self._colorGroups[0] if (not colorGroup): return QColor() return self._colors.get(str(name), {}).get(str(colorGroup), QColor())
def setAlternateProgressColor(self, color): """ Sets the alternate progress color that will be used when drawing a progress bar for this item. :return <QColor> """ self._alternateProgressColor = QColor(color)
def __init__(self, **options): # define custom properties self._name = options.get('name', '') self._color = QColor(options.get('color', self.randomColor())) self._colorMap = {} self._plot = options.get('plot', []) self._visible = True self._dragData = {}
def setKeyColor(self, key, color): """ Sets the color used when rendering pie charts. :param key | <str> color | <QColor> """ self._keyColors[nativestring(key)] = QColor(color)
def randomColor(self): """ Returns a random color for this dataset. :return <QColor> """ return QColor(random.randint(90, 200), random.randint(90, 200), random.randint(90, 200))
def __init__(self, treeItem): super(XGanttViewItem, self).__init__() # define custom properties self._color = QColor('white') self._alternateColor = QColor(230, 230, 230) self._highlightColor = QColor('yellow') self._alternateHighlightColor = self._highlightColor.darker(110) self._textColor = QColor('black') self._borderColor = QColor(50, 50, 50) self._progressColor = QColor(200, 200, 250) self._alternateProgressColor = QColor(180, 180, 230) self._showProgress = True self._padding = 3 self._borderRadius = 5 self._percentComplete = 0 self._text = '' self._syncing = False self._treeItem = weakref.ref(treeItem) # setup standard properties flags = self.ItemIsSelectable flags |= self.ItemIsFocusable if treeItem.flags() & Qt.ItemIsEditable: flags |= self.ItemIsMovable effect = QGraphicsDropShadowEffect() effect.setXOffset(0) effect.setYOffset(0) effect.setColor(QColor(40, 40, 40, 100)) effect.setBlurRadius(10) self.setFlags( flags ) self.setAcceptHoverEvents(True) self.setGraphicsEffect(effect) # need this flag for Qt 4.6+ try: self.setFlag(self.ItemSendsGeometryChanges) except AttributeError: pass
def drawItem(self, item, painter, option): """ Draws the inputed item as a bar graph. :param item | <XChartDatasetItem> painter | <QPainter> option | <QStyleOptionGraphicsItem> """ dataset = item.dataset() painter.save() painter.setRenderHint(painter.Antialiasing) pen = QPen(dataset.color()) pen.setWidth(0.75) painter.setPen(pen) for path in item.buildData('subpaths', []): gradient = QLinearGradient() clr = QColor(dataset.color()) clr.setAlpha(220) gradient.setColorAt(0.0, clr.lighter(180)) gradient.setColorAt(0.1, clr.lighter(160)) gradient.setColorAt(0.25, clr.lighter(140)) gradient.setColorAt(1.0, clr.lighter(125)) if self.orientation() == Qt.Vertical: gradient.setStart(0, path.boundingRect().bottom()) gradient.setFinalStop(0, path.boundingRect().top()) else: gradient.setStart(path.boundingRect().left(), 0) gradient.setFinalStop(path.boundingRect().right(), 0) painter.setBrush(gradient) painter.drawPath(path) painter.restore()
def setRecordState(self, recordState): """ Sets the record state for this item to the inputed state. :param recordState | <XOrbRecordItem.State> """ self._recordState = recordState try: is_colored = self.treeWidget().isColored() except AttributeError: return if not is_colored: return # determine the color for the item based on the state if recordState & XOrbRecordItem.State.Removed: clr = self.treeWidget().colorSet().color("RecordRemoved") elif recordState & XOrbRecordItem.State.New: clr = self.treeWidget().colorSet().color("RecordNew") elif recordState & XOrbRecordItem.State.Modified: clr = self.treeWidget().colorSet().color("RecordModified") else: clr = None # set the color based on the record state if clr is not None: clr = QColor(clr) clr.setAlpha(40) brush = QBrush(clr) else: brush = QBrush() for c in range(self.treeWidget().columnCount()): self.setBackground(c, brush)
def setColor( self, color ): """ Convenience method to set the border, fill and highlight colors based on the inputed color. :param color | <QColor> """ # sets the border color as the full value self.setBorderColor(color) # set the highlight color as the color with a 140 % alpha clr = QColor(color) clr.setAlpha(150) self.setHighlightColor(clr) # set the fill color as the color with a 50 % alpha clr = QColor(color) clr.setAlpha(80) self.setFillColor(clr)
class XChartWidgetItem(QGraphicsPathItem): def __init__( self ): super(XChartWidgetItem, self).__init__() self.setAcceptHoverEvents(True) # set default information self._chartType = None self._pieCenter = QPointF(0, 0) self._subpaths = [] self._keyColors = {} self._ellipses = [] self._keyToolTips = {} self._showPointsInLine = True self._shaded = True self._dragData = {} self._radius = 6 self._title = '' self._color = self.randomColor() self._alternateColor = self._color.lighter(140) self._points = [] self._barSize = 30 self._orientation = Qt.Horizontal self._pieAxis = Qt.YAxis self._pointRadius = 6 self._horizontalOffset = 0 self._verticalOffset = 0 self._hoveredPath = None self._dirty = False self._buildData = {} def addPoint( self, x, y ): """ Adds a new chart point to this item. :param x | <variant> y | <variant> """ self._points.append((x, y)) self._dirty = True def alternateColor( self ): """ Returns the alternate color for this item. :return <QColor> """ return QColor(self._alternateColor) def barSize( self ): """ Returns the size that the bar chart should be rendered with. :return <int> """ return self._barSize def chartType( self ): """ Returns the chart type for this item. If no type is explicitely set, then the scenes chart type will be utilized. :return <XChartScene.Type> """ if ( self._chartType ): return self._chartType scene = self.scene() if ( not scene ): return 0 return scene.chartType() def clear( self ): """ Clears the chart points from this item. """ self._points = [] self._dirty = True def color( self ): """ Returns the primary color for this item. :return <QColor> """ return QColor(self._color) def dragData(self, x=None, y=None): """ Returns any drag information that will be used from this chart item. :return <QMimeData> || None """ # look for specific drag information for this item first = (x, y) second = (x, None) third = (None, y) fourth = (None, None) for key in (first, second, third, fourth): data = self._dragData.get(key) if data: return data return None def hasCustomType( self ): """ Returns true if this item defines its own chart type. :return <bool> """ return self._chartType != None def horizontalRuler( self ): """ Returns the horizontal ruler for this widget item. :return <projexui.widgets.xchartwidget.XChartRuler> || None """ if ( not self.scene() ): return None return self.scene().horizontalRuler() def horizontalOffset( self ): """ Returns the horizontal offset for this item. :return <int> """ return self._horizontalOffset def hoverMoveEvent( self, event ): """ Tracks whether or not this item is being hovered. :param event | <QEvent> """ point = event.pos() found_key = '' found = None for key, value, subpath in self._subpaths: if subpath.contains(point): found = subpath found_key = key break if found: # update the tooltip tip = self.keyToolTip(found_key) if ( tip ): widget = self.scene().chartWidget() anchor = XPopupWidget.Anchor.RightCenter # show the popup widget XPopupWidget.showToolTip(tip, anchor = anchor, parent = widget, foreground = self.color().darker(120), background = self.alternateColor()) if ( found != self._hoveredPath ): self._hoveredPath = found self.update() def hoverLeaveEvent( self, event ): """ Tracks whether or not this item is being hovered. :param event | <QEvent> """ super(XChartWidgetItem, self).hoverEnterEvent(event) self._hoveredPath = None self.update() def isShaded( self ): """ Returns the shaded state for this item. :return <bool> """ return self._shaded def keyColor( self, key ): """ Returns a color for the inputed key (used in pie charts). :param key | <str> :return <QColor> """ self._keyColors.setdefault(nativestring(key), self.color()) return self._keyColors[nativestring(key)] def keyToolTip( self, key ): """ Returns the tool tip for this key. :param key | <str> :return <str> """ return self._keyToolTips.get(nativestring(key), '') def mousePressEvent(self, event): """ Creates the drag event for this item. :param event | <QMousePressEvent> """ near_x, near_y = self.nearestPoint(event.pos()) data = self.dragData(x=near_x, y=near_y) self.startDrag(data) super(XChartWidgetItem, self).mousePressEvent(event) def nearestPoint(self, pos): """ Returns the nearest graphing point for this item based on the inputed graph position. :param pos | <QPoint> :return (<variant> x, <variant> y) """ # lookup subpaths for x, y, path in self._subpaths: if path.contains(pos): return (x, y) return (None, None) def orientation( self ): """ Returns the orienatation for this item (used in bar charts). :return <Qt.Orienation> """ return self._orientation def paint( self, painter, option, widget ): """ Draws this item with the inputed painter. :param painter | <QPainter> rect | <QRect> """ if self._dirty: self.rebuild() scene = self.scene() if not scene: return grid = scene.gridRect() typ = self.chartType() # draw the line chart if typ == XChartScene.Type.Line: painter.setRenderHint(painter.Antialiasing) # draw the path area area = self._buildData.get('path_area') if area and self.isShaded(): clr = QColor(self.color()) clr.setAlpha(120) painter.setPen(Qt.NoPen) painter.setBrush(clr) painter.drawPath(area) # draw the line data pen = QPen(self.color()) pen.setWidth(2) painter.setPen(pen) painter.setBrush(Qt.NoBrush) painter.drawPath(self.path()) if ( self.showPointsInLine() ): palette = QApplication.palette() pen = QPen(palette.color(palette.Base)) pen.setWidth(2) painter.setBrush(self.color()) painter.setPen(pen) for point in self._ellipses: painter.drawEllipse(point, self.pointRadius(), self.pointRadius()) # draw a bar chart elif typ == XChartScene.Type.Bar: painter.setRenderHint(painter.Antialiasing) pen = QPen(self.color()) pen.setWidth(1) painter.setPen(pen) for key, value, sub_path in self._subpaths: gradient = QLinearGradient() clr = QColor(self.color()) if ( sub_path != self._hoveredPath ): clr.setAlpha(130) gradient.setColorAt(0.0, clr.lighter(140)) gradient.setColorAt(0.1, clr.lighter(120)) gradient.setColorAt(0.25, clr.lighter(110)) gradient.setColorAt(1.0, clr.lighter(105)) if ( self.orientation() == Qt.Horizontal ): gradient.setStart(0, sub_path.boundingRect().top()) gradient.setFinalStop(0, sub_path.boundingRect().bottom()) else: gradient.setStart(sub_path.boundingRect().left(), 0) gradient.setFinalStop(sub_path.boundingRect().right(), 0) painter.setBrush(gradient) painter.drawPath(sub_path) # draw a simple pie chart (calculated by scene) elif typ == XChartScene.Type.Pie: painter.setRenderHint(painter.Antialiasing) center = self.pieCenter() radius = self.radius() for key, value, sub_path in self._subpaths: clr = self.keyColor(key) gradient = QRadialGradient(QPointF(0, 0), radius) a = QColor(clr.lighter(140)) b = QColor(clr.lighter(110)) a.setAlpha(40) b.setAlpha(80) # look for mouse over if ( sub_path == self._hoveredPath ): a.setAlpha(100) b.setAlpha(200) gradient.setColorAt(0, a) gradient.setColorAt(1, b) pen = QPen(clr) pen.setWidth(1) painter.setBrush(gradient) painter.setPen(pen) painter.drawPath(sub_path) def pieAxis( self ): """ Returns the axis that is used as the pie value for this item. :return <Qt.Axis> """ return self._pieAxis def pieCenter( self ): """ Returns the center point for the pie for this item. :return <QPointF> """ return self._pieCenter def pointRadius(self): """ Returns the radius for individual points on the line. :return <int> """ return self._pointRadius def randomColor( self ): """ Generates a random color. :return <QColor> """ r = random.randint(120, 180) g = random.randint(120, 180) b = random.randint(120, 180) return QColor(r, g, b) def radius( self ): """ Returns the radius for this item for the pie chart. :return <float> """ return self._radius def rebuild( self ): """ Rebuilds the item based on the current points. """ scene = self.scene() if not scene: return self._subpaths = [] grid = scene.gridRect() typ = self.chartType() hruler = scene.horizontalRuler() vruler = scene.verticalRuler() path = QPainterPath() area = QPainterPath() self._buildData.clear() self._buildData['path_area'] = area self.setPos(0, 0) # draw a line item if typ == XChartScene.Type.Line: first = True pos = None home = None self._ellipses = [] points = self.points() if ( self.orientation() == Qt.Horizontal ): points.sort(hruler.compareValues, key = lambda x: x[0]) else: points.sort(vruler.compareValues, key = lambda y: y[1]) points.reverse() for x, y in self.points(): pos = scene.mapFromChart(x, y) if first: home = QPointF(pos.x(), grid.bottom()) area.moveTo(home) area.lineTo(pos) path.moveTo(pos) self._ellipses.append(pos) first = False else: path.lineTo(pos) area.lineTo(pos) self._ellipses.append(pos) if pos and home: area.lineTo(pos.x(), grid.bottom()) area.lineTo(home) # draw a bar item elif typ == XChartScene.Type.Bar: barsize = self.barSize() horiz = self.orientation() == Qt.Horizontal for x, y in self.points(): pos = scene.mapFromChart(x, y) subpath = QPainterPath() if horiz: r = min(grid.bottom() - pos.y(), 8) subpath.moveTo(pos.x() - barsize / 2.0, grid.bottom()) subpath.lineTo(pos.x() - barsize / 2.0, pos.y() + r) subpath.quadTo(pos.x() - barsize / 2.0, pos.y(), pos.x() - barsize / 2.0 + r, pos.y()) subpath.lineTo(pos.x() + barsize / 2.0 - r, pos.y()) subpath.quadTo(pos.x() + barsize / 2.0, pos.y(), pos.x() + barsize / 2.0, pos.y() + r) subpath.lineTo(pos.x() + barsize / 2.0, grid.bottom()) subpath.lineTo(pos.x() - barsize / 2.0, grid.bottom()) else: subpath.moveTo(grid.left(), pos.y() - barsize / 2.0) subpath.lineTo(pos.x(), pos.y() - barsize / 2.0) subpath.lineTo(pos.x(), pos.y() + barsize / 2.0) subpath.lineTo(grid.left(), pos.y() + barsize / 2.0) subpath.lineTo(grid.left(), pos.y() - barsize / 2.0) path.addPath(subpath) self._subpaths.append((x, y, subpath)) # draw a pie chart elif typ == XChartScene.Type.Pie: if self.orientation() == Qt.Horizontal: key_index = 0 value_index = 1 value_ruler = self.verticalRuler() else: key_index = 1 value_index = 0 value_ruler = self.horizontalRuler() pie_values = {} for point in self.points(): key = point[key_index] value = point[value_index] pie_values.setdefault(key, []) pie_values[key].append(value) for key, values in pie_values.items(): pie_values[key] = value_ruler.calcTotal(values) total = max(1, value_ruler.calcTotal(pie_values.values())) # calculate drawing parameters center = self.pieCenter() radius = self.radius() diameter = radius * 2 angle = 0 bound = QRectF(-radius, -radius, diameter, diameter) for key, value in sorted(pie_values.items(), key = lambda x: x[1]): # calculate the percentage perc = float(value) / total # calculate the angle as the perc * 360 item_angle = perc * 360 self.setPos(center) sub_path = QPainterPath() sub_path.arcTo(bound, angle, item_angle) sub_path.lineTo(0, 0) path.addPath(sub_path) self._subpaths.append((key, value, sub_path)) angle += item_angle self.setPath(path) self._dirty = False def points( self ): """ Returns a list of the points for this item. :return [(<variant> x, <variant> y), ..] """ return self._points def setAlternateColor( self, color ): """ Sets the alternate color for this widget to the inputed color. :param color | <QColor> """ self._alternateColor = QColor(color) def setChartType( self, chartType ): """ Sets the chart type for this item. Setting the item to a None chart type will signal it to use the default scenes chart type. :param chartType | <XChartScene.Type> """ self._chartType = chartType self._dirty = True def setColor( self, color ): """ Sets the color for this widget to the inputed color. :param color | <QColor> """ self._color = QColor(color) self.setAlternateColor(self._color.lighter(140)) def setDirty( self, state = True ): """ Sets whether or not this item is dirty. :param state | <bool> """ self._dirty def setDragData(self, data, x=None, y=None): """ Sets the drag data for this chart item to the inputed data. :param data | <QMimeData> || None """ self._dragData[(x, y)] = data def setKeyColor( self, key, color ): """ Sets the color used when rendering pie charts. :param key | <str> color | <QColor> """ self._keyColors[nativestring(key)] = QColor(color) def setKeyToolTip( self, key, tip ): """ Sets the tool tip for the specified key. :param key | <str> tip | <str> """ self._keyToolTips[nativestring(key)] = tip def setHorizontalOffset( self, offset ): """ Sets the horizontal offset for this item. :param offset | <int> """ self._horizontalOffset = offset def setPieCenter( self, center ): """ Sets the center for the pie for the chart. :param center | <QPointF> """ self._pieCenter = center def setPointRadius(self, radius): """ Sets the point radius for this line. :param radius | <int> """ self._pointRadius = radius def setPoints(self, points): """ Sets the points values for this chart widget item. :param points | [(<variant> x, <variant> y), ..] """ self._points = points[:] def setPos( self, *args ): super(XChartWidgetItem, self).setPos(*args) if ( self._horizontalOffset or self._verticalOffset ): offset = QPointF(self._horizontalOffset, self._verticalOffset) super(XChartWidgetItem, self).setPos(self.pos() + offset) def setPieAxis( self, pieAxis ): """ Sets the axis that will be used for the pie chart for this item. This will only apply when the item itself defines itself as a pie chart, otherwise, the scene will determine it when the scene is rendered as a pie chart. :param pieAxis | <Qt.Axis> """ self._pieAxis = pieAxis def setRadius( self, radius ): """ Sets the radius size for this item. :param radius | <float> """ self._radius = radius def setShaded( self, state ): """ Sets whether or not to shade line items in this graph. :param state | <bool> """ self._shaded = state def setShowPointsInLine( self, state ): """ Sets whether or not to show points in line mode. :param state | <bool> """ self._showPointsInLine = state def setTitle( self, title ): """ Sets the title text for this chart widget item. :param title | <str> """ self._title = title def startDrag(self, data): """ Starts dragging information from this chart widget based on the dragData associated with this item. """ if not data: return widget = self.scene().chartWidget() drag = QDrag(widget) drag.setMimeData(data) drag.exec_() def showPointsInLine( self ): """ Returns whether or not to show points in the line. :return <bool> """ return self._showPointsInLine def title( self ): """ Returns the title for this item. :return <str> """ return self._title def verticalRuler( self ): """ Returns the vertical ruler for this widget item. :return <projexui.widgets.xchartwidget.XChartRuler> || None """ if ( not self.scene() ): return None return self.scene().verticalRuler()
def paint( self, painter, option, widget ): """ Draws this item with the inputed painter. :param painter | <QPainter> rect | <QRect> """ if self._dirty: self.rebuild() scene = self.scene() if not scene: return grid = scene.gridRect() typ = self.chartType() # draw the line chart if typ == XChartScene.Type.Line: painter.setRenderHint(painter.Antialiasing) # draw the path area area = self._buildData.get('path_area') if area and self.isShaded(): clr = QColor(self.color()) clr.setAlpha(120) painter.setPen(Qt.NoPen) painter.setBrush(clr) painter.drawPath(area) # draw the line data pen = QPen(self.color()) pen.setWidth(2) painter.setPen(pen) painter.setBrush(Qt.NoBrush) painter.drawPath(self.path()) if ( self.showPointsInLine() ): palette = QApplication.palette() pen = QPen(palette.color(palette.Base)) pen.setWidth(2) painter.setBrush(self.color()) painter.setPen(pen) for point in self._ellipses: painter.drawEllipse(point, self.pointRadius(), self.pointRadius()) # draw a bar chart elif typ == XChartScene.Type.Bar: painter.setRenderHint(painter.Antialiasing) pen = QPen(self.color()) pen.setWidth(1) painter.setPen(pen) for key, value, sub_path in self._subpaths: gradient = QLinearGradient() clr = QColor(self.color()) if ( sub_path != self._hoveredPath ): clr.setAlpha(130) gradient.setColorAt(0.0, clr.lighter(140)) gradient.setColorAt(0.1, clr.lighter(120)) gradient.setColorAt(0.25, clr.lighter(110)) gradient.setColorAt(1.0, clr.lighter(105)) if ( self.orientation() == Qt.Horizontal ): gradient.setStart(0, sub_path.boundingRect().top()) gradient.setFinalStop(0, sub_path.boundingRect().bottom()) else: gradient.setStart(sub_path.boundingRect().left(), 0) gradient.setFinalStop(sub_path.boundingRect().right(), 0) painter.setBrush(gradient) painter.drawPath(sub_path) # draw a simple pie chart (calculated by scene) elif typ == XChartScene.Type.Pie: painter.setRenderHint(painter.Antialiasing) center = self.pieCenter() radius = self.radius() for key, value, sub_path in self._subpaths: clr = self.keyColor(key) gradient = QRadialGradient(QPointF(0, 0), radius) a = QColor(clr.lighter(140)) b = QColor(clr.lighter(110)) a.setAlpha(40) b.setAlpha(80) # look for mouse over if ( sub_path == self._hoveredPath ): a.setAlpha(100) b.setAlpha(200) gradient.setColorAt(0, a) gradient.setColorAt(1, b) pen = QPen(clr) pen.setWidth(1) painter.setBrush(gradient) painter.setPen(pen) painter.drawPath(sub_path)
class XGanttViewItem(QGraphicsRectItem): def __init__(self, treeItem): super(XGanttViewItem, self).__init__() # define custom properties self._color = QColor('white') self._alternateColor = QColor(230, 230, 230) self._highlightColor = QColor('yellow') self._alternateHighlightColor = self._highlightColor.darker(110) self._textColor = QColor('black') self._borderColor = QColor(50, 50, 50) self._progressColor = QColor(200, 200, 250) self._alternateProgressColor = QColor(180, 180, 230) self._showProgress = True self._padding = 3 self._borderRadius = 5 self._percentComplete = 0 self._text = '' self._syncing = False self._treeItem = weakref.ref(treeItem) # setup standard properties flags = self.ItemIsSelectable flags |= self.ItemIsFocusable if treeItem.flags() & Qt.ItemIsEditable: flags |= self.ItemIsMovable effect = QGraphicsDropShadowEffect() effect.setXOffset(0) effect.setYOffset(0) effect.setColor(QColor(40, 40, 40, 100)) effect.setBlurRadius(10) self.setFlags( flags ) self.setAcceptHoverEvents(True) self.setGraphicsEffect(effect) # need this flag for Qt 4.6+ try: self.setFlag(self.ItemSendsGeometryChanges) except AttributeError: pass def alternateColor( self ): """ Returns the alternate color for this widget. :return <QColor> """ return self._alternateColor def alternateHighlightColor( self ): """ Returns the alternate selection color for this item. :return <QColor> """ return self._alternateHighlightColor def alternateProgressColor( self ): """ Returns the alternate progress color that will be used when drawing a progress bar for this item. :return <QColor> """ return self._alternateProgressColor def borderColor( self ): """ Returns the border color that will be used when drawing this item. :return <QColor> """ return self._borderColor def borderRadius( self ): """ Returns the border radius for this item. :return <int> """ return self._borderRadius def color( self ): """ Returns the color for this widget. :return <QColor> """ return self._color def highlightColor( self ): """ Returns the primary color used for highlighting this view item. :return <QColor> """ return self._highlightColor def isSyncing( self ): """ Return whether or not this item is syncing. :return <bool> """ return self._syncing def itemChange( self, change, value ): """ Overloads the base QGraphicsItem itemChange method to block user ability to move along the y-axis. :param change <int> :param value <variant> :return <variant> """ # only operate when it is a visible, geometric change if not (self.isVisible() and change == self.ItemPositionChange): return super(XGanttViewItem, self).itemChange( change, value ) if self.isSyncing(): return super(XGanttViewItem, self).itemChange(change, value) scene = self.scene() # only operate when we have a scene if not scene: return super(XNode, self).itemChange( change, value ) point = value.toPointF() point.setY(self.pos().y()) # create the return value new_value = wrapVariant(point) # call the base method to operate on the new point return super(XGanttViewItem, self).itemChange(change, new_value) def itemStyle(self): """ Returns the style that this item will be rendered as. :return <XGanttWidgetItem.ItemStyle> """ item = self.treeItem() if item: return item.itemStyle() return 0 def mouseReleaseEvent(self, event): """ Overloads the mouse release event to apply the current changes. :param event | <QEvent> """ super(XGanttViewItem, self).mouseReleaseEvent(event) if not self.flags() & self.ItemIsMovable: return # force the x position to snap to the nearest date scene = self.scene() if scene: gantt = scene.ganttWidget() curr_x = self.pos().x() + gantt.cellWidth() / 2.0 new_x = curr_x - curr_x % gantt.cellWidth() self.setPos(new_x, self.pos().y()) # look for date based times gantt = self.scene().ganttWidget() # determine hour/minute information if gantt.timescale() in (gantt.Timescale.Minute, gantt.Timescale.Hour, gantt.Timescale.Day): dstart = self.scene().datetimeAt(self.pos().x()) dend = self.scene().datetimeAt(self.pos().x() + self.rect().width()) dend.addSecs(-60) else: dstart = self.scene().dateAt(self.pos().x()) dend = self.scene().dateAt(self.pos().x() + self.rect().width()) dend = dend.addDays(-1) item = self._treeItem() if item: item.viewChanged(dstart, dend) def padding( self ): """ Returns the top and bottom padding for this item. :return <int> """ return self._padding def paint( self, painter, option, widget ): """ Paints this item to the system. :param painter | <QPainter> option | <QStyleOptionGraphicItem> widget | <QWidget> """ style = self.itemStyle() ItemStyle = self.treeItem().ItemStyle if ( style == ItemStyle.Group ): self.paintGroup( painter ) elif ( style == ItemStyle.Milestone ): self.paintMilestone( painter ) else: self.paintNormal( painter ) def paintGroup( self, painter ): """ Paints this item as the group look. :param painter | <QPainter> """ # generate the rect rect = self.rect() padding = self.padding() gantt = self.scene().ganttWidget() cell_w = gantt.cellWidth() cell_h = gantt.cellHeight() x = 0 y = self.padding() w = rect.width() h = rect.height() - (padding + 1) # grab the color options color = self.color() alt_color = self.alternateColor() if ( self.isSelected() ): color = self.highlightColor() alt_color = self.alternateHighlightColor() # create the background brush gradient = QLinearGradient() gradient.setStart(0, 0) gradient.setFinalStop(0, h) gradient.setColorAt(0, color) gradient.setColorAt(0.8, alt_color) gradient.setColorAt(1, color) painter.setPen(self.borderColor()) painter.setBrush(QBrush(gradient)) pen = painter.pen() pen.setWidthF(0.5) painter.setPen(pen) painter.setRenderHint( painter.Antialiasing ) path = QPainterPath() path.moveTo(x - cell_w / 4.0, y) path.lineTo(w + cell_w / 4.0, y) path.lineTo(w + cell_w / 4.0, y + h / 2.0) path.lineTo(w, h) path.lineTo(w - cell_w / 4.0, y + h / 2.0) path.lineTo(x + cell_w / 4.0, y + h / 2.0) path.lineTo(x, h) path.lineTo(x - cell_w / 4.0, y + h / 2.0) path.lineTo(x - cell_w / 4.0, y) painter.drawPath(path) # create the progress brush if ( self.showProgress() ): gradient = QLinearGradient() gradient.setStart(0, 0) gradient.setFinalStop(0, h) gradient.setColorAt(0, self.progressColor()) gradient.setColorAt(0.8, self.alternateProgressColor()) gradient.setColorAt(1, self.progressColor()) prog_w = (w - 4) * (self._percentComplete/100.0) painter.setPen(Qt.NoPen) painter.setBrush(QBrush(gradient)) painter.drawRect(x, y, prog_w, y + h / 2.0) # draw the text on this item if ( self.text() ): painter.setPen(self.textColor()) painter.drawText(x, y, w, h, Qt.AlignCenter, self.text()) def paintMilestone( self, painter ): """ Paints this item as the milestone look. :param painter | <QPainter> """ # generate the rect rect = self.rect() padding = self.padding() gantt = self.scene().ganttWidget() cell_w = gantt.cellWidth() cell_h = gantt.cellHeight() x = rect.width() - cell_w y = self.padding() w = cell_w h = rect.height() - padding - 2 # grab the color options color = self.color() alt_color = self.alternateColor() if ( self.isSelected() ): color = self.highlightColor() alt_color = self.alternateHighlightColor() # create the background brush gradient = QLinearGradient() gradient.setStart(0, 0) gradient.setFinalStop(0, h) gradient.setColorAt(0, color) gradient.setColorAt(0.8, alt_color) gradient.setColorAt(1, color) painter.setPen(self.borderColor()) painter.setBrush(QBrush(gradient)) pen = painter.pen() pen.setWidthF(0.5) painter.setPen(pen) painter.setRenderHint( painter.Antialiasing ) path = QPainterPath() path.moveTo(x - cell_w / 3.0, y + h / 2.0) path.lineTo(x, y) path.lineTo(x + cell_w / 3.0, y + h / 2.0) path.lineTo(x, y + h) path.lineTo(x - cell_w / 3.0, y + h / 2.0) painter.drawPath(path) def paintNormal( self, painter ): """ Paints this item as the normal look. :param painter | <QPainter> """ # generate the rect rect = self.rect() x = 0 y = self.padding() w = rect.width() h = rect.height() - (2 * self.padding()) - 1 radius = self.borderRadius() # grab the color options color = self.color() alt_color = self.alternateColor() if ( self.isSelected() ): color = self.highlightColor() alt_color = self.alternateHighlightColor() # create the background brush gradient = QLinearGradient() gradient.setStart(0, 0) gradient.setFinalStop(0, h) gradient.setColorAt(0, color) gradient.setColorAt(0.8, alt_color) gradient.setColorAt(1, color) painter.setPen(self.borderColor()) if ( radius ): painter.setRenderHint(painter.Antialiasing) pen = painter.pen() pen.setWidthF(0.5) painter.setPen(pen) painter.setBrush(QBrush(gradient)) painter.drawRoundedRect(x, y, w, h, radius, radius) # create the progress brush if ( self.showProgress() ): gradient = QLinearGradient() gradient.setStart(0, 0) gradient.setFinalStop(0, h) gradient.setColorAt(0, self.progressColor()) gradient.setColorAt(0.8, self.alternateProgressColor()) gradient.setColorAt(1, self.progressColor()) prog_w = (w - 4) * (self._percentComplete/100.0) radius -= 2 painter.setPen(Qt.NoPen) painter.setBrush(QBrush(gradient)) painter.drawRoundedRect(x + 2, y + 2, prog_w, h - 4, radius, radius) # draw the text on this item if ( self.text() ): painter.setPen(self.textColor()) painter.drawText(x, y, w, h, Qt.AlignCenter, self.text()) def percentComplete( self ): """ Returns the percent complete that this item is in. :return <int> """ return self._percentComplete def progressColor( self ): """ Returns the color that will be displayed with the progress bar for this widget. :return <QColor> """ return self._progressColor def setAlternateColor( self, color ): """ Sets the alternate color for this widget to the inputed color. :param color | <QColor> """ self._alternateColor = QColor(color) def setAlternateProgressColor( self, color ): """ Sets the alternate progress color that will be used when drawing a progress bar for this item. :return <QColor> """ self._alternateProgressColor = QColor(color) def setAlternateHighlightColor( self, color ): """ Sets the alternate selection color for this item to the inputed color. :param color | <QColor> """ self._alternateHighlightColor = QColor(color) def setBorderRadius( self, radius ): """ Sets the radius that will be used for this item to the inputed radius. :param radius | <int> """ self._borderRadius = radius def setColor( self, color ): """ Sets the color for this widget. :param color | <QColor> || <str> """ self._color = QColor(color) self.setAlternateColor(self._color.darker(110)) def setHighlightColor( self, color ): """ Sets the primary color used for highlighting this item. :param color | <QColor> """ self._highlightColor = QColor(color) self.setAlternateHighlightColor(self._highlightColor.darker(110)) def setPadding( self, padding ): """ Sets the padding that will be used to pad the top and bottom for this item. :param padding | <int> """ self._padding = padding def setPercentComplete( self, percent ): """ Sets the completion percentage for this item to the inputed amount. :param percent | <int> """ self._percentComplete = percent def setProgressColor( self, color ): """ Sets the color that for the progress bar for this item. :param color | <QColor> """ self._progressColor = QColor(color) self.setAlternateProgressColor(self._progressColor.darker(110)) def setShowProgress( self, state ): """ Sets whether or not the progress information should be displayed. :param state | <bool> """ self._showProgress = state def setSyncing( self, state ): """ Sets whether or not this item is syncing. :param state | <bool> """ self._syncing = state def setText( self, text ): """ Sets the text for this item. :param text | <str> """ self._text = text def setTextColor( self, color ): """ Sets the color that will be used for this widget's text. :param color | <QColor> || <str> """ self._textColor = QColor(color) def showProgress( self ): """ Returns whether or not the progress should be displayed for this item. :return <bool> """ return self._showProgress def text( self ): """ Returns the text for this widget. :return <str> """ return self._text def textColor( self ): """ Returns the text color that will be used for this item's text. :return <QColor> """ return self._textColor def treeItem( self ): """ Returns the tree item that is linked with this view item. :return <XGanttWidgetItem> """ return self._treeItem()