def draw_icon(self, painter): path = QPainterPath(QPointF(0, 0.3)) path.lineTo(0, 0.9) path.lineTo(1, 0.3) path.lineTo(1, 0.9) path.closeSubpath() painter.drawPath(path)
def draw_icon(self, painter): path = QPainterPath(QPointF(0, 0.3)) path.lineTo(0, 0.9) path.lineTo(1, 0.3) path.lineTo(1, 0.9) path.closeSubpath() painter.drawPath(path) prev_brush = painter.brush() prev_pen = painter.pen() painter.setPen(Qt.NoPen) painter.setBrush(self._arrow_brush) arrow = QPolygonF([ QPointF(0.2, 0), QPointF(0.2, 0.20), QPointF(0.5, 0.40), QPointF(0.8, 0.20), QPointF(0.8, 0) ]) painter.drawPolygon(arrow) painter.setPen(prev_pen) painter.setBrush(prev_brush) painter.drawLine(QPointF(0.2, 0), QPointF(0.5, 0.20)) painter.drawLine(QPointF(0.2, 0.20), QPointF(0.5, 0.40)) painter.drawLine(QPointF(0.5, 0.20), QPointF(0.8, 0)) painter.drawLine(QPointF(0.5, 0.40), QPointF(0.8, 0.20)) painter.drawLine(QPointF(0.5, 0.6), QPointF(0.5, 0.0))
def draw_icon(self, painter): path = QPainterPath(QPointF(0, 0.3)) path.lineTo(0, 0.9) path.lineTo(1, 0.3) path.lineTo(1, 0.9) path.closeSubpath() painter.drawPath(path) painter.drawLine(QPointF(0.5, 0.6), QPointF(0.5, 0.15)) # Draw the arrow end-caps painter.setBrush(QBrush(QColor(0, 0, 0))) top_arrow_point = QPointF(0.65, 0.36) arrow = QPolygonF([ QPointF(-0.09, 0.0), QPointF(-0.005, 0.0), QPointF(-0.005, 0.8), QPointF(0.005, 0.8), QPointF(0.005, 0.0), QPointF(0.09, 0.0), QPointF(0.00, -0.25) ]) t = QTransform() t.rotate(35) top_arrow_r = t.map(arrow) arrow_l = top_arrow_r.translated(top_arrow_point) painter.drawPolygon(arrow_l) painter.setBrush(self._interlock_brush) painter.drawRect(QRectF(0.3, 0, 0.4, 0.15))
def draw_icon(self, painter): path = QPainterPath(QPointF(0, 0)) path.lineTo(1, 1) path.lineTo(0.005, 1) path.lineTo(0.5, 0.5) path.lineTo(0, 0.9) path.closeSubpath() painter.drawPath(path) painter.drawEllipse(QPointF(0.5, 0.5), 0.05, 0.05)
def painterPathForTriangle(): bottomLeft = QPointF(-1.0, -1.0) top = QPointF(0.0, 1.0) bottomRight = QPointF(1.0, -1.0) path = QPainterPath(bottomLeft) path.lineTo(top) path.lineTo(bottomRight) path.closeSubpath() return path
def draw_icon(self, painter): path = QPainterPath(QPointF(0, 0.3)) path.lineTo(0, 0.9) path.lineTo(1, 0.3) path.lineTo(1, 0.9) path.closeSubpath() painter.drawPath(path) painter.drawLine(QPointF(0.5, 0.6), QPointF(0.5, 0.3)) painter.setBrush(self._interlock_brush) painter.drawRect(QRectF(0.2, 0, 0.6, 0.3))
def draw_icon(self, painter): path = QPainterPath(QPointF(0, 0.3)) path.lineTo(0, 0.9) path.lineTo(1, 0.3) path.lineTo(1, 0.9) path.closeSubpath() painter.drawPath(path) painter.drawLine(QPointF(0.4, 0), QPointF(0.5, 0.15)) painter.drawLine(QPointF(0.4, 0.10), QPointF(0.5, 0.25)) painter.drawLine(QPointF(0.5, 0.15), QPointF(0.6, 0)) painter.drawLine(QPointF(0.5, 0.25), QPointF(0.6, 0.10)) painter.drawLine(QPointF(0.5, 0.6), QPointF(0.5, 0.0))
def qwtCombinePathList(rect, pathList): if not pathList: return QPainterPath() ordered = [None] * 8 for subPath in pathList: index = -1 br = subPath.controlPointRect() if br.center().x() < rect.center().x(): if br.center().y() < rect.center().y(): if abs(br.top() - rect.top()) < abs(br.left() - rect.left()): index = 1 else: index = 0 else: if abs(br.bottom() - rect.bottom) < abs(br.left() - rect.left()): index = 6 else: index = 7 if subPath.currentPosition().y() > br.center().y(): qwtRevertPath(subPath) else: if br.center().y() < rect.center().y(): if abs(br.top() - rect.top()) < abs(br.right() - rect.right()): index = 2 else: index = 3 else: if abs(br.bottom() - rect.bottom()) < abs(br.right() - rect.right()): index = 5 else: index = 4 if subPath.currentPosition().y() < br.center().y(): qwtRevertPath(subPath) ordered[index] = subPath for i in range(4): if ordered[2 * i].isEmpty() != ordered[2 * i + 1].isEmpty(): return QPainterPath() corners = QPolygonF(rect) path = QPainterPath() for i in range(4): if ordered[2 * i].isEmpty(): path.lineTo(corners[i]) else: path.connectPath(ordered[2 * i]) path.connectPath(ordered[2 * i + 1]) path.closeSubpath() return path
def draw_icon(self, painter): path = QPainterPath(QPointF(0, 0.3)) path.lineTo(0, 0.9) path.lineTo(1, 0.3) path.lineTo(1, 0.9) path.closeSubpath() painter.drawPath(path) painter.drawLine(QPointF(0.5, 0.6), QPointF(0.5, 0.3)) painter.setBrush(self._interlock_brush) painter.drawRect(QRectF(0.2, 0, 0.6, 0.3)) # Draw the N n_path = QPainterPath(QPointF(0.25, 0.25)) n_path.lineTo(0.25, 0.05) n_path.lineTo(0.45, 0.25) n_path.lineTo(0.45, 0.05) painter.drawPath(n_path) # Draw the O painter.drawEllipse(QPointF(0.65, 0.15), 0.1, 0.1)
def drawLine(self, qp, value: int): """Draw line on triangle indicating value. Parameters ---------- qp: QPainter object value: int Value of highlight thickness. """ col = QColor('white') qp.setPen(QPen(col, 2)) qp.setBrush(col) path = QPainterPath() path.moveTo(value, 15) path.lineTo(value, 0) path.closeSubpath() qp.drawPath(path) self.valueChanged.emit(self._value)
def drawPolygon(self, *args): if len(args) == 3: points, pointCount, mode = args elif len(args) == 2: points, mode = args pointCount = len(points) else: raise TypeError("Unexpected arguments") device = self.nullDevice() if device is None: return if device.mode() == QwtNullPaintDevice.PathMode: path = QPainterPath() if pointCount > 0: path.moveTo(points[0]) for i in range(1, pointCount): path.lineTo(points[i]) if mode != QPaintEngine.PolylineMode: path.closeSubpath() device.drawPath(path) return device.drawPolygon(points, pointCount, mode)
def drawTriangle(self, qp): """Draw triangle. Parameters ---------- qp: QPainter object """ width = self.rect().width() height = self.rect().height() col = QColor(135, 206, 235) qp.setPen(QPen(col, 1)) qp.setBrush(col) path = QPainterPath() height = 10 path.moveTo(0, height) path.lineTo(width, height) path.lineTo(width, 0) path.closeSubpath() qp.drawPath(path)
def _paintBackgroundCross(cls, painter): grey = QColor(220, 220, 220) greyAccent = QColor(180, 180, 180) painter.setBrush(QBrush(grey)) painter.setPen(QPen(greyAccent, 1)) path = QPainterPath() h0 = -86 h1 = -18 h2 = 18 h3 = 86 v0 = -86 v1 = -18 v2 = 18 v3 = 86 c = 7 path.moveTo(v0, h1) path.lineTo(v1 - c, h1) path.lineTo(v1, h1 - c) path.lineTo(v1, h0) path.lineTo(v2, h0) path.lineTo(v2, h1 - c) path.lineTo(v2 + c, h1) path.lineTo(v3, h1) path.lineTo(v3, h2) path.lineTo(v2 + c, h2) path.lineTo(v2, h2 + c) path.lineTo(v2, h3) path.lineTo(v1, h3) path.lineTo(v1, h2 + c) path.lineTo(v1 - c, h2) path.lineTo(v0, h2) path.closeSubpath() painter.drawPath(path)
def _paintAbsDropIcon(self, painter, placement): self._configureBrushAndPen(painter, Qt.white, Qt.white) r = QRectF(-14, -14, 28, 28) painter.drawRoundedRect(r, 2, 2) self._configureBrushAndPen(painter, self.Blue, self.BlueAccent) title = { Placement.LEFT: QRectF(-10, -10, 10, 4), Placement.RIGHT: QRectF(0, -10, 10, 4), Placement.TOP: QRectF(-10, -10, 20, 4), Placement.BOTTOM: QRectF(-10, -2, 20, 4), Placement.TAB: None, } if title[placement] is not None: painter.drawRect(title[placement]) if placement == self._activeAbsoluteRegion: self._configureBrushAndPen(painter, self.Yellow, self.BlueAccent) else: self._configureBrushAndPen(painter, self.BlueDim, self.BlueAccentDim) bg = { Placement.LEFT: QRectF(-10, -5, 10, 14), Placement.RIGHT: QRectF(0, -5, 10, 14), Placement.TOP: QRectF(-10, -5, 20, 7), Placement.BOTTOM: QRectF(-10, 2, 20, 7), Placement.TAB: None, } if bg[placement] is not None: painter.drawRect(bg[placement]) if placement == Placement.LEFT: painter.setBrush(QBrush(self.Blue)) painter.setPen(QPen(self.BlueAccent, 1)) path = QPainterPath() path.moveTo(6, 0) path.lineTo(10, -4) path.lineTo(10, 4) path.closeSubpath() painter.drawPath(path) elif placement == Placement.TOP: painter.setBrush(QBrush(self.Blue)) painter.setPen(QPen(self.BlueAccent, 1)) path = QPainterPath() path.moveTo(0, 6) path.lineTo(-4, 10) path.lineTo(4, 10) path.closeSubpath() painter.drawPath(path) elif placement == Placement.RIGHT: painter.setBrush(QBrush(self.Blue)) painter.setPen(QPen(self.BlueAccent, 1)) path = QPainterPath() path.moveTo(-6, 0) path.lineTo(-10, -4) path.lineTo(-10, 4) path.closeSubpath() painter.drawPath(path) elif placement == Placement.BOTTOM: painter.setBrush(QBrush(self.Blue)) painter.setPen(QPen(self.BlueAccent, 1)) path = QPainterPath() path.moveTo(0, -6) path.lineTo(-4, -10) path.lineTo(4, -10) path.closeSubpath() painter.drawPath(path)
class FadingTipBox(FadingDialog): """ """ def __init__(self, parent, opacity, duration, easing_curve, tour=None): super(FadingTipBox, self).__init__(parent, opacity, duration, easing_curve) self.holder = self.anim # needed for qt to work self.parent = parent self.tour = tour self.frames = None self.color_top = QColor.fromRgb(230, 230, 230) self.color_back = QColor.fromRgb(255, 255, 255) self.offset_shadow = 0 self.fixed_width = 300 self.key_pressed = None self.setAttribute(Qt.WA_TranslucentBackground) self.setWindowFlags(Qt.Dialog | Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint) self.setModal(False) # Widgets def toolbutton(icon): bt = QToolButton() bt.setAutoRaise(True) bt.setIcon(icon) return bt self.button_close = toolbutton(ima.icon("tour.close")) self.button_home = toolbutton(ima.icon("tour.home")) self.button_previous = toolbutton(ima.icon("tour.previous")) self.button_end = toolbutton(ima.icon("tour.end")) self.button_next = toolbutton(ima.icon("tour.next")) self.button_run = QPushButton(_('Run code')) self.button_disable = None self.button_current = QToolButton() self.label_image = QLabel() self.label_title = QLabel() self.combo_title = QComboBox() self.label_current = QLabel() self.label_content = QLabel() self.label_content.setMinimumWidth(self.fixed_width) self.label_content.setMaximumWidth(self.fixed_width) self.label_current.setAlignment(Qt.AlignCenter) self.label_content.setWordWrap(True) self.widgets = [self.label_content, self.label_title, self.label_current, self.combo_title, self.button_close, self.button_run, self.button_next, self.button_previous, self.button_end, self.button_home, self.button_current] arrow = get_image_path('hide.png') self.stylesheet = '''QComboBox { padding-left: 5px; background-color: rgbs(230,230,230,100%); border-width: 0px; border-radius: 0px; min-height:20px; max-height:20px; } QComboBox::drop-down { subcontrol-origin: padding; subcontrol-position: top left; border-width: 0px; } QComboBox::down-arrow { image: url(''' + arrow + '''); } ''' # Windows fix, slashes should be always in unix-style self.stylesheet = self.stylesheet.replace('\\', '/') self.setFocusPolicy(Qt.StrongFocus) for widget in self.widgets: widget.setFocusPolicy(Qt.NoFocus) widget.setStyleSheet(self.stylesheet) layout_top = QHBoxLayout() layout_top.addWidget(self.combo_title) layout_top.addStretch() layout_top.addWidget(self.button_close) layout_top.addSpacerItem(QSpacerItem(self.offset_shadow, self.offset_shadow)) layout_content = QHBoxLayout() layout_content.addWidget(self.label_content) layout_content.addWidget(self.label_image) layout_content.addSpacerItem(QSpacerItem(5, 5)) layout_run = QHBoxLayout() layout_run.addStretch() layout_run.addWidget(self.button_run) layout_run.addStretch() layout_run.addSpacerItem(QSpacerItem(self.offset_shadow, self.offset_shadow)) layout_navigation = QHBoxLayout() layout_navigation.addWidget(self.button_home) layout_navigation.addWidget(self.button_previous) layout_navigation.addStretch() layout_navigation.addWidget(self.label_current) layout_navigation.addStretch() layout_navigation.addWidget(self.button_next) layout_navigation.addWidget(self.button_end) layout_navigation.addSpacerItem(QSpacerItem(self.offset_shadow, self.offset_shadow)) layout = QVBoxLayout() layout.addLayout(layout_top) layout.addStretch() layout.addSpacerItem(QSpacerItem(15, 15)) layout.addLayout(layout_content) layout.addLayout(layout_run) layout.addStretch() layout.addSpacerItem(QSpacerItem(15, 15)) layout.addLayout(layout_navigation) layout.addSpacerItem(QSpacerItem(self.offset_shadow, self.offset_shadow)) layout.setSizeConstraint(QLayout.SetFixedSize) self.setLayout(layout) self.set_funcs_before_fade_in([self._disable_widgets]) self.set_funcs_after_fade_in([self._enable_widgets, self.setFocus]) self.set_funcs_before_fade_out([self._disable_widgets]) self.setContextMenuPolicy(Qt.CustomContextMenu) # signals and slots # These are defined every time by the AnimatedTour Class def _disable_widgets(self): """ """ for widget in self.widgets: widget.setDisabled(True) def _enable_widgets(self): """ """ self.setWindowFlags(Qt.Dialog | Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint) for widget in self.widgets: widget.setDisabled(False) if self.button_disable == 'previous': self.button_previous.setDisabled(True) self.button_home.setDisabled(True) elif self.button_disable == 'next': self.button_next.setDisabled(True) self.button_end.setDisabled(True) def set_data(self, title, content, current, image, run, frames=None, step=None): """ """ self.label_title.setText(title) self.combo_title.clear() self.combo_title.addItems(frames) self.combo_title.setCurrentIndex(step) # min_content_len = max([len(f) for f in frames]) # self.combo_title.setMinimumContentsLength(min_content_len) # Fix and try to see how it looks with a combo box self.label_current.setText(current) self.button_current.setText(current) self.label_content.setText(content) self.image = image if image is None: self.label_image.setFixedHeight(1) self.label_image.setFixedWidth(1) else: extension = image.split('.')[-1] self.image = QPixmap(get_image_path(image), extension) self.label_image.setPixmap(self.image) self.label_image.setFixedSize(self.image.size()) if run is None: self.button_run.setVisible(False) else: self.button_run.setDisabled(False) self.button_run.setVisible(True) # Refresh layout self.layout().activate() def set_pos(self, x, y): """ """ self.x = x self.y = y self.move(QPoint(x, y)) def build_paths(self): """ """ geo = self.geometry() radius = 0 shadow = self.offset_shadow x0, y0 = geo.x(), geo.y() width, height = geo.width() - shadow, geo.height() - shadow left, top = 0, 0 right, bottom = width, height self.round_rect_path = QPainterPath() self.round_rect_path.moveTo(right, top + radius) self.round_rect_path.arcTo(right-radius, top, radius, radius, 0.0, 90.0) self.round_rect_path.lineTo(left+radius, top) self.round_rect_path.arcTo(left, top, radius, radius, 90.0, 90.0) self.round_rect_path.lineTo(left, bottom-radius) self.round_rect_path.arcTo(left, bottom-radius, radius, radius, 180.0, 90.0) self.round_rect_path.lineTo(right-radius, bottom) self.round_rect_path.arcTo(right-radius, bottom-radius, radius, radius, 270.0, 90.0) self.round_rect_path.closeSubpath() # Top path header = 36 offset = 2 left, top = offset, offset right = width - (offset) self.top_rect_path = QPainterPath() self.top_rect_path.lineTo(right, top + radius) self.top_rect_path.moveTo(right, top + radius) self.top_rect_path.arcTo(right-radius, top, radius, radius, 0.0, 90.0) self.top_rect_path.lineTo(left+radius, top) self.top_rect_path.arcTo(left, top, radius, radius, 90.0, 90.0) self.top_rect_path.lineTo(left, top + header) self.top_rect_path.lineTo(right, top + header) def paintEvent(self, event): """ """ self.build_paths() painter = QPainter(self) painter.setRenderHint(QPainter.Antialiasing) painter.fillPath(self.round_rect_path, self.color_back) painter.fillPath(self.top_rect_path, self.color_top) painter.strokePath(self.round_rect_path, QPen(Qt.gray, 1)) # TODO: Build the pointing arrow? def keyReleaseEvent(self, event): """ """ key = event.key() self.key_pressed = key keys = [Qt.Key_Right, Qt.Key_Left, Qt.Key_Down, Qt.Key_Up, Qt.Key_Escape, Qt.Key_PageUp, Qt.Key_PageDown, Qt.Key_Home, Qt.Key_End, Qt.Key_Menu] if key in keys: if not self.is_fade_running(): self.sig_key_pressed.emit() def mousePressEvent(self, event): """override Qt method""" # Raise the main application window on click self.parent.raise_() self.raise_() if event.button() == Qt.RightButton: pass # clicked_widget = self.childAt(event.x(), event.y()) # if clicked_widget == self.label_current: # self.context_menu_requested(event) def focusOutEvent(self, event): """Override Qt method.""" # To be used so tips do not appear outside spyder self.tour.lost_focus() def context_menu_requested(self, event): """ """ pos = QPoint(event.x(), event.y()) menu = QMenu(self) actions = [] action_title = create_action(self, _('Go to step: '), icon=QIcon()) action_title.setDisabled(True) actions.append(action_title) # actions.append(create_action(self, _(': '), icon=QIcon())) add_actions(menu, actions) menu.popup(self.mapToGlobal(pos)) def reject(self): """Qt method to handle escape key event""" if not self.is_fade_running(): key = Qt.Key_Escape self.key_pressed = key self.sig_key_pressed.emit()
class FadingTipBox(FadingDialog): """ """ def __init__(self, parent, opacity, duration, easing_curve, tour=None, color_top=None, color_back=None, combobox_background=None): super(FadingTipBox, self).__init__(parent, opacity, duration, easing_curve) self.holder = self.anim # needed for qt to work self.parent = parent self.tour = tour self.frames = None self.offset_shadow = 0 self.fixed_width = 300 self.key_pressed = None self.setAttribute(Qt.WA_TranslucentBackground) self.setWindowFlags(Qt.Dialog | Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint) self.setModal(False) # Widgets def toolbutton(icon): bt = QToolButton() bt.setAutoRaise(True) bt.setIcon(icon) return bt self.button_close = toolbutton(ima.icon("tour.close")) self.button_home = toolbutton(ima.icon("tour.home")) self.button_previous = toolbutton(ima.icon("tour.previous")) self.button_end = toolbutton(ima.icon("tour.end")) self.button_next = toolbutton(ima.icon("tour.next")) self.button_run = QPushButton(_('Run code')) self.button_disable = None self.button_current = QToolButton() self.label_image = QLabel() self.label_title = QLabel() self.combo_title = QComboBox() self.label_current = QLabel() self.label_content = QLabel() self.label_content.setMinimumWidth(self.fixed_width) self.label_content.setMaximumWidth(self.fixed_width) self.label_current.setAlignment(Qt.AlignCenter) self.label_content.setWordWrap(True) self.widgets = [ self.label_content, self.label_title, self.label_current, self.combo_title, self.button_close, self.button_run, self.button_next, self.button_previous, self.button_end, self.button_home, self.button_current ] arrow = get_image_path('hide.png') self.color_top = color_top self.color_back = color_back self.combobox_background = combobox_background self.stylesheet = '''QComboBox {{ padding-left: 5px; background-color: {} border-width: 0px; border-radius: 0px; min-height:20px; max-height:20px; }} QComboBox::drop-down {{ subcontrol-origin: padding; subcontrol-position: top left; border-width: 0px; }} QComboBox::down-arrow {{ image: url({}); }} '''.format(self.combobox_background.name(), arrow) # Windows fix, slashes should be always in unix-style self.stylesheet = self.stylesheet.replace('\\', '/') self.setFocusPolicy(Qt.StrongFocus) for widget in self.widgets: widget.setFocusPolicy(Qt.NoFocus) widget.setStyleSheet(self.stylesheet) layout_top = QHBoxLayout() layout_top.addWidget(self.combo_title) layout_top.addStretch() layout_top.addWidget(self.button_close) layout_top.addSpacerItem( QSpacerItem(self.offset_shadow, self.offset_shadow)) layout_content = QHBoxLayout() layout_content.addWidget(self.label_content) layout_content.addWidget(self.label_image) layout_content.addSpacerItem(QSpacerItem(5, 5)) layout_run = QHBoxLayout() layout_run.addStretch() layout_run.addWidget(self.button_run) layout_run.addStretch() layout_run.addSpacerItem( QSpacerItem(self.offset_shadow, self.offset_shadow)) layout_navigation = QHBoxLayout() layout_navigation.addWidget(self.button_home) layout_navigation.addWidget(self.button_previous) layout_navigation.addStretch() layout_navigation.addWidget(self.label_current) layout_navigation.addStretch() layout_navigation.addWidget(self.button_next) layout_navigation.addWidget(self.button_end) layout_navigation.addSpacerItem( QSpacerItem(self.offset_shadow, self.offset_shadow)) layout = QVBoxLayout() layout.addLayout(layout_top) layout.addStretch() layout.addSpacerItem(QSpacerItem(15, 15)) layout.addLayout(layout_content) layout.addLayout(layout_run) layout.addStretch() layout.addSpacerItem(QSpacerItem(15, 15)) layout.addLayout(layout_navigation) layout.addSpacerItem( QSpacerItem(self.offset_shadow, self.offset_shadow)) layout.setSizeConstraint(QLayout.SetFixedSize) self.setLayout(layout) self.set_funcs_before_fade_in([self._disable_widgets]) self.set_funcs_after_fade_in([self._enable_widgets, self.setFocus]) self.set_funcs_before_fade_out([self._disable_widgets]) self.setContextMenuPolicy(Qt.CustomContextMenu) # signals and slots # These are defined every time by the AnimatedTour Class def _disable_widgets(self): """ """ for widget in self.widgets: widget.setDisabled(True) def _enable_widgets(self): """ """ self.setWindowFlags(Qt.Dialog | Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint) for widget in self.widgets: widget.setDisabled(False) if self.button_disable == 'previous': self.button_previous.setDisabled(True) self.button_home.setDisabled(True) elif self.button_disable == 'next': self.button_next.setDisabled(True) self.button_end.setDisabled(True) def set_data(self, title, content, current, image, run, frames=None, step=None): """ """ self.label_title.setText(title) self.combo_title.clear() self.combo_title.addItems(frames) self.combo_title.setCurrentIndex(step) # min_content_len = max([len(f) for f in frames]) # self.combo_title.setMinimumContentsLength(min_content_len) # Fix and try to see how it looks with a combo box self.label_current.setText(current) self.button_current.setText(current) self.label_content.setText(content) self.image = image if image is None: self.label_image.setFixedHeight(1) self.label_image.setFixedWidth(1) else: extension = image.split('.')[-1] self.image = QPixmap(get_image_path(image), extension) self.label_image.setPixmap(self.image) self.label_image.setFixedSize(self.image.size()) if run is None: self.button_run.setVisible(False) else: self.button_run.setDisabled(False) self.button_run.setVisible(True) # Refresh layout self.layout().activate() def set_pos(self, x, y): """ """ self.x = ceil(x) self.y = ceil(y) self.move(QPoint(self.x, self.y)) def build_paths(self): """ """ geo = self.geometry() radius = 0 shadow = self.offset_shadow x0, y0 = geo.x(), geo.y() width, height = geo.width() - shadow, geo.height() - shadow left, top = 0, 0 right, bottom = width, height self.round_rect_path = QPainterPath() self.round_rect_path.moveTo(right, top + radius) self.round_rect_path.arcTo(right - radius, top, radius, radius, 0.0, 90.0) self.round_rect_path.lineTo(left + radius, top) self.round_rect_path.arcTo(left, top, radius, radius, 90.0, 90.0) self.round_rect_path.lineTo(left, bottom - radius) self.round_rect_path.arcTo(left, bottom - radius, radius, radius, 180.0, 90.0) self.round_rect_path.lineTo(right - radius, bottom) self.round_rect_path.arcTo(right - radius, bottom - radius, radius, radius, 270.0, 90.0) self.round_rect_path.closeSubpath() # Top path header = 36 offset = 2 left, top = offset, offset right = width - (offset) self.top_rect_path = QPainterPath() self.top_rect_path.lineTo(right, top + radius) self.top_rect_path.moveTo(right, top + radius) self.top_rect_path.arcTo(right - radius, top, radius, radius, 0.0, 90.0) self.top_rect_path.lineTo(left + radius, top) self.top_rect_path.arcTo(left, top, radius, radius, 90.0, 90.0) self.top_rect_path.lineTo(left, top + header) self.top_rect_path.lineTo(right, top + header) def paintEvent(self, event): """ """ self.build_paths() painter = QPainter(self) painter.setRenderHint(QPainter.Antialiasing) painter.fillPath(self.round_rect_path, self.color_back) painter.fillPath(self.top_rect_path, self.color_top) painter.strokePath(self.round_rect_path, QPen(Qt.gray, 1)) # TODO: Build the pointing arrow? def keyReleaseEvent(self, event): """ """ key = event.key() self.key_pressed = key keys = [ Qt.Key_Right, Qt.Key_Left, Qt.Key_Down, Qt.Key_Up, Qt.Key_Escape, Qt.Key_PageUp, Qt.Key_PageDown, Qt.Key_Home, Qt.Key_End, Qt.Key_Menu ] if key in keys: if not self.is_fade_running(): self.sig_key_pressed.emit() def mousePressEvent(self, event): """override Qt method""" # Raise the main application window on click self.parent.raise_() self.raise_() if event.button() == Qt.RightButton: pass # clicked_widget = self.childAt(event.x(), event.y()) # if clicked_widget == self.label_current: # self.context_menu_requested(event) def focusOutEvent(self, event): """Override Qt method.""" # To be used so tips do not appear outside spyder self.tour.lost_focus() def context_menu_requested(self, event): """ """ pos = QPoint(event.x(), event.y()) menu = QMenu(self) actions = [] action_title = create_action(self, _('Go to step: '), icon=QIcon()) action_title.setDisabled(True) actions.append(action_title) # actions.append(create_action(self, _(': '), icon=QIcon())) add_actions(menu, actions) menu.popup(self.mapToGlobal(pos)) def reject(self): """Qt method to handle escape key event""" if not self.is_fade_running(): key = Qt.Key_Escape self.key_pressed = key self.sig_key_pressed.emit()
class RectangularRegion(ChartItem): """ Rectangular overlay, that (optionally) can be resized by handles. TODO: * Notification framework * Modifiers to allow for more flexible mouse interactions """ def __init__(self, x, y, width=1, height=1, rotation=0, parent=None): """ Constructor. :param x: Initial x position of ROIs center. :param y: Initial y position of ROIs center. :param width: Initial width :param height: Initial height :param rotation: Initial rotation in radians :param parent: Optional parent item. """ super(RectangularRegion, self).__init__(parent) self.setFlags(QGraphicsItem.ItemIsMovable | QGraphicsItem.ItemIsFocusable | QGraphicsItem.ItemSendsGeometryChanges) # self.setHandlesChildEvents(False) # self.setFiltersChildEvents(True) self.__in_move = False self._path = QPainterPath() self.pen = QPen(QBrush(QColor(161, 0, 161, 255)), 1.0, Qt.SolidLine) self.pen.setCosmetic(True) self.brush = QBrush(QColor(255, 255, 255, 40)) self.state = RoiState() self.state.pos = QPointF(x, y) self.state.w0 = width self.state.w1 = width self.state.h0 = height self.state.h1 = height self.state.rotation = rotation self.setPos(self.state.pos) self.updatePath() self._handles = [] @property def handles(self): """ Returns all handles which are attached to the ROI. :return: list """ return self._handles def addHandle(self, handle): """ Adds a handle to the ROI. :param handle: Resize or rotate handle """ handle.setParentItem(self) # self.addToGroup(handle) self.handles.append(handle) handle.updatePosition() def removeHandle(self, handle): """ Removes the given handle from the ROI. :param handle: Handle :return: """ if handle not in self.handles: _log.warning("Handle not part of ROI.") return self.handles.remove(handle) # self.removeFromGroup(handle) self.scene().removeItem(handle) def boundingRect(self): return self._path.boundingRect() def updatePath(self): p0 = Vec2(self.state.w0, self.state.h0) p1 = Vec2(-self.state.w1, self.state.h0) p2 = Vec2(-self.state.w1, -self.state.h1) p3 = Vec2(self.state.w0, -self.state.h1) p0t = p0.rotate(self.state.rotation) p1t = p1.rotate(self.state.rotation) p2t = p2.rotate(self.state.rotation) p3t = p3.rotate(self.state.rotation) self._path = QPainterPath() self._path.moveTo(p0t.x, p0t.y) self._path.lineTo(p1t.x, p1t.y) self._path.lineTo(p2t.x, p2t.y) self._path.lineTo(p3t.x, p3t.y) self._path.closeSubpath() self.prepareGeometryChange() def paint(self, p=QPainter(), o=QStyleOptionGraphicsItem(), widget=None): p.setRenderHint(QPainter.Antialiasing) p.setPen(self.pen) p.setBrush(self.brush) p.drawPath(self._path) p.setBrush(Qt.transparent) p.drawLine(QLineF(-0.5, 0, 0.5, 0)) p.drawLine(QLineF(0, -0.5, 0, 0.5)) p.drawEllipse(QPointF(0, 0), 0.25, 0.25) def mousePressEvent(self, e): # !!!F*****g leason learned, call super to avoid weird jumps in position!!! super(RectangularRegion, self).mousePressEvent(e) self.__in_move = True def mouseReleaseEvent(self, e): super(RectangularRegion, self).mouseReleaseEvent(e) self.__in_move = False def itemChange(self, change, value): if change == QGraphicsItem.ItemPositionChange and self.__in_move: old_pos = self.pos() new_pos = value # .toPointF() delta = old_pos - new_pos _log.debug("Delta: {}".format(delta)) self.state.pos = new_pos value = new_pos for handle in self.handles: handle.updatePosition() return super(RectangularRegion, self).itemChange(change, value) def rotation(self): """ Override takes rotation from the state instead of items transformation. :return: rotation in degrees """ return self.state.rotation * 180 / np.pi def setRotation(self, degree): """ Override to propagate rotation to state instead of applying it to the items transform :param degree: Rotation in degrees """ self.state.rotation = (degree % 360) * np.pi / 180.0 for h in self.handles: h.updatePosition() self.updatePath()