def __init__(self, parent_item, src_item, dst_item, duration=2000): """Initializes animation stuff. Args: parent_item (QGraphicsItem): The item on top of which the animation should play. src_item (QGraphicsItem): The source item. dst_item (QGraphicsItem): The destination item. duration (int. optional): The desired duration of each loop in milliseconds, defaults to 1000. """ self._parent_item = parent_item self.src_item = src_item self.dst_item = dst_item font = QFont('Font Awesome 5 Free Solid') size = 0.875 * round(parent_item.rect().height() / 2) font.setPixelSize(size) self.src_item.setFont(font) self.dst_item.setFont(font) self.src_opacity_effect = QGraphicsOpacityEffect() self.src_item.setGraphicsEffect(self.src_opacity_effect) self.dst_opacity_effect = QGraphicsOpacityEffect() self.dst_item.setGraphicsEffect(self.dst_opacity_effect) self.timer = QTimeLine() self.timer.setLoopCount(0) # loop forever self.timer.setFrameRange(0, 10) self.timer.valueChanged.connect(self._handle_timer_value_changed) self.timer.setDuration(duration) self.src_animation = QGraphicsItemAnimation() self.src_animation.setItem(self.src_item) self.src_animation.setTimeLine(self.timer) self.dst_animation = QGraphicsItemAnimation() self.dst_animation.setItem(self.dst_item) self.dst_animation.setTimeLine(self.timer)
class ShootingLabel(QLabel): def __init__(self, origin, destination, parent=None, duration=1200): super().__init__("FIXME", parent=parent) self.origin = QPointF(origin) self.direction = QPointF(destination - origin) self.effect = QGraphicsOpacityEffect() self.setGraphicsEffect(self.effect) self.anim = QVariantAnimation() self.anim.setDuration(duration) self.anim.setStartValue(0.0) self.anim.setEndValue(1.0) self.anim.valueChanged.connect(self._handle_value_changed) self.anim.finished.connect(self.close) self.move(origin) self.setAttribute(Qt.WA_TransparentForMouseEvents) def _handle_value_changed(self, value): opacity = 1.0 - abs(2 * value - 1.0) self.effect.setOpacity(opacity) pos = self.origin + value * self.direction self.move(pos.toPoint()) def show(self): self.anim.start(QVariantAnimation.DeleteWhenStopped) super().show()
class BlackOverlay(QWidget): def __init__(self, parent): super(BlackOverlay, self).__init__(parent) self.main_widget = parent self.main_window = parent.parent() # AspectRatioWidget >> MainWindow self.resize(self.main_window.size().width(), self.main_window.size().height()) self.op = QGraphicsOpacityEffect(self) self.init_layout() def resizeEvent(self, event): super(BlackOverlay, self).resizeEvent(event) w = event.size().width() h = event.size().height() self.resize(w, h) def paintEvent(self, pe): o = QStyleOption() o.initFrom(self) p = QPainter(self) self.style().drawPrimitive(QStyle.PE_Widget, o, p, self) def init_layout(self): self.op.setOpacity( 0.50) # 0 to 1 will cause the fade effect to kick in self.setGraphicsEffect(self.op)
def __init__(self, parent, txt, anim_duration=500, life_span=2000): """ Args: parent (QWidget): Parent widget txt (str): Text to display in notification anim_duration (int): Duration of the animation in msecs life_span (int): How long does the notification stays in place in msecs """ super().__init__() self.setWindowFlags(Qt.Popup) self.setParent(parent) self._parent = parent self.label = QLabel(txt) self.label.setAlignment(Qt.AlignCenter) self.label.setWordWrap(True) self.label.setMargin(8) font = QFont() font.setBold(True) self.label.setFont(font) layout = QHBoxLayout() layout.addWidget(self.label) layout.setSizeConstraint(QLayout.SetFixedSize) layout.setContentsMargins(1, 0, 1, 0) self.setLayout(layout) self.adjustSize() # Move to the top right corner of the parent x = self._parent.size().width() - self.width() - 2 self.move(x, 0) self.setAttribute(Qt.WA_DeleteOnClose) self.setAttribute(Qt.WA_TranslucentBackground) ss = ("QWidget{background-color: rgba(255, 194, 179, 0.8);" "border-width: 2px;" "border-color: #ffebe6;" "border-style: groove; border-radius: 8px;}") self.setStyleSheet(ss) self.effect = QGraphicsOpacityEffect() self.setGraphicsEffect(self.effect) self.effect.setOpacity(0.0) self._opacity = 0.0 self.timer = QTimer(self) self.timer.setInterval(life_span) self.timer.timeout.connect(self.start_self_destruction) # Fade in animation self.fade_in_anim = QPropertyAnimation(self, b"opacity") self.fade_in_anim.setDuration(anim_duration) self.fade_in_anim.setStartValue(0.0) self.fade_in_anim.setEndValue(1.0) self.fade_in_anim.valueChanged.connect(self.update_opacity) self.fade_in_anim.finished.connect(self.timer.start) # Fade out animation self.fade_out_anim = QPropertyAnimation(self, b"opacity") self.fade_out_anim.setDuration(anim_duration) self.fade_out_anim.setStartValue(1.0) self.fade_out_anim.setEndValue(0) self.fade_out_anim.valueChanged.connect(self.update_opacity) self.fade_out_anim.finished.connect(self.close) # Start fade in animation self.fade_in_anim.start(QPropertyAnimation.DeleteWhenStopped)
class FWidget(QWidget): def __init__(self, *args, pos=(0, 0), shift=(0, 0), length=30, **kwargs): super(FWidget, self).__init__(*args, **kwargs) self.setWindowFlags(Qt.FramelessWindowHint | Qt.WindowMinimizeButtonHint) self.setAttribute(Qt.WA_TranslucentBackground) self.setAttribute(Qt.WA_TransparentForMouseEvents, True) self.length = length self.lengths = dict((i, length * i / 6) for i in range(1, 13)) self.resize(self.lengths[12], self.lengths[12]) self.center = length * 10, length * 9 self.opacity = QGraphicsOpacityEffect(self) x, y = pos a, b = shift self.move(x + a, y + b) self.setGraphicsEffect(self.opacity) self.opacity.setOpacity(0) self.animation = QPropertyAnimation(self.opacity, b'opacity') self.animation.setDuration(1000) self.animation.setStartValue(0) # self.animation.setKeyValueAt(0.25, 0.67) self.animation.setKeyValueAt(0.5, 1) # self.animation.setKeyValueAt(0.75, 0.67) self.animation.setEndValue(0) self.animation.setLoopCount(-1) def pos(self): x, y = super(FWidget, self).pos().toTuple() return int(x - self.center[0]), int(y - self.center[1]) def move(self, *arg__1): x, y = arg__1 super(FWidget, self).move(x + self.center[0], y + self.center[1]) pass def paintEvent(self, event: QPaintEvent): painter = QPainter() painter.begin(self) # painter.setRenderHints(QPainter.SmoothPixmapTransform) pen = QPen(Qt.black, 1, Qt.SolidLine) painter.setPen(pen) # 右上 painter.drawLine(self.lengths[8], self.lengths[1], self.lengths[11], self.lengths[1]) painter.drawLine(self.lengths[11], self.lengths[1], self.lengths[11], self.lengths[4]) # 左上 painter.drawLine(self.lengths[1], self.lengths[1], self.lengths[4], self.lengths[1]) painter.drawLine(self.lengths[1], self.lengths[1], self.lengths[1], self.lengths[4]) # 右下 painter.drawLine(self.lengths[8], self.lengths[11], self.lengths[11], self.lengths[11]) painter.drawLine(self.lengths[11], self.lengths[8], self.lengths[11], self.lengths[11]) # 左下 painter.drawLine(self.lengths[1], self.lengths[11], self.lengths[4], self.lengths[11]) painter.drawLine(self.lengths[1], self.lengths[11], self.lengths[1], self.lengths[8]) # painter.setPen(QPen(QColor(0, 160, 230), 2)) # # painter.setBrush(QColor(255, 160, 90)) # painter.drawRect(QRect(0, 0, self.length * 2, self.length * 2)) painter.end()
def __init__(self, parent): super(BlackOverlay, self).__init__(parent) self.main_widget = parent self.main_window = parent.parent() # AspectRatioWidget >> MainWindow self.resize(self.main_window.size().width(), self.main_window.size().height()) self.op = QGraphicsOpacityEffect(self) self.init_layout()
def __init__(self, origin, destination, parent=None, duration=1200): super().__init__("FIXME", parent=parent) self.origin = QPointF(origin) self.direction = QPointF(destination - origin) self.effect = QGraphicsOpacityEffect() self.setGraphicsEffect(self.effect) self.anim = QVariantAnimation() self.anim.setDuration(duration) self.anim.setStartValue(0.0) self.anim.setEndValue(1.0) self.anim.valueChanged.connect(self._handle_value_changed) self.anim.finished.connect(self.close) self.move(origin) self.setAttribute(Qt.WA_TransparentForMouseEvents)
def __init__(self, parent, row, col): super(Mark, self).__init__(parent) self.main_window = parent.parent().parent().parent() # CenterWidget >> AspectRatioWidget >> MainWindow self.table_width = 50 self.row = row self.col = col self.setAttribute(Qt.WA_NoSystemBackground) self.setAttribute(Qt.WA_TranslucentBackground) self.setAttribute(Qt.WA_TransparentForMouseEvents) self.op = QGraphicsOpacityEffect(self) self.op.setOpacity(0.50) # 0 to 1 will cause the fade effect to kick in self.setGraphicsEffect(self.op)
def set_to_fade_out(self, widget): fade_out_effect = QGraphicsOpacityEffect() self.current_effect = fade_out_effect widget.setGraphicsEffect(fade_out_effect) fade_out_anim = QPropertyAnimation(fade_out_effect, b"opacity") fade_out_anim.setDuration(1000) fade_out_anim.setStartValue(1) fade_out_anim.setEndValue(0) fade_out_anim.setEasingCurve(QEasingCurve.InBack) self.current_anim = fade_out_anim
def __init__(self, *args, pos=(0, 0), shift=(0, 0), length=30, **kwargs): super(FWidget, self).__init__(*args, **kwargs) self.setWindowFlags(Qt.FramelessWindowHint | Qt.WindowMinimizeButtonHint) self.setAttribute(Qt.WA_TranslucentBackground) self.setAttribute(Qt.WA_TransparentForMouseEvents, True) self.length = length self.lengths = dict((i, length * i / 6) for i in range(1, 13)) self.resize(self.lengths[12], self.lengths[12]) self.center = length * 10, length * 9 self.opacity = QGraphicsOpacityEffect(self) x, y = pos a, b = shift self.move(x + a, y + b) self.setGraphicsEffect(self.opacity) self.opacity.setOpacity(0) self.animation = QPropertyAnimation(self.opacity, b'opacity') self.animation.setDuration(1000) self.animation.setStartValue(0) # self.animation.setKeyValueAt(0.25, 0.67) self.animation.setKeyValueAt(0.5, 1) # self.animation.setKeyValueAt(0.75, 0.67) self.animation.setEndValue(0) self.animation.setLoopCount(-1)
def init_ui(self): self.setMinimumSize(600, 400) self.setWindowTitle('Sandy Screen') # Menu widget self.menu = SandyMenu(self) # Sandbox container widget and its background and canvas label stack self.sandbox = QWidget(self) self.sandbox.setGeometry(0, 0, 600, 400) self.sandbox_bg = QLabel(self.sandbox) self.sandbox_bg.setGeometry(0, 0, 600, 400) self.sandbox_bg.setPixmap( QPixmap(['1 1 1 1', '1 c #000000', '1']).scaled(self.sandbox_bg.size())) self.canvases = [QLabel(self.sandbox), QLabel(self.sandbox)] for c in self.canvases: c.setAlignment(Qt.AlignCenter) c.setGeometry(0, 0, 600, 400) self.canvases[1].setPixmap(QPixmap(generate_xpm(self.sandpile)[0])) self.sandpile.topple_step() self.canvases[0].setPixmap(QPixmap(generate_xpm(self.sandpile)[0])) # Opacity effect on the upper frame label self.opeff = QGraphicsOpacityEffect(self.canvases[-1]) self.opeff.setOpacity(1) self.canvases[-1].setGraphicsEffect(self.opeff) # Main stack layout self.layout = QStackedLayout(self) self.layout.addWidget(self.sandbox) self.layout.addWidget(self.menu) # Overlay pause icon label self.pause_label = QLabel(self) self.pause_label.setAlignment(Qt.AlignCenter) self.pause_label.setPixmap(QPixmap(ImageQt.ImageQt(self.pause_icon)))
class Mark(QWidget): def __init__(self, parent, row, col): super(Mark, self).__init__(parent) self.main_window = parent.parent().parent().parent() # CenterWidget >> AspectRatioWidget >> MainWindow self.table_width = 50 self.row = row self.col = col self.setAttribute(Qt.WA_NoSystemBackground) self.setAttribute(Qt.WA_TranslucentBackground) self.setAttribute(Qt.WA_TransparentForMouseEvents) self.op = QGraphicsOpacityEffect(self) self.op.setOpacity(0.50) # 0 to 1 will cause the fade effect to kick in self.setGraphicsEffect(self.op) def paintEvent(self, pe): o = QStyleOption() o.initFrom(self) p = QPainter(self) self.style().drawPrimitive(QStyle.PE_Widget, o, p, self) def update_size(self, w, h): side_width = self.main_window.aspect_ratio_widget.side_widget.width() if w - side_width > h: self.table_width = h else: self.table_width = w - side_width cell_width = (self.table_width - 20) / 8 width = cell_width / 4 self.setStyleSheet("border-radius: " + str(width / 2 - 1) + "px; background: white; opacity:0.5;") self.resize(width, width) self.move(cell_width * self.col + 3 * width / 2 + 10, cell_width * self.row + 3 * width / 2 + 10)
def addBackground(self): scene = self.scene() if not DisplayOptions.map_poly: bg = QPixmap("./resources/" + self.game.theater.overview_image) scene.addPixmap(bg) # Apply graphical effects to simulate current daytime if self.game.current_turn_time_of_day == TimeOfDay.Day: pass elif self.game.current_turn_time_of_day == TimeOfDay.Night: ov = QPixmap(bg.width(), bg.height()) ov.fill(CONST.COLORS["night_overlay"]) overlay = scene.addPixmap(ov) effect = QGraphicsOpacityEffect() effect.setOpacity(0.7) overlay.setGraphicsEffect(effect) else: ov = QPixmap(bg.width(), bg.height()) ov.fill(CONST.COLORS["dawn_dust_overlay"]) overlay = scene.addPixmap(ov) effect = QGraphicsOpacityEffect() effect.setOpacity(0.3) overlay.setGraphicsEffect(effect) else: # Polygon display mode if self.game.theater.landmap is not None: for sea_zone in self.game.theater.landmap[2]: print(sea_zone) poly = QPolygonF([QPointF(*self._transform_point(Point(point[0], point[1]))) for point in sea_zone]) scene.addPolygon(poly, CONST.COLORS["sea_blue"], CONST.COLORS["sea_blue"]) for inclusion_zone in self.game.theater.landmap[0]: poly = QPolygonF([QPointF(*self._transform_point(Point(point[0], point[1]))) for point in inclusion_zone]) scene.addPolygon(poly, CONST.COLORS["grey"], CONST.COLORS["dark_grey"]) for exclusion_zone in self.game.theater.landmap[1]: poly = QPolygonF([QPointF(*self._transform_point(Point(point[0], point[1]))) for point in exclusion_zone]) scene.addPolygon(poly, CONST.COLORS["grey"], CONST.COLORS["dark_dark_grey"])
def addBackground(self): scene = self.scene() bg = QPixmap("./resources/" + self.game.theater.overview_image) scene.addPixmap(bg) # Apply graphical effects to simulate current daytime if self.game.current_turn_daytime == "day": pass elif self.game.current_turn_daytime == "night": ov = QPixmap(bg.width(), bg.height()) ov.fill(CONST.COLORS["night_overlay"]) overlay = scene.addPixmap(ov) effect = QGraphicsOpacityEffect() effect.setOpacity(0.7) overlay.setGraphicsEffect(effect) else: ov = QPixmap(bg.width(), bg.height()) ov.fill(CONST.COLORS["dawn_dust_overlay"]) overlay = scene.addPixmap(ov) effect = QGraphicsOpacityEffect() effect.setOpacity(0.3) overlay.setGraphicsEffect(effect)
class ImportExportAnimation: def __init__(self, parent_item, src_item, dst_item, duration=2000): """Initializes animation stuff. Args: parent_item (QGraphicsItem): The item on top of which the animation should play. src_item (QGraphicsItem): The source item. dst_item (QGraphicsItem): The destination item. duration (int. optional): The desired duration of each loop in milliseconds, defaults to 1000. """ self._parent_item = parent_item self.src_item = src_item self.dst_item = dst_item font = QFont('Font Awesome 5 Free Solid') size = 0.875 * round(parent_item.rect().height() / 2) font.setPixelSize(size) self.src_item.setFont(font) self.dst_item.setFont(font) self.src_opacity_effect = QGraphicsOpacityEffect() self.src_item.setGraphicsEffect(self.src_opacity_effect) self.dst_opacity_effect = QGraphicsOpacityEffect() self.dst_item.setGraphicsEffect(self.dst_opacity_effect) self.timer = QTimeLine() self.timer.setLoopCount(0) # loop forever self.timer.setFrameRange(0, 10) self.timer.valueChanged.connect(self._handle_timer_value_changed) self.timer.setDuration(duration) self.src_animation = QGraphicsItemAnimation() self.src_animation.setItem(self.src_item) self.src_animation.setTimeLine(self.timer) self.dst_animation = QGraphicsItemAnimation() self.dst_animation.setItem(self.dst_item) self.dst_animation.setTimeLine(self.timer) @Slot(float) def _handle_timer_value_changed(self, value): self.src_opacity_effect.setOpacity(1.0 - 2 * value) self.dst_opacity_effect.setOpacity(2 * value - 1.0) def start(self): """Starts the animation.""" rect = self._parent_item.rect() dx = self.src_item.boundingRect().width() dy = self.dst_item.boundingRect().height() rect.adjust(0, 0, -dx, -dy) src, dst = rect.topLeft(), rect.bottomRight() vec = dst - src self.src_item.setParentItem(self._parent_item) self.dst_item.setParentItem(self._parent_item) self.src_item.setPos(src) self.dst_item.setPos(src) self.src_opacity_effect.setOpacity(0.0) self.dst_opacity_effect.setOpacity(0.0) for i in range(100): step = i / 100.0 self.src_animation.setPosAt(step, src + vec * step) self.dst_animation.setPosAt(step, src + vec * step) self.timer.start() def stop(self): """Stops the animation""" self.timer.stop() self.src_item.setParentItem(None) self.dst_item.setParentItem(None) self.src_item.scene().removeItem(self.src_item) self.dst_item.scene().removeItem(self.dst_item) self.timer.setCurrentTime(999)
def setupWidget(self): # Top self.pinBtn = ButtonIcon(icon=f"{self.resourcePath}/pin.svg", iconsize=15) self.closeBtn = ButtonIcon(icon=f"{self.resourcePath}/cancel.svg", iconsize=15) self.topLayout = QHBoxLayout() self.topLayout.setContentsMargins(5, 5, 5, 5) self.topLayout.addWidget(self.pinBtn) self.topLayout.addStretch() self.topLayout.addWidget(self.closeBtn) # Middle self.playBtn = ButtonIcon(icon=f"{self.resourcePath}/play.svg", iconsize=100) self.volumeSlider = QSlider(Qt.Vertical, self) self.volumeSlider.setMaximum(100) self.volumeSlider.setValue(100) self.volumeBtn = ButtonIcon(icon=f"{self.resourcePath}/speaker.svg", iconsize=15) self.volumeLayout = QVBoxLayout() self.volumeLayout.setContentsMargins(0, 0, 0, 0) for w in (self.volumeSlider, self.volumeBtn): self.volumeLayout.addWidget(w) self.playLayout = QHBoxLayout() self.playLayout.addStretch() self.playLayout.addWidget(self.playBtn) self.playLayout.addStretch() self.playLayout.addLayout(self.volumeLayout) # Bottom self.addBtn = ButtonIcon(icon=f"{self.resourcePath}/plus.svg", iconsize=15) self.timeSlider = TimeSlider(Qt.Horizontal, self) self.volumeSlider.setStyleSheet(self.timeSlider.qss()) self.repeatBtn = ButtonIcon(icon=f"{self.resourcePath}/replay.svg", iconsize=15) self.listBtn = ButtonIcon(icon=f"{self.resourcePath}/list.svg", iconsize=15) self.bottomLayout = QHBoxLayout() self.bottomLayout.setContentsMargins(0, 0, 0, 0) self.bottomLayout.addWidget(self.addBtn) self.bottomLayout.addWidget(self.listBtn) self.bottomLayout.addWidget(self.timeSlider) self.bottomLayout.addWidget(self.repeatBtn) self.layout().addLayout(self.topLayout) self.layout().addStretch() self.layout().addLayout(self.playLayout) self.layout().addStretch() self.layout().addLayout(self.bottomLayout) self.timer = QTimer() self.timer.setInterval(50) self.timer.timeout.connect(self.toggleCursor) self.timer.start() self.opacFX = [] for w in (self.pinBtn, self.closeBtn, self.playBtn, self.volumeSlider, self.volumeBtn, self.addBtn, self.repeatBtn, self.listBtn): w.setFocusProxy(self) fx = QGraphicsOpacityEffect(w) fx.setOpacity(0) w.setGraphicsEffect(fx) self.opacFX.append(fx) self.timeSlider.setHeight(1) self.timeSlider.setFocusProxy(self)
def addBackground(self): scene = self.scene() if not DisplayOptions.map_poly: bg = QPixmap("./resources/" + self.game.theater.overview_image) scene.addPixmap(bg) # Apply graphical effects to simulate current daytime if self.game.current_turn_time_of_day == TimeOfDay.Day: pass elif self.game.current_turn_time_of_day == TimeOfDay.Night: ov = QPixmap(bg.width(), bg.height()) ov.fill(CONST.COLORS["night_overlay"]) overlay = scene.addPixmap(ov) effect = QGraphicsOpacityEffect() effect.setOpacity(0.7) overlay.setGraphicsEffect(effect) else: ov = QPixmap(bg.width(), bg.height()) ov.fill(CONST.COLORS["dawn_dust_overlay"]) overlay = scene.addPixmap(ov) effect = QGraphicsOpacityEffect() effect.setOpacity(0.3) overlay.setGraphicsEffect(effect) if DisplayOptions.map_poly or self.reference_point_setup_mode: # Polygon display mode if self.game.theater.landmap is not None: for sea_zone in self.game.theater.landmap.sea_zones: print(sea_zone) poly = QPolygonF([ QPointF( *self._transform_point(Point(point[0], point[1]))) for point in sea_zone.exterior.coords ]) if self.reference_point_setup_mode: color = "sea_blue_transparent" else: color = "sea_blue" scene.addPolygon(poly, CONST.COLORS[color], CONST.COLORS[color]) for inclusion_zone in self.game.theater.landmap.inclusion_zones: poly = QPolygonF([ QPointF( *self._transform_point(Point(point[0], point[1]))) for point in inclusion_zone.exterior.coords ]) if self.reference_point_setup_mode: scene.addPolygon(poly, CONST.COLORS["grey_transparent"], CONST.COLORS["dark_grey_transparent"]) else: scene.addPolygon(poly, CONST.COLORS["grey"], CONST.COLORS["dark_grey"]) for exclusion_zone in self.game.theater.landmap.exclusion_zones: poly = QPolygonF([ QPointF( *self._transform_point(Point(point[0], point[1]))) for point in exclusion_zone.exterior.coords ]) if self.reference_point_setup_mode: scene.addPolygon( poly, CONST.COLORS["grey_transparent"], CONST.COLORS["dark_dark_grey_transparent"]) else: scene.addPolygon(poly, CONST.COLORS["grey"], CONST.COLORS["dark_dark_grey"]) # Uncomment to display plan projection test # self.projection_test() self.draw_scale() if self.reference_point_setup_mode: for i, point in enumerate(self.game.theater.reference_points): self.scene().addRect(QRectF(point.image_coordinates.x, point.image_coordinates.y, 25, 25), pen=CONST.COLORS["red"], brush=CONST.COLORS["red"]) text = self.scene().addText( f"P{i} = {point.image_coordinates}", font=QFont("Trebuchet MS", 14, weight=8, italic=False)) text.setDefaultTextColor(CONST.COLORS["red"]) text.setPos(point.image_coordinates.x + 26, point.image_coordinates.y) # Set to True to visually debug _transform_point. draw_transformed = False if draw_transformed: x, y = self._transform_point(point.world_coordinates) self.scene().addRect(QRectF(x, y, 25, 25), pen=CONST.COLORS["red"], brush=CONST.COLORS["red"]) text = self.scene().addText(f"P{i}' = {x}, {y}", font=QFont("Trebuchet MS", 14, weight=8, italic=False)) text.setDefaultTextColor(CONST.COLORS["red"]) text.setPos(x + 26, y)
class SandyScreen(QWidget): def __init__(self, root): QWidget.__init__(self) self.root = root # Setting state vars self.app_running = True self.ctrl_down = False self.in_fullscreen = False self.in_menu = False self.on_pause = True # Setting animation vars self.timer_delay = 10 self.phase = 1 self.delta_per_tick = 1 / 30 self.xpmsz = None self.geo = [0, 0, 0, 0] # Creating timer and sandpile self.timer = QTimer(self) self.seed = None self.piletype = None self.sandpile = None self.reroll_pile() # Generating pause icon self.pause_icon = Image.new('RGBA', size=(60, 60)) for i in range(60): for j in range(60): self.pause_icon.putpixel( (j, i), (255, 255, 255, 0 if 20 < j < 40 else 100)) # Initialising UI and running self.init_ui() self.show() def init_ui(self): self.setMinimumSize(600, 400) self.setWindowTitle('Sandy Screen') # Menu widget self.menu = SandyMenu(self) # Sandbox container widget and its background and canvas label stack self.sandbox = QWidget(self) self.sandbox.setGeometry(0, 0, 600, 400) self.sandbox_bg = QLabel(self.sandbox) self.sandbox_bg.setGeometry(0, 0, 600, 400) self.sandbox_bg.setPixmap( QPixmap(['1 1 1 1', '1 c #000000', '1']).scaled(self.sandbox_bg.size())) self.canvases = [QLabel(self.sandbox), QLabel(self.sandbox)] for c in self.canvases: c.setAlignment(Qt.AlignCenter) c.setGeometry(0, 0, 600, 400) self.canvases[1].setPixmap(QPixmap(generate_xpm(self.sandpile)[0])) self.sandpile.topple_step() self.canvases[0].setPixmap(QPixmap(generate_xpm(self.sandpile)[0])) # Opacity effect on the upper frame label self.opeff = QGraphicsOpacityEffect(self.canvases[-1]) self.opeff.setOpacity(1) self.canvases[-1].setGraphicsEffect(self.opeff) # Main stack layout self.layout = QStackedLayout(self) self.layout.addWidget(self.sandbox) self.layout.addWidget(self.menu) # Overlay pause icon label self.pause_label = QLabel(self) self.pause_label.setAlignment(Qt.AlignCenter) self.pause_label.setPixmap(QPixmap(ImageQt.ImageQt(self.pause_icon))) def restart_pile(self): del self.sandpile self.sandpile = self.piletype(copy.deepcopy(self.seed), frozen=True, timed=False, vocal=False) print('restart called') def reroll_pile(self, piletype=None, seed=None): if seed: self.seed = seed else: v = random.randint(8, 33) self.seed = [[v for j in range(_X)] for i in range(_Y)] if piletype: self.piletype = piletype else: v = random.randint(0, 3) self.piletype = [t4f, t6hf, t6vf, t8f][v] self.sandpile = self.piletype(copy.deepcopy(self.seed), frozen=True, timed=False, vocal=False) def run(self): self.root.exec_() def closeEvent(self, event): self.timer.stop() self.app_running = False def keyPressEvent(self, event): k = event.key() if k == 16777236: self.update_sandbox(1) # if k == _CTRL: self.ctrl_down = True if self.ctrl_down: if k == _M: self.toggle_menu() # Menu toggled on Ctrl+M elif k == _R: self.reroll_pile() else: if k == _F11: self.toggle_fullscreen() elif k == _SPACE and not self.in_menu: self.toggle_pause() def keyReleaseEvent(self, event): if event.key() == _CTRL: self.ctrl_down = False def resizeEvent(self, event): self.pause_label.setGeometry(self.rect()) sbg = self.sandbox.geometry() sbs = self.sandbox.size() self.sandbox_bg.setGeometry(sbg) self.sandbox_bg.setPixmap(self.sandbox_bg.pixmap().scaled( self.sandbox_bg.size())) for c in self.canvases: c.setGeometry(sbg) c.setPixmap(c.pixmap().scaled(sbs, Qt.KeepAspectRatio)) ### Fix this. def toggle_fullscreen(self): self.in_fullscreen = not self.in_fullscreen self.showFullScreen() if self.in_fullscreen else self.showNormal() def toggle_menu(self): self.in_menu = not self.in_menu if self.in_menu: self.layout.setCurrentIndex(1) self.pause_label.setVisible(False) self.on_pause = True self.root.restoreOverrideCursor() else: self.layout.setCurrentIndex(0) if self.on_pause: self.pause_label.raise_() self.pause_label.setVisible(True) else: self.root.setOverrideCursor(Qt.BlankCursor) self.resizeEvent(None) def toggle_pause(self): self.on_pause = not self.on_pause if self.on_pause: self.timer.stop() self.pause_label.raise_() self.pause_label.setVisible(True) self.root.restoreOverrideCursor() else: self.pause_label.setVisible(False) self.timer.singleShot(self.timer_delay, lambda: self.update_sandbox(0)) self.root.setOverrideCursor(Qt.BlankCursor) def update_sandbox(self, mode): if not self.in_menu: if mode == self.on_pause: self.phase -= self.delta_per_tick if self.phase <= 0: self.canvases[-1].setPixmap(self.canvases[0].pixmap()) self.phase = 1 self.opeff.setOpacity(self.phase) if not self.sandpile.topple_step() and not self.on_pause: self.toggle_pause() xpm, sz = generate_xpm(self.sandpile) self.canvases[0].setPixmap( QPixmap(xpm).scaled(self.sandbox.size(), Qt.KeepAspectRatio)) else: self.opeff.setOpacity( math.pow(math.sin(math.pi * self.phase / 2), 2)) if mode == 0 and self.app_running: self.timer.singleShot(self.timer_delay, lambda: self.update_sandbox(0))
def __init__(self, *args, **kwargs): super(EmptyVolumeUI, self).__init__(*args, **kwargs) self.visible = QGraphicsOpacityEffect(self) self.visible.setOpacity(1.0) self.disvisible = QGraphicsOpacityEffect(self) self.disvisible.setOpacity(0.0) main_layout = QHBoxLayout() self.variety_tree = VarietyTree(self) main_layout.addWidget(self.variety_tree) self.right_widget = QWidget(self) right_layout = QVBoxLayout() right_layout.setContentsMargins(QMargins(1, 1, 1, 1)) opts_layout = QHBoxLayout() # 选择分析的目标数据类别 self.radio_button_group = QButtonGroup(self) radio_button_1 = QRadioButton("行情统计", self) radio_button_1.setChecked(True) self.radio_button_group.addButton(radio_button_1) radio_button_2 = QRadioButton("排名持仓", self) self.radio_button_group.addButton(radio_button_2) opts_layout.addWidget(radio_button_1) opts_layout.addWidget(radio_button_2) self.rank_spinbox = QSpinBox(self) self.rank_spinbox.setPrefix("前 ") self.rank_spinbox.setSuffix(" 名") self.rank_spinbox.setRange(1, 20) self.rank_spinbox.setValue(20) self.rank_spinbox.setEnabled(False) opts_layout.addWidget(self.rank_spinbox) # 分割线 vertical_line = QFrame(self) vertical_line.setFrameShape(QFrame.VLine) opts_layout.addWidget(vertical_line) opts_layout.addWidget(QLabel("选择合约:", self)) self.contract_combobox = QComboBox(self) opts_layout.addWidget(self.contract_combobox) self.confirm_button = QPushButton("确定", self) opts_layout.addWidget(self.confirm_button) self.tip_button = QPushButton('左侧选择品种后进行查询 ', self) # 提示文字 opts_layout.addWidget(self.tip_button) self.tip_button.setGraphicsEffect(self.disvisible) opts_layout.addStretch() right_layout.addLayout(opts_layout) self.web_container = QWebEngineView(self) right_layout.addWidget(self.web_container) self.right_widget.setLayout(right_layout) main_layout.addWidget(self.right_widget) self.setStretchFactor(1, 2) self.setStretchFactor(2, 8) self.setHandleWidth(1) self.contract_combobox.setMinimumWidth(80) self.setLayout(main_layout) self.tip_button.setObjectName("tipButton") self.setStyleSheet( "#tipButton{border:none;color:rgb(230,50,50);font-weight:bold;}")
class Notification(QFrame): """Custom pop-up notification widget with fade-in and fade-out effect.""" def __init__(self, parent, txt, anim_duration=500, life_span=None, word_wrap=True, corner=Qt.TopRightCorner): """ Args: parent (QWidget): Parent widget txt (str): Text to display in notification anim_duration (int): Duration of the animation in msecs life_span (int): How long does the notification stays in place in msecs word_wrap (bool) corner (Qt.Corner) """ super().__init__() if life_span is None: word_count = len(txt.split(" ")) mspw = 60000 / 140 # Assume people can read ~140 words per minute life_span = mspw * word_count self.setFocusPolicy(Qt.NoFocus) self.setWindowFlags(Qt.Popup) self.setParent(parent) self._parent = parent self._corner = corner self.label = QLabel(txt) self.label.setMaximumSize(parent.size()) self.label.setAlignment(Qt.AlignCenter) self.label.setWordWrap(word_wrap) self.label.setMargin(8) self.label.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum) font = QFont() font.setBold(True) self.label.setFont(font) layout = QHBoxLayout() layout.addWidget(self.label) layout.setSizeConstraint(QLayout.SetMinimumSize) layout.setContentsMargins(3, 3, 3, 3) self.setLayout(layout) self.adjustSize() self.setAttribute(Qt.WA_DeleteOnClose) self.setObjectName("Notification") self._background_color = "#e6ffc2b3" ss = ("QFrame#Notification{" f"background-color: {self._background_color};" "border-width: 2px;" "border-color: #ffebe6;" "border-style: groove; border-radius: 8px;}") self.setStyleSheet(ss) self.setAcceptDrops(True) self.effect = QGraphicsOpacityEffect() self.setGraphicsEffect(self.effect) self.effect.setOpacity(0.0) self._opacity = 0.0 self.timer = QTimer(self) self.timer.setInterval(life_span) self.timer.timeout.connect(self.start_self_destruction) # Fade in animation self.fade_in_anim = QPropertyAnimation(self, b"opacity") self.fade_in_anim.setDuration(anim_duration) self.fade_in_anim.setStartValue(0.0) self.fade_in_anim.setEndValue(1.0) self.fade_in_anim.valueChanged.connect(self.update_opacity) self.fade_in_anim.finished.connect(self.timer.start) # Fade out animation self.fade_out_anim = QPropertyAnimation(self, b"opacity") self.fade_out_anim.setDuration(anim_duration) self.fade_out_anim.setStartValue(1.0) self.fade_out_anim.setEndValue(0) self.fade_out_anim.valueChanged.connect(self.update_opacity) self.fade_out_anim.finished.connect(self.close) # Start fade in animation self.fade_in_anim.start(QPropertyAnimation.DeleteWhenStopped) def show(self): # Move to the top right corner of the parent super().show() if self._corner in (Qt.TopRightCorner, Qt.BottomRightCorner): x = self._parent.size().width() - self.width() - 2 else: x = self.pos().x() if self._corner in (Qt.BottomLeftCorner, Qt.BottomRightCorner): y = self._parent.size().height() - self.height() - 2 else: y = self.pos().y() self.move(x, y) def get_opacity(self): """opacity getter.""" return self._opacity def set_opacity(self, op): """opacity setter.""" self._opacity = op @Slot(float) def update_opacity(self, value): """Updates graphics effect opacity.""" self.effect.setOpacity(value) def start_self_destruction(self): """Starts fade-out animation and closing of the notification.""" self.fade_out_anim.start(QPropertyAnimation.DeleteWhenStopped) self.setAttribute(Qt.WA_TransparentForMouseEvents) def enterEvent(self, e): super().enterEvent(e) self.start_self_destruction() def dragEnterEvent(self, e): super().dragEnterEvent(e) self.start_self_destruction() def remaining_time(self): if self.timer.isActive(): return self.timer.remainingTime() if self.fade_out_anim.state() == QPropertyAnimation.Running: return 0 return self.timer.interval() opacity = Property(float, get_opacity, set_opacity)
def __init__(self, parent, txt, anim_duration=500, life_span=None, alignment=Qt.AlignCenter): """ Args: parent (QWidget): Parent widget txt (str): Text to display in notification anim_duration (int): Duration of the animation in msecs life_span (int): How long does the notification stays in place in msecs """ super().__init__() if life_span is None: word_count = len(txt.split(" ")) mspw = 60000 / 140 # Assume people can read ~140 words per minute life_span = mspw * word_count self.setWindowFlags(Qt.Popup) self.setParent(parent) self._parent = parent self.label = QLabel(txt) self.label.setMaximumSize(parent.size()) self.label.setAlignment(alignment) self.label.setWordWrap(True) self.label.setMargin(8) self.label.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum) font = QFont() font.setBold(True) self.label.setFont(font) layout = QHBoxLayout() layout.addWidget(self.label) layout.setSizeConstraint(QLayout.SetMinimumSize) layout.setContentsMargins(1, 0, 1, 0) self.setLayout(layout) self.adjustSize() self.setAttribute(Qt.WA_DeleteOnClose) self.setAttribute(Qt.WA_TranslucentBackground) ss = ( "QWidget{background-color: rgba(255, 194, 179, 0.9);" "border-width: 2px;" "border-color: #ffebe6;" "border-style: groove; border-radius: 8px;}" ) self.setStyleSheet(ss) self.setAcceptDrops(True) self.effect = QGraphicsOpacityEffect() self.setGraphicsEffect(self.effect) self.effect.setOpacity(0.0) self._opacity = 0.0 self.timer = QTimer(self) self.timer.setInterval(life_span) self.timer.timeout.connect(self.start_self_destruction) # Fade in animation self.fade_in_anim = QPropertyAnimation(self, b"opacity") self.fade_in_anim.setDuration(anim_duration) self.fade_in_anim.setStartValue(0.0) self.fade_in_anim.setEndValue(1.0) self.fade_in_anim.valueChanged.connect(self.update_opacity) self.fade_in_anim.finished.connect(self.timer.start) # Fade out animation self.fade_out_anim = QPropertyAnimation(self, b"opacity") self.fade_out_anim.setDuration(anim_duration) self.fade_out_anim.setStartValue(1.0) self.fade_out_anim.setEndValue(0) self.fade_out_anim.valueChanged.connect(self.update_opacity) self.fade_out_anim.finished.connect(self.close) # Start fade in animation self.fade_in_anim.start(QPropertyAnimation.DeleteWhenStopped)
class Notification(QWidget): """Custom pop-up notification widget with fade-in and fade-out effect.""" def __init__(self, parent, txt, anim_duration=500, life_span=2000): """ Args: parent (QWidget): Parent widget txt (str): Text to display in notification anim_duration (int): Duration of the animation in msecs life_span (int): How long does the notification stays in place in msecs """ super().__init__() self.setWindowFlags(Qt.Popup) self.setParent(parent) self._parent = parent self.label = QLabel(txt) self.label.setAlignment(Qt.AlignCenter) self.label.setWordWrap(True) self.label.setMargin(8) font = QFont() font.setBold(True) self.label.setFont(font) layout = QHBoxLayout() layout.addWidget(self.label) layout.setSizeConstraint(QLayout.SetFixedSize) layout.setContentsMargins(1, 0, 1, 0) self.setLayout(layout) self.adjustSize() # Move to the top right corner of the parent x = self._parent.size().width() - self.width() - 2 self.move(x, 0) self.setAttribute(Qt.WA_DeleteOnClose) self.setAttribute(Qt.WA_TranslucentBackground) ss = ("QWidget{background-color: rgba(255, 194, 179, 0.8);" "border-width: 2px;" "border-color: #ffebe6;" "border-style: groove; border-radius: 8px;}") self.setStyleSheet(ss) self.effect = QGraphicsOpacityEffect() self.setGraphicsEffect(self.effect) self.effect.setOpacity(0.0) self._opacity = 0.0 self.timer = QTimer(self) self.timer.setInterval(life_span) self.timer.timeout.connect(self.start_self_destruction) # Fade in animation self.fade_in_anim = QPropertyAnimation(self, b"opacity") self.fade_in_anim.setDuration(anim_duration) self.fade_in_anim.setStartValue(0.0) self.fade_in_anim.setEndValue(1.0) self.fade_in_anim.valueChanged.connect(self.update_opacity) self.fade_in_anim.finished.connect(self.timer.start) # Fade out animation self.fade_out_anim = QPropertyAnimation(self, b"opacity") self.fade_out_anim.setDuration(anim_duration) self.fade_out_anim.setStartValue(1.0) self.fade_out_anim.setEndValue(0) self.fade_out_anim.valueChanged.connect(self.update_opacity) self.fade_out_anim.finished.connect(self.close) # Start fade in animation self.fade_in_anim.start(QPropertyAnimation.DeleteWhenStopped) def get_opacity(self): """opacity getter.""" return self._opacity def set_opacity(self, op): """opacity setter.""" self._opacity = op @Slot(float) def update_opacity(self, value): """Updates graphics effect opacity.""" self.effect.setOpacity(value) def start_self_destruction(self): """Starts fade-out animation and closing of the notification.""" self.fade_out_anim.start(QPropertyAnimation.DeleteWhenStopped) def enterEvent(self, e): super().enterEvent(e) self.start_self_destruction() self.setAttribute(Qt.WA_TransparentForMouseEvents) def remaining_time(self): if self.timer.isActive(): return self.timer.remainingTime() if self.fade_out_anim.state() == QPropertyAnimation.Running: return 0 return self.timer.interval() opacity = Property(float, get_opacity, set_opacity)
def info(self, message: str) -> None: """ This function will show a box with a message that will fade in and then out. :param message: The message to show inside of the window :type message: str :return: None :rtype: NoneType """ # QMessageBox.information(self, title, message) label = QLabel(self) windowWidth = self.width() windowHeight = self.height() labelWidth = 700 labelHeight = 300 label.setGeometry(windowWidth / 2 - labelWidth / 2, windowHeight / 3 - labelHeight / 2, labelWidth, labelHeight) label.show() style = "border: 3px solid red;" \ "border-radius:20px;" \ "background-color:#353535;" \ "color:#dddddd" label.setStyleSheet(style) label.setAlignment(Qt.AlignCenter) label.setText(message) fadeInTimer = QTimer() waitTimer = QTimer() fadeOutTimer = QTimer() waitTimer.setSingleShot(True) waitTimer.setInterval(3000) effect = QGraphicsOpacityEffect(label) label.setGraphicsEffect(effect) effect.setOpacity(0) def fadeIn(): opacity = effect.opacity() + 0.01 effect.setOpacity(opacity) if opacity >= 1: fadeInTimer.stop() waitTimer.start() def wait(): fadeOutTimer.start(10) def fadeOut(): opacity = effect.opacity() - 0.01 effect.setOpacity(opacity) if opacity <= 0: fadeOutTimer.stop() label.hide() fadeInTimer.timeout.connect(fadeIn) waitTimer.timeout.connect(wait) fadeOutTimer.timeout.connect(fadeOut) fadeInTimer.start(10)