def paint(self, painter, option, index): QItemDelegate.paint(self, painter, option, index) column = index.column() row = index.row() rect = option.rect # Draw borders pen = QPen() pen.setWidth(1) pen.setColor(QColor('#cdcdcd')) painter.setPen(pen) painter.drawLine(rect.topLeft(), rect.topRight()) if (row == self.current_hover_row() or row == self.current_row() and (self.has_focus_or_context())): brush = QBrush(Qt.SolidPattern) brush.setColor(QColor(255, 255, 255, 100)) painter.fillRect(rect, brush) if row == self.current_row() and column in [const.COL_START]: pen = QPen() pen.setWidth(10) pen.setColor(QColor('#7cbb4c')) painter.setPen(pen) dyt = QPoint(0, 5) dyb = QPoint(0, 4) painter.drawLine(rect.bottomLeft()-dyb, rect.topLeft()+dyt)
def __init__(self, anchor, parent=None): QGraphicsObject.__init__(self, parent=parent) MapItem.__init__(self) self.setZValue(200.0) anchorPos = self._posForAnchors[anchor] self._anchorPos = QPointF(anchorPos) self._anchor = anchor self._border = QGraphicsRectItem(parent=self) self._border.setPen(QPen(Qt.NoPen)) self._border.setBrush(QBrush(QColor(190, 190, 190, 160))) self._entries = list() imgfile = os.path.dirname(__file__) + os.sep + 'zoom_in_symbol.png' img = QPixmap(24, 24) img.load(imgfile) img = img.scaled(24, 24) img = ImageButton(img, parent=self) self.zoom_in_button = img self.addEntry(self.zoom_in_button) imgfile = os.path.dirname(__file__) + os.sep + 'zoom_out_symbol.png' img2 = QPixmap(24, 24) img2.load(imgfile) img2 = img2.scaled(24, 24) img2 = ImageButton(img2, parent=self) self.zoom_out_button = img2 self.addEntry(self.zoom_out_button)
def paintEvent(self, event): painter = QPainter(self) painter.setRenderHints(QPainter.Antialiasing) if self.label_width <= 0: return painter.setPen(Qt.NoPen) if self.hover: painter.setBrush( QColor(self.back_color.red() + 30, self.back_color.green() + 30, self.back_color.blue() + 30)) else: painter.setBrush(self.back_color) painter.drawRoundedRect(QRect(0, 0, self.width(), self.height()), self.border_radius, self.border_radius) x1 = QPointF(self.label_width + float(self.height() / 3), float(self.height() * 0.45)) x2 = QPointF( self.label_width + float(self.height() * (0.66 + self.rate) / 2), float(self.height() * 0.55)) x3 = QPointF(self.width() - float(self.height() / 3), float(self.height() * 0.45)) check_path = QPainterPath() check_path.moveTo(x1) check_path.lineTo(x2) check_path.lineTo(x3) pen = QPen(self.text_color, self.drop_thick, Qt.SolidLine) painter.setPen(pen) painter.drawPath(check_path)
def __init__(self, parent=None, circle=False): super(PyDMBitIndicator, self).__init__(parent) self.setAutoFillBackground(True) self.circle = circle self._painter = QPainter() self._brush = QBrush(Qt.SolidPattern) self._pen = QPen(Qt.SolidLine)
def paint(self, p, *args): ''' Overrides the default implementation so as to draw a vertical marker. ''' # draw the text super(LineIDMarker, self).paint(p, args) # Add marker. Geometry depends on the # text being vertical or horizontal. points = [] bounding_rect = self.boundingRect() if self._orientation == 'vertical': x = bounding_rect.x() y = bounding_rect.y() + bounding_rect.height() / 2. points.append(QPointF(x, y)) points.append(QPointF(x - 20, y)) else: x = bounding_rect.x() + bounding_rect.width() / 2. y = bounding_rect.y() + bounding_rect.height() * 2. points.append(QPointF(x, y)) points.append(QPointF(x, y - 20)) polygon = QPolygonF(points) pen = QPen(QColor(functions.mkColor(self._color))) p.setPen(pen) p.drawPolygon(polygon)
def paintEvent(self, event): painter = QPainter(self) painter.setRenderHints(QPainter.Antialiasing) side = min(self.width(), self.height()) painter.scale(side / 32.0, side / 32.0) painter.setPen(Qt.NoPen) if not self.is_pressed: painter.setBrush(self.back_color) else: painter.setBrush( QColor(self.back_color.red() + 30, self.back_color.green() + 30, self.back_color.blue() + 30)) painter.drawRoundedRect(QRect(0, 0, 32, 32), 8, 8) if self.is_checked: check_path = QPainterPath() check_path.moveTo(self.x1) check_path.lineTo(self.x2) check_path.lineTo(self.x3) pen = QPen(self.check_color, self.check_thick, Qt.SolidLine) painter.setPen(pen) painter.drawPath(check_path)
def qwtDrawRectSymbols(painter, points, numPoints, symbol): size = symbol.size() pen = QPen(symbol.pen()) pen.setJoinStyle(Qt.MiterJoin) painter.setPen(pen) painter.setBrush(symbol.brush()) painter.setRenderHint(QPainter.Antialiasing, False) sw = size.width() sh = size.height() sw2 = 0.5 * size.width() sh2 = 0.5 * size.height() for pos in points: x = pos.x() y = pos.y() r = QRectF(x - sw2, y - sh2, sw, sh) painter.drawRect(r)
def paint(self, painter: QPainter, style: QStyleOptionViewItem, model: QModelIndex): if model.data() not in image_dict: image_dict[model.data()] = create_colormap_image( model.data(), self.color_dict) rect = QRect(style.rect.x(), style.rect.y() + 2, style.rect.width(), style.rect.height() - 4) painter.drawImage(rect, image_dict[model.data()]) if int(style.state & QStyle.State_HasFocus): painter.save() pen = QPen() pen.setWidth(5) painter.setPen(pen) painter.drawRect(rect) painter.restore()
def _draw_rect(self, rect, painter): """ Draw the background rectangle using the current style primitive color. :param rect: The fold zone rect to draw :param painter: The widget's painter. """ c = self.editor.sideareas_color grad = QLinearGradient(rect.topLeft(), rect.topRight()) if sys.platform == 'darwin': grad.setColorAt(0, c.lighter(100)) grad.setColorAt(1, c.lighter(110)) outline = c.darker(110) else: grad.setColorAt(0, c.lighter(110)) grad.setColorAt(1, c.lighter(130)) outline = c.darker(100) painter.fillRect(rect, grad) painter.setPen(QPen(outline)) painter.drawLine(rect.topLeft() + QPointF(1, 0), rect.topRight() - QPointF(1, 0)) painter.drawLine(rect.bottomLeft() + QPointF(1, 0), rect.bottomRight() - QPointF(1, 0)) painter.drawLine(rect.topRight() + QPointF(0, 1), rect.bottomRight() - QPointF(0, 1)) painter.drawLine(rect.topLeft() + QPointF(0, 1), rect.bottomLeft() - QPointF(0, 1))
def __init__(self, camera, **settings): super(CroppableCameraView, self).__init__() self.setRenderHint(QPainter.Antialiasing) self.cam = camera self.is_live = False self._cmin = 0 self._cmax = None self.settings = settings self._selecting = False self.needs_resize = False self.latest_array = None self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.scene = QGraphicsScene() #self.setFrameStyle(QFrame.NoFrame) self.setScene(self.scene) self.pixmapitem = self.scene.addPixmap(QPixmap()) self._uncropped_pixmap = None self.setMouseTracking(True) self.start = None c1 = QColor(0, 100, 220, 150) self.c2 = QColor(0, 100, 220, 50) self.c3 = QColor(0, 100, 220, 0) pen = QPen(c1, 2) self.selrect = self.scene.addRect(1, 1, 1, 1, pen, self.c3) self.selrect.setZValue(100) self.selrect.hide()
def test_update(self): obj = QPen(Qt.red, 2, Qt.SolidLine) ls = LineStyleParam(_("Line style")) ls.update_param(obj) self.assertEqual(ls.width, 2) self.assertEqual(ls.style, "SolidLine") self.assertEqual(ls.color, "#ff0000")
def _draw_rect(self, rect, painter): """ Draw the background rectangle using the current style primitive color or foldIndicatorBackground if nativeFoldingIndicator is true. :param rect: The fold zone rect to draw :param painter: The widget's painter. """ c = self._custom_color if self._native: c = self.get_system_bck_color() grad = QLinearGradient(rect.topLeft(), rect.topRight()) if sys.platform == 'darwin': grad.setColorAt(0, c.lighter(100)) grad.setColorAt(1, c.lighter(110)) outline = c.darker(110) else: grad.setColorAt(0, c.lighter(110)) grad.setColorAt(1, c.lighter(130)) outline = c.darker(100) painter.fillRect(rect, grad) painter.setPen(QPen(outline)) painter.drawLine(rect.topLeft() + QPointF(1, 0), rect.topRight() - QPointF(1, 0)) painter.drawLine(rect.bottomLeft() + QPointF(1, 0), rect.bottomRight() - QPointF(1, 0)) painter.drawLine(rect.topRight() + QPointF(0, 1), rect.bottomRight() - QPointF(0, 1)) painter.drawLine(rect.topLeft() + QPointF(0, 1), rect.bottomLeft() - QPointF(0, 1))
def drawWidget(self, qp): size = self.size() w = size.width() h = size.height() lower_threshold = self.margin * self.range upper_threshold = (1 - self.margin) * self.range till = round(old_div((h * (self.range - self.value)), self.range)) if self.value <= lower_threshold or self.value >= upper_threshold: qp.setBrush(QColor(255, 100, 100)) else: qp.setBrush(QColor(50, 255, 50)) qp.setPen(QColor(0, 0, 0)) qp.drawRect(0, h - 1, w, till - h) pen = QPen(QColor(20, 20, 20), 1, Qt.SolidLine) qp.setPen(pen) qp.setBrush(Qt.NoBrush) qp.drawRect(0, 0, w - 1, h - 1) sepeation_marks = int(round(h / 10.0)) for i in range(sepeation_marks, 10 * sepeation_marks, sepeation_marks): qp.drawLine(0, i, 5, i)
def __init__(self, parent=None, init_channel=None): QWidget.__init__(self, parent) PyDMWidget.__init__(self, init_channel=init_channel) self.value = 0 self.setLayout(QGridLayout(self)) self._on_color = QColor(0, 255, 0) self._off_color = QColor(100, 100, 100) self._disconnected_color = QColor(255, 255, 255) self._invalid_color = QColor(255, 0, 255) self._pen_style = Qt.SolidLine self._line_pen = QPen(self._pen_style) self._orientation = Qt.Vertical # This is kind of ridiculous, importing QTabWidget just to get a 4-item enum thats usable in Designer. # PyQt5 lets you define custom enums that you can use in designer with QtCore.Q_ENUMS(), doesn't exist in PyQt4. self._labels = [] self._show_labels = True self._label_position = QTabWidget.East self._num_bits = 1 self._indicators = [] self._circles = False self.set_spacing() self.layout().setOriginCorner(Qt.TopLeftCorner) self._big_endian = False self._shift = 0 self.numBits = 1 # Need to set the property to initialize
class PyDMBitIndicator(QWidget): """ A QWidget which draws a colored circle or rectangle Parameters ---------- parent : QWidget The parent widget for the Label """ def __init__(self, parent=None, circle=False): super(PyDMBitIndicator, self).__init__(parent) self.setAutoFillBackground(True) self.circle = circle self._painter = QPainter() self._brush = QBrush(Qt.SolidPattern) self._pen = QPen(Qt.SolidLine) def paintEvent(self, event): """ Paint events are sent to widgets that need to update themselves, for instance when part of a widget is exposed because a covering widget was moved. Parameters ---------- event : QPaintEvent """ self._painter.begin(self) opt = QStyleOption() opt.initFrom(self) self.style().drawPrimitive(QStyle.PE_Widget, opt, self._painter, self) self._painter.setRenderHint(QPainter.Antialiasing) self._painter.setBrush(self._brush) self._painter.setPen(self._pen) if self.circle: rect = self.rect() w = rect.width() h = rect.height() r = min(w, h) / 2.0 - 2.0 * max(self._pen.widthF(), 1.0) self._painter.drawEllipse(QPoint(w / 2.0, h / 2.0), r, r) else: self._painter.drawRect(self.rect()) self._painter.end() def setColor(self, color): """ Property for the color to be used when drawing Parameters ---------- QColor """ self._brush.setColor(color) self.update() def minimumSizeHint(self): fm = QFontMetrics(self.font()) return QSize(fm.height(), fm.height())
class PyDMBitIndicator(QWidget): """ A QWidget which draws a colored circle or rectangle Parameters ---------- parent : QWidget The parent widget for the Label """ def __init__(self, parent=None, circle=False): super(PyDMBitIndicator, self).__init__(parent) self.setAutoFillBackground(True) self.circle = circle self._painter = QPainter() self._brush = QBrush(Qt.SolidPattern) self._pen = QPen(Qt.SolidLine) def paintEvent(self, event): """ Paint events are sent to widgets that need to update themselves, for instance when part of a widget is exposed because a covering widget was moved. Parameters ---------- event : QPaintEvent """ self._painter.begin(self) opt = QStyleOption() opt.initFrom(self) self.style().drawPrimitive(QStyle.PE_Widget, opt, self._painter, self) self._painter.setRenderHint(QPainter.Antialiasing) self._painter.setBrush(self._brush) self._painter.setPen(self._pen) if self.circle: rect = event.rect() w = rect.width() h = rect.height() r = min(w, h) / 2.0 - 2.0 * max(self._pen.widthF(), 1.0) self._painter.drawEllipse(QPoint(w / 2.0, h / 2.0), r, r) else: self._painter.drawRect(event.rect()) self._painter.end() def setColor(self, color): """ Property for the color to be used when drawing Parameters ---------- QColor """ self._brush.setColor(color) self.update() def minimumSizeHint(self): fm = QFontMetrics(self.font()) return QSize(fm.height(), fm.height())
def qwtDrawXCrossSymbols(painter, points, numPoints, symbol): size = symbol.size() pen = QPen(symbol.pen()) if pen.width() > 1: pen.setCapStyle(Qt.FlatCap) painter.setPen(pen) sw = size.width() sh = size.height() sw2 = 0.5 * size.width() sh2 = 0.5 * size.height() for pos in points: x1 = pos.x() - sw2 x2 = x1 + sw y1 = pos.y() - sh2 y2 = y1 + sh painter.drawLine(x1, y1, x2, y2) painter.drawLine(x2, y1, x1, y2)
def qwtDrawDiamondSymbols(painter, points, numPoints, symbol): size = symbol.size() pen = QPen(symbol.pen()) pen.setJoinStyle(Qt.MiterJoin) painter.setPen(pen) painter.setBrush(symbol.brush()) for pos in points: x1 = pos.x() - 0.5 * size.width() y1 = pos.y() - 0.5 * size.height() x2 = x1 + size.width() y2 = y1 + size.height() polygon = QPolygonF() polygon += QPointF(pos.x(), y1) polygon += QPointF(x1, pos.y()) polygon += QPointF(pos.x(), y2) polygon += QPointF(x2, pos.y()) painter.drawPolygon(polygon)
def paintEvent(self, event): """ Override from QWidget, needed to get stylesheets working :param event: paint event """ # _log.debug("Tab: paint event.") opt = QStyleOption() opt.initFrom(self) painter = QPainter(self) self.style().drawPrimitive(QStyle.PE_Widget, opt, painter, self) if CONFIG.debug_layout: painter.setPen(QPen(Qt.red, 1.0)) painter.drawRect(self.rect().adjusted(0, 0, -1, -1)) painter.setPen(QPen(Qt.black, 1.0)) painter.drawText(QPointF(5, 12), str(self))
def paintEvent(self, event): """Override Qt method""" painter = QPainter(self) painter.setRenderHint(QPainter.Antialiasing) # Decoration painter.fillPath(self.path_current, QBrush(self.color)) painter.strokePath(self.path_decoration, QPen(self.color_decoration, self.stroke_decoration))
def _get_pens_and_colors(self, canvas, line_color=None, fill_color=None): scale = self.get_scale(canvas) if self.shape_type != 'freeform': line_color = line_color or DEFAULT_LINE_COLOR fill_color = fill_color or DEFAULT_FILL_COLOR last_line_color = DEFAULT_LAST_LINE_COLOR else: line_color = line_color or FREEFORM_LINE_COLOR fill_color = fill_color or FREEFORM_FILL_COLOR last_line_color = FREEFORM_LINE_COLOR line_pen = QPen(line_color) last_line_pen = QPen(last_line_color) # Try using integer sizes for smoother drawing(?) width = max(1, int(round(self.line_width / scale))) for pen in (line_pen, last_line_pen): pen.setWidth(width) return line_pen, last_line_pen, fill_color
def paintEvent(self, evt): painter = QPainter(self) if self.color is not None: painter.setPen(QPen(self.color)) painter.rotate(self.angle) transform = painter.transform().inverted()[0] rct = transform.mapRect(self.rect()) painter.drawText(rct, self.alignment(), self.text())
def set_outline(self, color): """ Uses an outline rectangle. :param color: Color of the outline rect :type color: QtGui.QColor """ self.format.setProperty(QTextFormat.OutlinePen, QPen(color))
def setY(self, y, label=None, color=QColor(Qt.red)): """ Sets the Hline's y value :param y: Ordinate value :param label: :param color: """ self._y = y self.setPos(QPointF(0, self._y)) if label is not None: self._label = label self._color = color self._pen = QPen(QBrush(color), 1.0, Qt.SolidLine) self._pen.setCosmetic(True) self._brush = QBrush(QColor(255, 255, 255, 0))
def setX(self, x, label=None, color=QColor(Qt.red)): """ Sets the Vline's x value. :param x: abscissa value. :param label: :param color: """ self._x = x self.setPos(QPointF(self._x, 0)) if label is not None: self._label = label self._color = color self._pen = QPen(QBrush(color), 1.0, Qt.SolidLine) self._pen.setCosmetic(True) self._brush = QBrush(QColor(255, 255, 255, 0))
def paint(self, p=QPainter(), o=QStyleOptionGraphicsItem(), widget=None): pen = QPen(Qt.red) p.setPen(pen) p.drawLine(QLineF(0, 0, 2, 0)) p.drawLine(QLineF(2, 0, 1.5, 0.5)) p.drawLine(QLineF(2, 0, 1.5, -0.5)) pen = QPen(Qt.blue) p.setPen(pen) p.drawLine(QLineF(0, 0, 0, 2)) p.drawLine(QLineF(0, 2, 0.5, 1.5)) p.drawLine(QLineF(0, 2, -0.5, 1.5)) pen = QPen(Qt.yellow) p.setPen(pen) p.drawRect(-9, -9, 18, 18)
def drawBackground(self, painter: QPainter, r: QRectF): """ drawBackground Parameters ---------- painter : QPainter r : QRectF """ super().drawBackground(painter, r) def draw_grid(grid_step): window_rect = self.rect() tl = self.mapToScene(window_rect.topLeft()) br = self.mapToScene(window_rect.bottomRight()) left = math.floor(tl.x() / grid_step - 0.5) right = math.floor(br.x() / grid_step + 1.0) bottom = math.floor(tl.y() / grid_step - 0.5) top = math.floor(br.y() / grid_step + 1.0) # vertical lines lines = [ QLineF(xi * grid_step, bottom * grid_step, xi * grid_step, top * grid_step) for xi in range(int(left), int(right) + 1) ] # horizontal lines lines.extend([ QLineF(left * grid_step, yi * grid_step, right * grid_step, yi * grid_step) for yi in range(int(bottom), int(top) + 1) ]) painter.drawLines(lines) style = self._style.flow_view # brush = self.backgroundBrush() pfine = QPen(style.fine_grid_color, 1.0) painter.setPen(pfine) draw_grid(15) p = QPen(style.coarse_grid_color, 1.0) painter.setPen(p) draw_grid(150)
def setPen(self, *args): """ Build and/or assign a pen, depending on the arguments. .. py:method:: setPen(color, width, style) :noindex: Build and assign a pen In Qt5 the default pen width is 1.0 ( 0.0 in Qt4 ) what makes it non cosmetic (see `QPen.isCosmetic()`). This method signature has been introduced to hide this incompatibility. :param QColor color: Pen color :param float width: Pen width :param Qt.PenStyle style: Pen style .. py:method:: setPen(pen) :noindex: Assign a pen :param QPen pen: New pen .. seealso:: :py:meth:`pen()`, :py:meth:`brush()` """ if len(args) == 3: color, width, style = args pen = QPen(color, width, style) elif len(args) == 1: (pen, ) = args else: raise TypeError( "%s().setPen() takes 1 or 3 argument(s) (%s given)" % (self.__class__.__name__, len(args))) if pen != self.__data.pen: if isinstance(pen, QColor): pen = QPen(pen) else: assert isinstance(pen, QPen) self.__data.pen = pen self.legendChanged() self.itemChanged()
def __init__(self, size): super(QwtStyleSheetRecorder, self).__init__() self.__size = size self.__pen = QPen() self.__brush = QBrush() self.__origin = QPointF() self.clipRects = [] self.border = Border() self.background = Background()
def test_update(self): obj = QwtSymbol(QwtSymbol.Rect, QBrush(Qt.black), QPen(Qt.yellow), QSize(3, 3)) sym = SymbolParam(_("Symbol")) sym.update_param(obj) self.assertEqual(sym.marker, "Rect") self.assertEqual(sym.size, 3) self.assertEqual(sym.edgecolor, "#ffff00") self.assertEqual(sym.facecolor, "#000000")
def __init__(self): QwtPlotItem_PrivateData.__init__(self) self.style = QwtPlotCurve.Lines self.baseline = 0.0 self.symbol = None self.attributes = 0 self.legendAttributes = QwtPlotCurve.LegendShowLine self.pen = QPen(Qt.black) self.brush = QBrush()
def __init__(self, parent=None, init_channel=None): self._rotation = 0.0 self._brush = QBrush(Qt.SolidPattern) self._original_brush = None self._painter = QPainter() self._pen = QPen(Qt.NoPen) self._pen_style = Qt.NoPen self._pen_cap_style = Qt.SquareCap self._pen_join_style = Qt.MiterJoin self._pen_width = 0 self._pen_color = QColor(0, 0, 0) self._pen.setCapStyle(self._pen_cap_style) self._pen.setJoinStyle(self._pen_join_style) self._original_pen_style = self._pen_style self._original_pen_color = self._pen_color QWidget.__init__(self, parent) PyDMWidget.__init__(self, init_channel=init_channel) self.alarmSensitiveBorder = False
def __init__(self, parent): super().__init__(parent) self._imageItem = ImageGraphicsItem() self.addItem(self._imageItem) self._roiMode = False self._drawingRoi = False self.roiPen = QPen() self.roiPen.setWidthF(1.25) self.roiPen.setCosmetic(True) self.roiPen.setColor(Qt.yellow) self._roiPolygon = QPolygonF() self._roiItem = QGraphicsPolygonItem(self._roiPolygon) self._roiItem.setPen(self.roiPen) self.addItem(self._roiItem)
def __init__(self, parent=None): super(QScale, self).__init__(parent) self._value = 1 self._lower_limit = -5 self._upper_limit = 5 self.position = None # unit: pixel self._bg_color = QColor('darkgray') self._bg_size_rate = 0.8 # from 0 to 1 self._indicator_color = QColor('black') self._pointer_width_rate = 0.05 self._barIndicator = False self._num_divisions = 10 self._show_ticks = True self._tick_pen = QPen() self._tick_color = QColor('black') self._tick_width = 0 self._tick_size_rate = 0.1 # from 0 to 1 self._painter = QPainter() self._painter_rotation = None self._painter_translation_y = None self._painter_translation_x = None self._painter_scale_x = None self._flip_traslation_y = None self._flip_scale_y = None self._widget_width = self.width() self._widget_height = self.height() self._orientation = Qt.Horizontal self._inverted_appearance = False self._flip_scale = False self._scale_height = 35 self._origin_at_zero = False self._origin_position = 0 self.set_position()
class QScale(QFrame): """ A bar-shaped indicator for scalar value. Configurable features include indicator type (bar/pointer), scale tick marks and orientation (horizontal/vertical). Parameters ---------- parent : QWidget The parent widget for the Scale """ def __init__(self, parent=None): super(QScale, self).__init__(parent) self._value = 1 self._lower_limit = -5 self._upper_limit = 5 self.position = None # unit: pixel self._bg_color = QColor('darkgray') self._bg_size_rate = 0.8 # from 0 to 1 self._indicator_color = QColor('black') self._pointer_width_rate = 0.05 self._barIndicator = False self._num_divisions = 10 self._show_ticks = True self._tick_pen = QPen() self._tick_color = QColor('black') self._tick_width = 0 self._tick_size_rate = 0.1 # from 0 to 1 self._painter = QPainter() self._painter_rotation = None self._painter_translation_y = None self._painter_translation_x = None self._painter_scale_x = None self._flip_traslation_y = None self._flip_scale_y = None self._widget_width = self.width() self._widget_height = self.height() self._orientation = Qt.Horizontal self._inverted_appearance = False self._flip_scale = False self._scale_height = 35 self._origin_at_zero = False self._origin_position = 0 self.set_position() def adjust_transformation(self): """ This method sets parameters for the widget transformations (needed to for orientation, flipping and appearance inversion). """ self.setMaximumSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX) # Unset fixed size if self._orientation == Qt.Horizontal: self._widget_width = self.width() self._widget_height = self.height() self._painter_translation_y = 0 self._painter_rotation = 0 self.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Fixed) self.setFixedHeight(self._scale_height) elif self._orientation == Qt.Vertical: # Invert dimensions for paintEvent() self._widget_width = self.height() self._widget_height = self.width() self._painter_translation_y = self._widget_width self._painter_rotation = -90 self.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Expanding) self.setFixedWidth(self._scale_height) if self._inverted_appearance: self._painter_translation_x = self._widget_width self._painter_scale_x = -1 else: self._painter_translation_x = 0 self._painter_scale_x = 1 if self._flip_scale: self._flip_traslation_y = self._widget_height self._flip_scale_y = -1 else: self._flip_traslation_y = 0 self._flip_scale_y = 1 def set_tick_pen(self): """ Define pen style for drawing scale tick marks. """ self._tick_pen.setColor(self._tick_color) self._tick_pen.setWidth(self._tick_width) def draw_ticks(self): """ Draw tick marks on the scale. """ if not self._show_ticks: return self.set_tick_pen() self._painter.setPen(self._tick_pen) division_size = self._widget_width / self._num_divisions tick_y0 = self._widget_height tick_yf = (1 - self._tick_size_rate)*self._widget_height for i in range(self._num_divisions+1): x = i*division_size self._painter.drawLine(x, tick_y0, x, tick_yf) # x1, y1, x2, y2 def draw_bar(self): """ Draw a bar as indicator of current value. """ self.set_origin() self.set_position() if self.position < 0 or self.position > self._widget_width: return self._painter.setPen(Qt.transparent) self._painter.setBrush(self._indicator_color) bar_width = self.position - self._origin_position bar_height = self._bg_size_rate * self._widget_height self._painter.drawRect(self._origin_position, 0, bar_width, bar_height) def draw_pointer(self): """ Draw a pointer as indicator of current value. """ self.set_position() if self.position < 0 or self.position > self._widget_width: return self._painter.setPen(Qt.transparent) self._painter.setBrush(self._indicator_color) pointer_width = self._pointer_width_rate * self._widget_width pointer_height = self._bg_size_rate * self._widget_height points = [ QPoint(self.position, 0), QPoint(self.position + 0.5*pointer_width, 0.5*pointer_height), QPoint(self.position, pointer_height), QPoint(self.position - 0.5*pointer_width, 0.5*pointer_height) ] self._painter.drawPolygon(QPolygon(points)) def draw_indicator(self): """ Draw the selected indicator for current value. """ if self._barIndicator: self.draw_bar() else: self.draw_pointer() def draw_background(self): """ Draw the background of the scale. """ self._painter.setPen(Qt.transparent) self._painter.setBrush(self._bg_color) bg_width = self._widget_width bg_height = self._bg_size_rate * self._widget_height self._painter.drawRect(0, 0, bg_width, bg_height) def paintEvent(self, event): """ Paint events are sent to widgets that need to update themselves, for instance when part of a widget is exposed because a covering widget was moved. Parameters ---------- event : QPaintEvent """ self.adjust_transformation() self._painter.begin(self) self._painter.translate(0, self._painter_translation_y) # Draw vertically if needed self._painter.rotate(self._painter_rotation) self._painter.translate(self._painter_translation_x, 0) # Invert appearance if needed self._painter.scale(self._painter_scale_x, 1) self._painter.translate(0, self._flip_traslation_y) # Invert scale if needed self._painter.scale(1, self._flip_scale_y) self._painter.setRenderHint(QPainter.Antialiasing) self.draw_background() self.draw_ticks() self.draw_indicator() self._painter.end() def calculate_position_for_value(self, value): """ Calculate the position (pixel) in which the pointer should be drawn for a given value. """ if value < self._lower_limit or value > self._upper_limit or \ self._upper_limit - self._lower_limit == 0: proportion = -1 # Invalid else: proportion = (value - self._lower_limit) / (self._upper_limit - self._lower_limit) position = int(proportion * self._widget_width) return position def set_origin(self): """ Set the position (pixel) in which the origin should be drawn. """ if self._origin_at_zero: self._origin_position = self.calculate_position_for_value(0) else: self._origin_position = 0 def set_position(self): """ Set the position (pixel) in which the pointer should be drawn. """ self.position = self.calculate_position_for_value(self._value) def update_indicator(self): """ Update the position and the drawing of indicator. """ self.set_position() self.repaint() def set_value(self, value): """ Set a new current value for the indicator. """ self._value = value self.update_indicator() def set_upper_limit(self, new_limit): """ Set the scale upper limit. Parameters ---------- new_limit : float The upper limit of the scale. """ self._upper_limit = new_limit def set_lower_limit(self, new_limit): """ Set the scale lower limit. Parameters ---------- new_limit : float The lower limit of the scale. """ self._lower_limit = new_limit def get_show_ticks(self): return self._show_ticks def set_show_ticks(self, checked): if self._show_ticks != bool(checked): self._show_ticks = checked self.repaint() def get_orientation(self): return self._orientation def set_orientation(self, orientation): self._orientation = orientation self.adjust_transformation() self.repaint() def get_flip_scale(self): return self._flip_scale def set_flip_scale(self, checked): self._flip_scale = bool(checked) self.adjust_transformation() self.repaint() def get_inverted_appearance(self): return self._inverted_appearance def set_inverted_appearance(self, inverted): self._inverted_appearance = inverted self.adjust_transformation() self.repaint() def get_bar_indicator(self): return self._barIndicator def set_bar_indicator(self, checked): if self._barIndicator != bool(checked): self._barIndicator = checked self.repaint() def get_background_color(self): return self._bg_color def set_background_color(self, color): self._bg_color = color self.repaint() def get_indicator_color(self): return self._indicator_color def set_indicator_color(self, color): self._indicator_color = color self.repaint() def get_tick_color(self): return self._tick_color def set_tick_color(self, color): self._tick_color = color self.repaint() def get_background_size_rate(self): return self._bg_size_rate def set_background_size_rate(self, rate): if rate >= 0 and rate <=1 and self._bg_size_rate != rate: self._bg_size_rate = rate self.repaint() def get_tick_size_rate(self): return self._tick_size_rate def set_tick_size_rate(self, rate): if rate >= 0 and rate <=1 and self._tick_size_rate != rate: self._tick_size_rate = rate self.repaint() def get_num_divisions(self): return self._num_divisions def set_num_divisions(self, divisions): if isinstance(divisions, int) and divisions > 0 and self._num_divisions != divisions: self._num_divisions = divisions self.repaint() def get_scale_height(self): return self._scale_height def set_scale_height(self, value): self._scale_height = int(value) self.adjust_transformation() self.repaint() def get_origin_at_zero(self): return self._origin_at_zero def set_origin_at_zero(self, checked): if self._origin_at_zero != bool(checked): self._origin_at_zero = checked self.repaint()
def __init__(self, parent=None, args=None): super(CamViewer, self).__init__(parent=parent, args=args) # Set up the list of cameras, and all the PVs test_dict = { "image": "ca://MTEST:Image", "max_width": "ca://MTEST:ImageWidth", "max_height": "ca://MTEST:ImageWidth", "roi_x": None, "roi_y": None, "roi_width": None, "roi_height": None } # self.cameras = { "VCC": vcc_dict, "C-Iris": c_iris_dict, "Test": test_dict } self.cameras = {"Testing IOC Image": test_dict } self._channels = [] self.imageChannel = None # Populate the camera combo box self.ui.cameraComboBox.clear() for camera in self.cameras: self.ui.cameraComboBox.addItem(camera) # When the camera combo box changes, disconnect from PVs, re-initialize, then reconnect. self.ui.cameraComboBox.activated[str].connect(self.cameraChanged) # Set up the color map combo box. self.ui.colorMapComboBox.clear() for key, map_name in cmap_names.items(): self.ui.colorMapComboBox.addItem(map_name, userData=key) self.ui.imageView.colorMap = self.ui.colorMapComboBox.currentData() self.ui.colorMapComboBox.activated[str].connect(self.colorMapChanged) # Set up the color map limit sliders and line edits. # self._color_map_limit_sliders_need_config = True self.ui.colorMapMinSlider.valueChanged.connect(self.setColorMapMin) self.ui.colorMapMaxSlider.valueChanged.connect(self.setColorMapMax) self.ui.colorMapMinLineEdit.returnPressed.connect(self.colorMapMinLineEditChanged) self.ui.colorMapMaxLineEdit.returnPressed.connect(self.colorMapMaxLineEditChanged) # Set up the stuff for single-shot and average modes. self.ui.singleShotRadioButton.setChecked(True) self._average_mode_enabled = False self.ui.singleShotRadioButton.clicked.connect(self.enableSingleShotMode) self.ui.averageRadioButton.clicked.connect(self.enableAverageMode) self.ui.numShotsLineEdit.returnPressed.connect(self.numAverageChanged) # Add a plot for vertical lineouts self.yLineoutPlot = PlotWidget() self.yLineoutPlot.setMaximumWidth(80) self.yLineoutPlot.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Expanding) self.yLineoutPlot.getPlotItem().invertY() self.yLineoutPlot.hideAxis('bottom') # self.yLineoutPlot.setYLink(self.ui.imageView.getView()) self.ui.imageGridLayout.addWidget(self.yLineoutPlot, 0, 0) self.yLineoutPlot.hide() # We do some mangling of the .ui file here and move the imageView over a cell, kind of ugly. self.ui.imageGridLayout.removeWidget(self.ui.imageView) self.ui.imageGridLayout.addWidget(self.ui.imageView, 0, 1) # Add a plot for the horizontal lineouts self.xLineoutPlot = PlotWidget() self.xLineoutPlot.setMaximumHeight(80) self.xLineoutPlot.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Minimum) self.xLineoutPlot.hideAxis('left') # self.xLineoutPlot.setXLink(self.ui.imageView.getView()) self.ui.imageGridLayout.addWidget(self.xLineoutPlot, 1, 1) self.xLineoutPlot.hide() # Update the lineout plot ranges when the image gets panned or zoomed self.ui.imageView.getView().sigRangeChanged.connect(self.updateLineoutRange) # Instantiate markers. self.marker_dict = {1:{}, 2:{}, 3:{}, 4:{}} marker_size = QPointF(20., 20.) self.marker_dict[1]['marker'] = ImageMarker((0, 0), size=marker_size, pen=mkPen((100, 100, 255), width=5)) self.marker_dict[1]['button'] = self.ui.marker1Button self.marker_dict[1]['xlineedit'] = self.ui.marker1XPosLineEdit self.marker_dict[1]['ylineedit'] = self.ui.marker1YPosLineEdit self.marker_dict[2]['marker'] = ImageMarker((0, 0), size=marker_size, pen=mkPen((255, 100, 100), width=5)) self.marker_dict[2]['button'] = self.ui.marker2Button self.marker_dict[2]['xlineedit'] = self.ui.marker2XPosLineEdit self.marker_dict[2]['ylineedit'] = self.ui.marker2YPosLineEdit self.marker_dict[3]['marker'] = ImageMarker((0, 0), size=marker_size, pen=mkPen((60, 255, 60), width=5)) self.marker_dict[3]['button'] = self.ui.marker3Button self.marker_dict[3]['xlineedit'] = self.ui.marker3XPosLineEdit self.marker_dict[3]['ylineedit'] = self.ui.marker3YPosLineEdit self.marker_dict[4]['marker'] = ImageMarker((0, 0), size=marker_size, pen=mkPen((255, 60, 255), width=5)) self.marker_dict[4]['button'] = self.ui.marker4Button self.marker_dict[4]['xlineedit'] = self.ui.marker4XPosLineEdit self.marker_dict[4]['ylineedit'] = self.ui.marker4YPosLineEdit # Disable auto-ranging the image (it feels strange when the zoom changes as you move markers around.) self.ui.imageView.getView().disableAutoRange() for d in self.marker_dict: marker = self.marker_dict[d]['marker'] marker.setZValue(20) marker.hide() marker.sigRegionChanged.connect(self.markerMoved) self.ui.imageView.getView().addItem(marker) self.marker_dict[d]['button'].toggled.connect(self.enableMarker) curvepen = QPen(marker.pen) curvepen.setWidth(1) self.marker_dict[d]['xcurve'] = self.xLineoutPlot.plot(pen=curvepen) self.marker_dict[d]['ycurve'] = self.yLineoutPlot.plot(pen=curvepen) self.marker_dict[d]['xlineedit'].returnPressed.connect(self.markerPositionLineEditChanged) self.marker_dict[d]['ylineedit'].returnPressed.connect(self.markerPositionLineEditChanged) # Set up zoom buttons self.ui.zoomInButton.clicked.connect(self.zoomIn) self.ui.zoomOutButton.clicked.connect(self.zoomOut) self.ui.zoomToActualSizeButton.clicked.connect(self.zoomToActualSize) # Set up ROI buttons self.ui.setROIButton.clicked.connect(self.setROI) self.ui.resetROIButton.clicked.connect(self.resetROI) self.destroyed.connect(functools.partial(widget_destroyed, self.channels))