def drawBackground(self, painter, rect): super(GridView, self).drawBackground(painter, rect) if self._show_grid: scene_rect = self.sceneRect() left = int(scene_rect.left()) - (int(scene_rect.left()) % self._draw_grid_size) top = int(scene_rect.top()) - (int(scene_rect.top()) % self._draw_grid_size) scale_mult = 1.0 lines = list() left_line = rect.left() - rect.left() % self._grid_size top_line = rect.top() - rect.top() % self._grid_size i = int(left_line) while i < int(rect.right()): lines.append(QLineF(i, rect.top(), i, rect.bottom())) i += self._grid_size u = int(top_line) while u < int(rect.bottom()): lines.append(QLineF(rect.left(), u, rect.right(), u)) u += self._grid_size # TODO: Change pen to a class variable (avoid to create a pen each drawing frame) pen = QPen() pen.setWidth(0) pen.setColor(QColor(20, 20, 20)) painter.setPen(pen) painter.drawLines(lines)
def main(): import sys app = QApplication(sys.argv) series0 = QLineSeries() series1 = QLineSeries() series0 << QPointF(1, 5) << QPointF(3, 7) << QPointF(7, 6) << QPointF( 9, 7) << QPointF(12, 6) << QPointF(16, 7) << QPointF(18, 5) series1 << QPointF(1, 3) << QPointF(3, 4) << QPointF(7, 3) << QPointF( 8, 2) << QPointF(12, 3) << QPointF(16, 4) << QPointF(18, 3) series = QAreaSeries(series0, series1) series.setName("Batman") pen = QPen(0x059605) pen.setWidth(3) series.setPen(pen) gradient = QLinearGradient(QPointF(0, 0), QPointF(0, 1)) gradient.setColorAt(0.0, QColor(0x3CC63C)) gradient.setColorAt(1.0, QColor(0x26F626)) gradient.setCoordinateMode(QGradient.ObjectBoundingMode) series.setBrush(gradient) chart = QChart() chart.addSeries(series) chart.setTitle("Simple areachart example") chart.createDefaultAxes() chart.axes(Qt.Horizontal)[0].setRange(0, 20) chart.axes(Qt.Vertical)[0].setRange(0, 10) chartView = QChartView(chart) chartView.setRenderHint(QPainter.Antialiasing) window = QMainWindow() window.setCentralWidget(chartView) window.resize(400, 300) window.show() sys.exit(app.exec_())
def set_badge(self, x, y, w, h, color=None): """ Set badge for the icon :param x: int :param y: int :param w: int :param h: int :param color: QColor or None """ color = color or QColor(240, 100, 100) size = self.actualSize(QSize(256, 256)) pixmap = self.pixmap(size) painter = QPainter(pixmap) pen = QPen(color) pen.setWidth(0) painter.setPen(pen) painter.setBrush(color) painter.setRenderHint(QPainter.Antialiasing) painter.drawEllipse(x, y, w, h) painter.end() icon = Icon(pixmap) self.swap(icon)
def paintEvent(self, event): painter = QPainter() painter.begin(self) painter.setRenderHint(painter.Antialiasing) font = painter.font() font.setBold(True) painter.setFont(font) x = self.rect().x() y = self.rect().y() w = self.rect().width() - 1 h = self.rect().height() - 1 _rect = 8 if self.rollout_style == AccordionStyle.ROUNDED: painter.drawText(x + 33 if not self._icon else 40, y + 3, w, 16, Qt.AlignLeft | Qt.AlignTop, self.title()) self._draw_triangle(painter, x, y) self._draw_icon(painter, x + 22, y + 3) pen = QPen(self.palette().color(QPalette.Light)) pen.setWidthF(0.6) painter.setPen(pen) painter.drawRoundedRect(x + 1, y + 1, w - 1, h - 1, _rect, _rect) pen.setColor(self.palette().color(QPalette.Shadow)) painter.setPen(pen) painter.drawRoundedRect(x, y, w - 1, h - 1, _rect, _rect) elif self.rollout_style == AccordionStyle.SQUARE: painter.drawText(x + 33 if not self._icon else 40, y + 3, w, 16, Qt.AlignLeft | Qt.AlignTop, self.title()) self._draw_triangle(painter, x, y) self._draw_icon(painter, x + 22, y + 3) pen = QPen(self.palette().color(QPalette.Light)) pen.setWidthF(0.3) painter.setPen(pen) painter.drawRect(x + 1, y + 1, w - 1, h - 1) pen.setColor(self.palette().color(QPalette.Shadow)) painter.setPen(pen) elif self.rollout_style == AccordionStyle.MAYA: painter.drawText(x + 33 if not self._icon else 40, y + 3, w, 16, Qt.AlignLeft | Qt.AlignTop, self.title()) painter.setRenderHint(QPainter.Antialiasing, False) self._draw_triangle(painter, x, y) self._draw_icon(painter, x + 22, y + 3) header_height = 20 header_rect = QRect(x + 1, y + 1, w - 1, header_height) header_rect_shadow = QRect(x - 1, y - 1, w + 1, header_height + 2) pen = QPen(self.palette().color(QPalette.Light)) pen.setWidthF(0.4) painter.setPen(pen) painter.drawRect(header_rect) painter.fillRect(header_rect, QColor(255, 255, 255, 18)) pen.setColor(self.palette().color(QPalette.Dark)) painter.setPen(pen) painter.drawRect(header_rect_shadow) if not self.is_collapsed(): pen = QPen(self.palette().color(QPalette.Dark)) pen.setWidthF(0.8) painter.setPen(pen) offset = header_height + 3 body_rect = QRect(x, y + offset, w, h - offset) body_rect_shadow = QRect(x + 1, y + offset, w + 1, h - offset + 1) painter.drawRect(body_rect) pen.setColor(self.palette().color(QPalette.Light)) pen.setWidth(0.4) painter.setPen(pen) painter.drawRect(body_rect_shadow) elif self.rollout_style == AccordionStyle.BOXED: if self.is_collapsed(): a_rect = QRect(x + 1, y + 9, w - 1, 4) b_rect = QRect(x, y + 8, w - 1, 4) text = '+' else: a_rect = QRect(x + 1, y + 9, w - 1, h - 9) b_rect = QRect(x, y + 8, w - 1, h - 9) text = '-' pen = QPen(self.palette().color(QPalette.Light)) pen.setWidthF(0.6) painter.setPen(pen) painter.drawRect(a_rect) pen.setColor(self.palette().color(QPalette.Shadow)) painter.setPen(pen) painter.drawRect(b_rect) painter.setRenderHint(painter.Antialiasing, False) painter.setBrush(self.palette().color(QPalette.Window).darker(120)) painter.drawRect(x + 10, y + 1, w - 20, 16) painter.drawText(x + 16, y + 1, w - 32, 16, Qt.AlignLeft | Qt.AlignVCenter, text) painter.drawText(x + 10, y + 1, w - 20, 16, Qt.AlignCenter, self.title()) if self.drag_drop_mode: rect = self.get_drag_drop_rect() _layout = rect.left() _rect = rect.right() center_y = rect.center().y() for y in (center_y - 3, center_y, center_y + 3): painter.drawLine(_layout, y, _rect, y) painter.end()
class CurveNodeItem(QGraphicsItem, object): curveUpdated = Signal() WIDTH = 10 def __init__(self, rect=None, parent=None): self.signals = CurveNodeItemSignals() gradient = QRadialGradient( self.WIDTH * 0.75, self.WIDTH * 0.75, self.WIDTH * 0.75, self.WIDTH * 0.75, self.WIDTH * 0.75) gradient.setColorAt(0, self.theme().accent_color_6 if self.theme() else QColor.fromRgbF(1, 0.5, 0.01, 1)) gradient.setColorAt(1, self.theme().accent_color_8 if self.theme() else QColor.fromRgbF(1, 0.6, 0.06, 1)) self._brush = QBrush(gradient) self._brush.setStyle(Qt.RadialGradientPattern) self._pen = QPen() self._pen.setStyle(Qt.SolidLine) self._pen.setWidth(2) self._pen.setColor(self.theme().accent_color if self.theme() else QColor(104, 104, 104, 255)) self._selected_pen = QPen() self._selected_pen.setStyle(Qt.SolidLine) self._selected_pen.setWidth(3) self._selected_pen.setColor(self.theme().accent_color_4 if self.theme() else QColor(67, 255, 163, 255)) super(CurveNodeItem, self).__init__(parent) self._lock_x_pos = False self._snap = False self._current_pos = None self._new_pos = None self._line = None self._is_point1 = False self.set_rect(rect if rect else QRect(0, 0, 10, 10)) self.setFlags( QGraphicsItem.ItemIsMovable | QGraphicsItem.ItemIsSelectable | QGraphicsItem.ItemSendsScenePositionChanges) @property def snap(self): return self._snap @snap.setter def snap(self, flag): self._snap = bool(flag) @property def lock_x_pos(self): return self._lock_x_pos @lock_x_pos.setter def lock_x_pos(self, value): self._lock_x_pos = value def boundingRect(self): return QRectF(0, 0, 20, 20) def paint(self, painter, option, widget): painter.setBrush(self._brush) painter.setPen(self._selected_pen if self.isSelected() else self._pen) painter.drawEllipse(self._rect) def mousePressEvent(self, event): self._current_pos = self.pos() super(CurveNodeItem, self).mousePressEvent(event) def mouseMoveEvent(self, event): super(CurveNodeItem, self).mouseMoveEvent(event) curve_offset = -self.WIDTH * 0.5 scale_x = min(max(event.scenePos().x(), curve_offset), self.scene().base_size + curve_offset) scale_y = min(max(event.scenePos().y(), curve_offset), self.scene().base_size + curve_offset) if self._lock_x_pos: scale_x = self._lock_x_pos if self._snap is not False: scale_x = round((float(scale_x) / self._snap)) * self._snap scale_y = round((float(scale_y) / self._snap)) * self._snap self._new_pos = QPointF(scale_x, scale_y) self.setPos(self._new_pos) self.scene().update_curve() self.signals.curveUpdated.emit() def mouseReleaseEvent(self, event): super(CurveNodeItem, self).mouseReleaseEvent(event) if not self._new_pos: return self.scene().undo_stack.push(CurveNodeMoveUndoCommand(self.scene(), self, self._current_pos, self._new_pos)) self._new_pos = None def itemChange(self, change, value): if change == self.ItemPositionChange and self.scene(): new_pos = value self._move_line_to_center(new_pos) return super(CurveNodeItem, self).itemChange(change, value) def set_rect(self, rect): self._rect = rect self.update() def add_line(self, line, is_point1): self._line = line self._is_point1 = is_point1 self._move_line_to_center(self.pos()) def _move_line_to_center(self, new_pos): if not self._line: return x_offset = self._rect.x() - self._rect.width() / 2 y_offset = self._rect.y() - self._rect.height() / 2 new_center_pos = QPointF(new_pos.x() - x_offset, new_pos.y() - y_offset) p1 = new_center_pos if self._is_point1 else self._line.line().p1() p2 = self._line.line().p2() if self._is_point1 else new_center_pos self._line.setLine(QLineF(p1, p2))
class GridScene(BaseScene, object): """ Scene with grid background drawing support """ def __init__(self, grid_main_spacing=8, grid_secondary_spacing=8, grid_main_pen_color=GridColors.BaseColor, grid_secondary_pen_color=GridColors.DarkerColor, grid_main_width=1, grid_secondary_width=1, grid_main_style=Qt.SolidLine, grid_secondary_style=Qt.SolidLine, draw_main_grid=True, draw_secondary_grid=True, fit_grid=False, fit_grid_main_divisions=10, fit_grid_secondary_divisions=4, parent=None): super(GridScene, self).__init__(parent=parent) self._grid_main_pen = QPen() self._grid_secondary_pen = QPen() self._grid_main_spacing = grid_main_spacing self._grid_secondary_spacing = grid_secondary_spacing self._grid_main_pen.setColor(grid_main_pen_color) self._grid_secondary_pen.setColor(grid_secondary_pen_color) self._grid_main_pen.setWidth(grid_main_width) self._grid_secondary_pen.setWidth(grid_secondary_width) self._grid_main_style = grid_main_style self._grid_secondary_style = grid_secondary_style self._draw_main_grid = draw_main_grid self._draw_secondary_grid = draw_secondary_grid self._fit_grid = fit_grid self._fit_grid_main_divisions = fit_grid_main_divisions self._fit_grid_secondary_divisions = fit_grid_secondary_divisions self._grid_main_pen.setStyle(self._grid_main_style) self._grid_secondary_pen.setStyle(self._grid_secondary_style) self._fit_grid_draw = False @decorators.accepts(int) def set_grid_main_spacing(self, value): """ Set the size of the main grid (define the gap between grid lines) """ self._grid_main_spacing = value @decorators.accepts(int) def set_grid_secondary_spacing(self, value): """ Set the size of the secondary grid """ self._grid_secondary_spacing = value @decorators.returns(int) def get_grid_main_spacing(self): """ Returns the size of the main grid :return: int, size of the main grid """ return self._grid_main_spacing @decorators.returns(int) def get_grid_secondary_spacing(self): """ Returns the size of the secondary grid :return: int, size of the secondary grid """ return self._grid_secondary_spacing @decorators.accepts(QColor) def set_main_pen_color(self, value): self._grid_main_pen.setColor(value) @decorators.returns(QColor) def get_main_pen_color(self): return self._grid_main_pen.color() @decorators.accepts(QColor) def set_secondary_pen_color(self, value): self._grid_secondary_pen.setColor(value) @decorators.returns(QColor) def get_secondary_pen_color(self): return self._grid_secondary_pen.color() @decorators.accepts(float) def set_grid_width(self, value): self._grid_main_pen.setWidth(value) self._grid_secondary_pen.setWidth(value) @decorators.returns(float) def get_grid_width(self): return self._grid_main_pen.width() @decorators.returns(bool) def get_draw_main_grid(self): return self._draw_main_grid @decorators.accepts(bool) def set_draw_main_grid(self, draw): self._draw_main_grid = draw @decorators.returns(bool) def get_draw_secondary_grid(self): return self._draw_secondary_grid @decorators.accepts(bool) def set_draw_secondary_grid(self, draw): self._draw_secondary_grid = draw @decorators.returns(bool) def get_fit_grid(self): return self._fit_grid @decorators.accepts(bool) def set_fit_grid(self, fit): self._fit_grid = fit grid_main_spacing = property(get_grid_main_spacing, set_grid_main_spacing) grid_secondary_spacing = property(get_grid_secondary_spacing, set_grid_secondary_spacing) grid_main_pen_color = property(get_main_pen_color, set_main_pen_color) grid_secondary_pen_color = property(get_secondary_pen_color, set_secondary_pen_color) grid_width = property(get_grid_width, set_grid_width) draw_main_grid = property(get_draw_main_grid, set_draw_main_grid) draw_secondary_grid = property(get_draw_secondary_grid, set_draw_secondary_grid) fit_grid = property(get_fit_grid, set_fit_grid) # region Override Functions def drawBackground(self, painter, rect): """ Draw grid background for the graph scene """ scene_rect = self.sceneRect() gradient = QColor(65, 65, 65) painter.fillRect(rect.intersected(scene_rect), QBrush(gradient)) painter.setPen(QPen()) painter.drawRect(scene_rect) if len(self.views()) <= 0: LOGGER.error('Scene has not view associated to it!') return if not self.views()[0]: LOGGER.error('View {0} is not valid!'.format(self.views()[0])) return if hasattr(self.views()[0], 'is_grid_visible'): if self.views()[0].is_grid_visible: return if self._fit_grid: if not self._fit_grid_draw: if self._draw_main_grid: pos = float(self.width() / self._fit_grid_main_divisions) for div in range(self._fit_grid_main_divisions): if div == 0: continue line = QGraphicsLineItem(0, pos * div, self.width(), pos * div) line.setZValue(-1) line.setPen(self._grid_main_pen) self.addItem(line) line = QGraphicsLineItem(pos * div, 0, pos * div, self.width()) line.setZValue(-1) line.setPen(self._grid_main_pen) self.addItem(line) rect = QGraphicsRectItem(self.sceneRect()) rect.setZValue(-1) self.addItem(rect) if self._draw_secondary_grid: pos = float(self.width() / self._fit_grid_secondary_divisions) for div in range(self._fit_grid_secondary_divisions): if div == 0: continue line = QGraphicsLineItem(0, pos * div, self.width(), pos * div) line.setZValue(-1) line.setPen(self._grid_secondary_pen) self.addItem(line) line = QGraphicsLineItem(pos * div, 0, pos * div, self.width()) line.setZValue(-1) line.setPen(self._grid_secondary_pen) self.addItem(line) rect = QGraphicsRectItem(self.sceneRect()) rect.setZValue(-1) self.addItem(rect) self._fit_grid_draw = True else: if self._draw_main_grid: left = int(self.sceneRect().left()) - (int(self.sceneRect().left()) % self._grid_main_spacing) top = int(self.sceneRect().top()) - (int(self.sceneRect().top()) % self._grid_main_spacing) painter.setPen(self._grid_main_pen) # draw grid vertical lines for x in range(left, int(self.sceneRect().right()), self.grid_main_spacing): painter.drawLine(x, self.sceneRect().top(), x, self.sceneRect().bottom()) # draw grid horizontal lines for y in range(top, int(self.sceneRect().bottom()), self.grid_main_spacing): painter.drawLine(self.sceneRect().left(), y, self.sceneRect().right(), y) if self._draw_secondary_grid: left = int(self.sceneRect().left()) - (int(self.sceneRect().left()) % self._grid_secondary_spacing) top = int(self.sceneRect().top()) - (int(self.sceneRect().top()) % self._grid_secondary_spacing) painter.setPen(self._grid_secondary_pen) # draw grid vertical lines for x in range(left, int(self.sceneRect().right()), self.grid_secondary_spacing * 10): painter.drawLine(x, self.sceneRect().top(), x, self.sceneRect().bottom()) # draw grid horizontal lines for y in range(top, int(self.sceneRect().bottom()), self.grid_secondary_spacing * 10): painter.drawLine(self.sceneRect().left(), y, self.sceneRect().right(), y)