class Tab(QObject): def __init__(self, parent): QObject.__init__(self, parent) self._toolbar = parent self.icon = None self.text = "" self.has_menu = False self.enabled = True self._fader = 0 self._animator = QPropertyAnimation(self) self._animator.setPropertyName(b"fader") self._animator.setTargetObject(self) def fade_in(self): self._animator.stop() self._animator.setDuration(80) self._animator.setEndValue(1) self._animator.start() def fade_out(self): self._animator.stop() self._animator.setDuration(160) self._animator.setEndValue(0) self._animator.start() def _set_fader(self, value): self._fader = value self._toolbar.update() def _get_fader(self): return self._fader fader = pyqtProperty(float, fget=_get_fader, fset=_set_fader)
def load_animation2(window: object, property_name: bytes = b'windowOpacity') -> None: animation = QPropertyAnimation() animation.setTargetObject(window) # 设置动画目标对象 # 设置动画属性 # 注意:字节类型 # pos---位置动画---QPoint # size---大小动画---QSize # geometry----位置+大小动画----QRect # windowOpacity---窗口的透明度(0.0是透明的 1.0是不透明)---好像只适合顶层窗口 animation.setPropertyName(property_name) # animation.setStartValue(QPoint(0, 0)) # 设置开始位置---按钮的左上角位置 # animation.setEndValue(QPoint(300, 300)) # 设置结束位置 # animation.setStartValue(QSize(0, 0)) # 设置开始大小 # animation.setEndValue(QSize(300, 300)) # 设置结束大小 # animation.setStartValue(QRect(0, 0,100,100)) # 设置开始位置和大小 # animation.setEndValue(QRect(100,100,300, 300)) # 设置结束位置和大小 # 参数1 0.0到1.0 0.0表示开始点,1.0表示结束点 # 在动画的中间插入透明度0.2 animation.setStartValue(0.2) # 设置开始不透明 animation.setKeyValueAt(0.2, 0.4) # 在动画的某时间点插入一个值 animation.setKeyValueAt(0.4, 0.6) animation.setKeyValueAt(1, 1) # 在动画的结束点是不透明的 # 0透明, 1不透明 # animation.setEndValue(1) # 设置结束透明度 animation.setEndValue(TRANSPARENT) # 设置结束透明度 animation.setDirection(3000) # 设置动画单次时长---单位毫秒 animation.setEasingCurve(QEasingCurve.InQuad) # 设置动画的节奏 animation.start() # 动画开始---非阻塞
class AnimationShadowEffect(QGraphicsDropShadowEffect): def __init__(self, color, *args, **kwargs): super(AnimationShadowEffect, self).__init__(*args, **kwargs) self.setColor(color) self.setOffset(0, 0) self.setBlurRadius(0) self._radius = 0 self.animation = QPropertyAnimation(self) self.animation.setTargetObject(self) self.animation.setDuration(2000) # 一次循环时间 self.animation.setLoopCount(-1) # 永久循环 self.animation.setPropertyName(b'radius') # 插入值 self.animation.setKeyValueAt(0, 1) self.animation.setKeyValueAt(0.5, 30) self.animation.setKeyValueAt(1, 1) def start(self): self.animation.start() def stop(self, r=0): # 停止动画并修改半径值 self.animation.stop() self.radius = r @pyqtProperty(int) def radius(self): return self._radius @radius.setter def radius(self, r): self._radius = r self.setBlurRadius(r)
class Demo(QWidget): def __init__(self): super(Demo, self).__init__() self.resize(600, 600) self.btn = QPushButton('Bigger', self) self.btn.setObjectName('btn') self.btn.resize(100, 100) self.animation = QPropertyAnimation(self) # 指定动画作用的对象 self.animation.setTargetObject(self.btn) # b'size' 改变大小 b'pos' 改变位置 self.animation.setPropertyName(b'pos') # 设置动画持续时长 self.animation.setDuration(1000) # 设置位置关键帧 self.animation.setKeyValueAt(0, self.btn.pos() + QPoint(0, 0)) self.animation.setKeyValueAt(0.2, self.btn.pos() + QPoint(0, 15)) self.animation.setKeyValueAt(0.4, self.btn.pos() + QPoint(0, 0)) self.animation.setKeyValueAt(0.6, self.btn.pos() + QPoint(0, -15)) self.animation.setKeyValueAt(0.8, self.btn.pos() + QPoint(0, 0)) # self.animation.setKeyValueAt(1, self.btn.pos() + QPoint(0, 0)) # 设置动画循环次数 self.animation.setLoopCount(3) QMetaObject.connectSlotsByName(self) @pyqtSlot() def on_btn_clicked(self): # 启动动画 self.animation.start()
def moveSlider(self): animation = QPropertyAnimation(self) animation.setTargetObject(self.line_label) animation.setPropertyName(b"geometry") animation.setStartValue(self.line_label.geometry()) geo = self.sender().geometry() animation.setEndValue(QRect(geo.x(), 76, geo.width(), 4)) animation.setDuration(200) animation.start()
def splash_exit_init(pane, pane1): animation = QPropertyAnimation(pane) animation.setTargetObject(pane) animation.setPropertyName(b"pos") animation.setEndValue(QPoint(0, pane1.width())) animation.setStartValue(QPoint(0, 0)) animation.setEasingCurve(QEasingCurve.InBounce) animation.setDuration(500) animation.start(QAbstractAnimation.DeleteWhenStopped)
def move_animation(self, car, x1, y1, x2, y2, cost=1): animation = QPropertyAnimation(self, propertyName=b'pos') animation.setParent(self) animation.setTargetObject(car) animation.setDuration(cost * 1000) animation.setStartValue(QPoint(x1, y1)) animation.setEndValue(QPoint(x2, y2)) # animation.start() return animation
def splash_open_init(pane): animation = QPropertyAnimation(pane) animation.setTargetObject(pane) animation.setPropertyName(b"pos") animation.setStartValue(pane.pos()) animation.setEndValue(QPoint(0, 0)) animation.setEasingCurve(QEasingCurve.OutBounce) animation.setDuration(500) animation.start(QAbstractAnimation.DeleteWhenStopped)
class SwitchPrivate(QObject): def __init__(self, q, parent=None, isOn=False): self.isOn = isOn QObject.__init__(self, parent=parent) self.mPointer = q if self.isOn: self.mPosition = 1.0 else: self.mPosition = 0.0 self.mGradient = QLinearGradient() self.mGradient.setSpread(QGradient.PadSpread) self.animation = QPropertyAnimation(self) self.animation.setTargetObject(self) self.animation.setPropertyName(b'position') self.animation.setStartValue(0.0) self.animation.setEndValue(1.0) self.animation.setDuration(200) self.animation.setEasingCurve(QEasingCurve.InOutExpo) self.animation.finished.connect(self.mPointer.update) @pyqtProperty(float) def position(self): return self.mPosition @position.setter def position(self, value): self.mPosition = value self.mPointer.update() def draw(self, painter): r = self.mPointer.rect() margin = r.height() / 10 painter.setPen(Qt.NoPen) self.background_color = QColor(118, 118, 118) painter.setBrush(self.background_color) painter.drawRoundedRect(r, r.height() / 2, r.height() / 2) self.mGradient = QColor(35, 35, 35) painter.setBrush(self.mGradient) x = r.height() / 2.0 + self.mPosition * (r.width() - r.height()) painter.drawEllipse(QPointF(x, r.height() / 2), r.height() / 2 - margin, r.height() / 2 - margin) @pyqtSlot(bool, name='animate') def animate(self, checked): self.animation.setDirection(QPropertyAnimation.Forward if checked else QPropertyAnimation.Backward) self.animation.start()
def move(self, car, px, py): animation = QPropertyAnimation(self, b'pos') animation.setParent(self) animation.setDuration(2000) animation.setTargetObject(car) animation.setStartValue(QPoint(100, 100)) animation.setEndValue(QPoint(100, 400)) animation.setLoopCount(1) # self.animation.finished.connect(self.animationFinished) animation.start()
class PushButtonFont(QPushButton): LoadingText = "\uf110" def __init__(self, *args, **kwargs): super(PushButtonFont, self).__init__(*args, **kwargs) self.fontSize = self.font().pointSize() * 2 self._rotateAnimationStarted = False self._rotateAnimation = QPropertyAnimation(self) self._rotateAnimation.setTargetObject(self) self._rotateAnimation.setStartValue(1) self._rotateAnimation.setEndValue(12) self._rotateAnimation.setDuration(1000) self._rotateAnimation.setLoopCount(-1) # 无限循环 self._rotateAnimation.valueChanged.connect(self.update) self.clicked.connect(self._onClick) def paintEvent(self, _): option = QStyleOptionButton() self.initStyleOption(option) painter = QStylePainter(self) if self._rotateAnimationStarted: option.text = "" painter.drawControl(QStyle.CE_PushButton, option) if not self._rotateAnimationStarted: return painter.save() font = self.font() font.setPointSize(self.fontSize) font.setFamily("FontAwesome") painter.setFont(font) # 变换坐标为正中间 painter.translate(self.rect().center()) # 旋转90度 painter.rotate(self._rotateAnimation.currentValue() * 30) fm = self.fontMetrics() # 在变换坐标后的正中间画文字 w = fm.width(self.LoadingText) h = fm.height() painter.drawText( QRectF(0 - w * 2, 0 - h, w * 2 * 2, h * 2), Qt.AlignCenter, self.LoadingText) painter.restore() def _onClick(self): if self._rotateAnimationStarted: self._rotateAnimationStarted = False self._rotateAnimation.stop() return self._rotateAnimationStarted = True self._rotateAnimation.start() def update(self, _=None): super(PushButtonFont, self).update()
def show_error_animation(self): animation = QPropertyAnimation(self) animation.setTargetObject(self.login_widget) animation.setPropertyName(b"pos") animation.setKeyValueAt(0, self.login_widget.pos()) animation.setKeyValueAt(0.2, self.login_widget.pos() - QPoint(15, 0)) animation.setKeyValueAt(0.5, self.login_widget.pos()) animation.setKeyValueAt(0.7, self.login_widget.pos() - QPoint(-15, 0)) animation.setKeyValueAt(1, self.login_widget.pos()) animation.setDuration(200) animation.setLoopCount(5) animation.start(QAbstractAnimation.DeleteWhenStopped)
def createScene(): # Root entity rootEntity = QEntity() # Material material = QPhongMaterial(rootEntity) # Torus torusEntity = QEntity(rootEntity) # Qt3DExtras.QTorusMesh * torusMesh = QTorusMesh() torusMesh.setRadius(5) torusMesh.setMinorRadius(1) torusMesh.setRings(100) torusMesh.setSlices(20) # Qt3DCore.QTransform * torusTransform = QTransform() torusTransform.setScale3D(QVector3D(1.5, 1, 0.5)) torusTransform.setRotation( QQuaternion.fromAxisAndAngle(QVector3D(1, 0, 0), 45.0)) torusEntity.addComponent(torusMesh) torusEntity.addComponent(torusTransform) torusEntity.addComponent(material) # Sphere sphereEntity = QEntity(rootEntity) sphereMesh = QSphereMesh() sphereMesh.setRadius(3) # Qt3DCore.QTransform * sphereTransform = QTransform() # OrbitTransformController * controller = OrbitTransformController(sphereTransform) controller.setTarget(sphereTransform) controller.setRadius(20.0) # QPropertyAnimation * sphereRotateTransformAnimation = QPropertyAnimation(sphereTransform) sphereRotateTransformAnimation.setTargetObject(controller) sphereRotateTransformAnimation.setPropertyName(b"angle") sphereRotateTransformAnimation.setStartValue(0) sphereRotateTransformAnimation.setEndValue(360) sphereRotateTransformAnimation.setDuration(10000) sphereRotateTransformAnimation.setLoopCount(-1) sphereRotateTransformAnimation.start() sphereEntity.addComponent(sphereMesh) sphereEntity.addComponent(sphereTransform) sphereEntity.addComponent(material) return rootEntity
def set_shadow_animation(self, start_val=5, end_val=20, duration=300, activate=True): if getattr(self, "shadow_animation", None): # print("已存在animation") pass else: shadow_animation = QPropertyAnimation(self) shadow_animation.setTargetObject(self.shadow_effect) shadow_animation.setPropertyName(b"blurRadius") shadow_animation.setStartValue(start_val) shadow_animation.setEndValue(end_val) shadow_animation.setDuration(duration) self.shadow_animation = shadow_animation if not activate: self.shadow_animation.setDuration(1)
def __setAnimation(self, animation: QPropertyAnimation, songInfoCard, endX): """ 设置动画 """ animation.setEasingCurve(QEasingCurve.OutQuart) animation.setTargetObject(songInfoCard) animation.setDuration(500) # 设置起始值 animation.setStartValue( QRect(songInfoCard.x(), songInfoCard.y(), songInfoCard.width(), songInfoCard.height())) # 设置结束值 animation.setEndValue( QRect(endX, songInfoCard.y(), songInfoCard.width(), songInfoCard.height()))
def show_hide_menu(self, checked): animation_group = QSequentialAnimationGroup(self) for idx, target in enumerate(self.animation_target): animation = QPropertyAnimation() animation.setTargetObject(target) animation.setPropertyName(b"pos") animation.setEndValue(self.pushButton.pos()) animation.setStartValue(self.animation_target_pos[idx]) animation.setDuration(200) animation.setEasingCurve(QEasingCurve.InOutBounce) animation_group.addAnimation(animation) animation_group.setDirection(not checked) animation_group.start(QAbstractAnimation.DeleteWhenStopped)
def animations(self, widget, starx, stary, endx, endy, time): # 创建动画对象,并且设置目标、属性 animation = QPropertyAnimation(self) animation.setTargetObject(widget) animation.setPropertyName(b"pos") # 设置属性值:开始 插值 结束 animation.setStartValue(QPoint(starx, stary)) animation.setEndValue(QPoint(endx, endy)) # 动画时长 animation.setDuration(time) # 启动动画 animation.start()
def fade(self): #动画实现 animation=QPropertyAnimation(self) animation.setTargetObject(self) animation.setPropertyName(b"pos") animation.setStartValue(QPoint(self.pos().x(),self.pos().y())) animation.setEndValue(QPoint(self.pos().x(),self.pos().y()+self.geometry().height())) animation.setDuration(550) animation.setEasingCurve(QEasingCurve.OutBounce) animation.start() #准备后事 self.timer.start() self.bool_hidden=True #设置优先显示 self.setWindowFlags(Qt.FramelessWindowHint | Qt.Tool) self.show()
def appear(self,int_x,int_y): #动画实现 animation=QPropertyAnimation(self) animation.setTargetObject(self) animation.setPropertyName(b"pos") animation.setStartValue(QPoint(int_x+95,int_y+8)) animation.setEndValue(QPoint(int_x+95,int_y-self.geometry().height()+8)) animation.setDuration(550) animation.setEasingCurve(QEasingCurve.OutBounce) animation.start() #准备结束处理 self.timer.start() self.bool_hidden=False #设置优先显示 self.setWindowFlags(Qt.FramelessWindowHint | Qt.Tool) self.show()
def load_animation(window: object, property_name: bytes = b'windowOpacity') -> None: animation = QPropertyAnimation() animation.setTargetObject(window) # 设置动画目标对象 # 设置动画属性 # 注意:字节类型 # pos---位置动画---QPoint # size---大小动画---QSize # geometry----位置+大小动画----QRect # windowOpacity---窗口的透明度(0.0是透明的 1.0是不透明)---好像只适合顶层窗口 animation.setPropertyName(property_name) animation.setEndValue(TRANSPARENT) # 设置结束透明度 animation.setEasingCurve(QEasingCurve.InQuad) # 设置动画的节奏 animation.start() # 动画开始---非阻塞
class ParentWin(QWidget): def __init__(self, parent=None, *args, **kwargs) -> None: super().__init__(parent, *args, **kwargs) self.setStyleSheet("QWidget{background-color: yellow}") self.resize(500, 500) self.move(200, 200) self.vbox = QVBoxLayout() self.btn1 = QPushButton("切换窗口") self.btn1.setObjectName('btn1') self.vbox.addWidget(self.btn1) self.setLayout(self.vbox) self.childwin = None QMetaObject.connectSlotsByName(self) @pyqtSlot() def on_btn1_clicked(self): print('切换窗口') self.childwin = ChildWin(self) # todo 设置窗口动画 self.animation = QPropertyAnimation(self) # 指定动画作用的对象 self.animation.setTargetObject(self.childwin) # b'size' 改变大小 b'pos' 改变位置 self.animation.setPropertyName(b'pos') # 设置动画持续时长 self.animation.setDuration(1000) # 设置位置关键帧 init_pos = self.childwin.pos() self.animation.setKeyValueAt(0, init_pos + QPoint(0, 0)) self.animation.setKeyValueAt(0.2, init_pos + QPoint(-200, -200)) self.animation.setKeyValueAt(0.4, init_pos + QPoint(-300, -300)) self.animation.setKeyValueAt(0.6, init_pos + QPoint(-400, -400)) self.animation.setKeyValueAt(0.8, init_pos + QPoint(-450, -450)) self.animation.setKeyValueAt(1, init_pos + QPoint(-500, -500)) # 设置动画速率曲线 缓动效果 self.animation.setEasingCurve(QEasingCurve.OutBounce) # 设置动画循环次数 # self.animation.setLoopCount(3) self.childwin.show() self.animation.start(QAbstractAnimation.DeleteWhenStopped)
class Demo(QWidget): def __init__(self): super(Demo, self).__init__() self.resize(600, 600) self.btn = QPushButton('Bigger', self) self.btn.resize(100, 100) self.animation = QPropertyAnimation(self) # 1 # 指定动画作用的对象 self.animation.setTargetObject(self.btn) # b'size' 改变大小 b'pos' 改变位置 self.animation.setPropertyName(b'size') self.animation.setDuration(6000) # 2 self.animation.setStartValue(QSize(100, 100)) # 3 self.animation.setEndValue(QSize(600, 600)) # 4 self.animation.start() # 5
class ChildWin(QWidget): def __init__(self, parent=None, *args, **kwargs) -> None: super().__init__(parent, *args, **kwargs) self.setStyleSheet("QWidget{background-color: green}") self.setAttribute(Qt.WA_StyledBackground, True) self.resize(500, 500) # 子窗口出现的位置 是相对于父窗口而言的 self.move(500, 500) self.vbox = QVBoxLayout() self.btn1 = QPushButton("提交") self.btn1.setObjectName('btn1') self.vbox.addWidget(self.btn1) self.setLayout(self.vbox) QMetaObject.connectSlotsByName(self) @pyqtSlot() def on_btn1_clicked(self): print(222) # todo 设置窗口动画 self.animation = QPropertyAnimation(self) # 指定动画作用的对象 self.animation.setTargetObject(self) # b'size' 改变大小 b'pos' 改变位置 self.animation.setPropertyName(b'pos') # 设置动画持续时长 self.animation.setDuration(1000) # 设置位置关键帧 init_pos = self.pos() self.animation.setKeyValueAt(0, init_pos + QPoint(0, 0)) self.animation.setKeyValueAt(0.2, init_pos + QPoint(-200, -200)) self.animation.setKeyValueAt(0.4, init_pos + QPoint(-300, -300)) self.animation.setKeyValueAt(0.6, init_pos + QPoint(-400, -400)) self.animation.setKeyValueAt(0.8, init_pos + QPoint(-450, -450)) self.animation.setKeyValueAt(1, init_pos + QPoint(-500, -500)) # 动画倒放 # self.animation.setDirection(QAbstractAnimation.Backward) # 设置动画速率曲线 缓动效果 self.animation.setEasingCurve(QEasingCurve.OutBounce) # 设置动画循环次数 # self.animation.setLoopCount(3) self.animation.start(QAbstractAnimation.DeleteWhenStopped)
def menu(self): """ 展示动画效果 :return: """ animation_group = QSequentialAnimationGroup(self.widget) for idx, target in enumerate(self.animation_targets): animation = QPropertyAnimation() animation.setTargetObject(target) animation.setPropertyName(b"pos") animation.setStartValue(self.menu_btn.pos()) animation.setEndValue(self.animation_targets_pos[idx]) animation.setDuration(self.duration) animation.setEasingCurve(QEasingCurve.InOutBounce) animation_group.addAnimation(animation) animation_group.setDirection(self.checked) animation_group.start(QAbstractAnimation.DeleteWhenStopped)
def table_toggle(self, table_idx): dt = self.datatables[table_idx] def resize_layout(): dt.setMaximumHeight(0) if self.expand[table_idx] == True: animation = QPropertyAnimation(self) animation.setPropertyName(QByteArray().append('size')) animation.setTargetObject(dt) animation.setDuration(250) ogWidth = dt.width() animation.setStartValue(QSize(ogWidth, 310)) animation.setEndValue(QSize(ogWidth, 0)) animation.finished.connect(resize_layout) animation.start() self.labels[table_idx].setText('+') self.a.updateGeometry() self.a.setMinimumHeight(self.a.minimumHeight() - 320) else: animation = QPropertyAnimation(self) animation.setPropertyName(QByteArray().append('size')) animation.setTargetObject(dt) animation.setDuration(250) dt.setMaximumHeight(310) ogWidth = dt.width() animation.setStartValue(QSize(ogWidth, 0)) animation.setEndValue(QSize(ogWidth, 310)) animation.start() self.labels[table_idx].setText('-') self.a.updateGeometry() self.a.setMinimumHeight(self.a.minimumHeight() + 320) self.expand[table_idx] = not self.expand[table_idx]
def setup_yd(self): if self.biaotipos == 1: self.biaotipos = 2 self.kuang.hide() self.edit2.hide() self.pushButton_18.hide() self.edit.hide() self.edit22.show() self.yuan2.show() self.pushButton_19.show() self.edit_suiji_size.show() self.yuan3.show() self.edit_suiji_num.show() animation = QPropertyAnimation(self) animation.setTargetObject(self.biaoti_one) animation.setPropertyName(b"pos") animation.setStartValue(QPoint(375, 75)) animation.setEndValue((QPoint(615, 75))) animation.setDuration(300) animation.start()
class RotatingTrefoilKnot(TrefoilKnot): def __init__(self, parent=None): super(RotatingTrefoilKnot, self).__init__(parent) self.m_thetaAnimation = QPropertyAnimation() self.m_thetaAnimation.setDuration(2000) self.m_thetaAnimation.setStartValue(0.0) self.m_thetaAnimation.setEndValue(360.0) self.m_thetaAnimation.setLoopCount(-1) self.m_thetaAnimation.setTargetObject(self) self.m_thetaAnimation.setPropertyName(b'phi') self.m_thetaAnimation.start() self.m_phiAnimation = QPropertyAnimation() self.m_phiAnimation.setDuration(2000) self.m_phiAnimation.setStartValue(0.0) self.m_phiAnimation.setEndValue(360.0) self.m_phiAnimation.setLoopCount(-1) self.m_phiAnimation.setTargetObject(self) self.m_phiAnimation.setPropertyName(b'theta') self.m_phiAnimation.start()
def initUi(self): self.getSystemSettings() self.setWindowTitle('我的第一个Qt程序') self.resize(500, 300) # 把label放到父类里 self就是父类 即主窗口 LoginWindow # label = QLabel() # label.setParent(self) label = QLabel(self) label.setText("社会我杰哥,人狠话不多") label.move(100, 100) self.le = QLineEdit(self) self.le.setText(self.settings.value("username")) # 透明效果 animation = QPropertyAnimation(self) animation.setTargetObject(self) animation.setPropertyName(b"windowOpacity") animation.setStartValue(1) animation.setKeyValueAt(0.5, 0) animation.setEndValue(1) animation.setLoopCount(2) animation.setDuration(2000) animation.start(QAbstractAnimation.DeleteWhenStopped)
def push_message(self, text, type='Info'): self.setText(f' {text} ') self.setObjectName(type) self.setScaledContents(True) ds_effect = QGraphicsDropShadowEffect() ds_effect.setOffset(5, 5) ds_effect.setColor(Qt.gray) ds_effect.setBlurRadius(10) self.setGraphicsEffect(ds_effect) self.show() animation = QPropertyAnimation(self.parent()) animation.setTargetObject(self) animation.setPropertyName(b'pos') animation.setDuration(500) if self.parent(): if not hasattr(self.parent(), 'off_y'): setattr(self.parent(), 'off_y', 0) if not hasattr(self.parent(), 'number'): setattr(self.parent(), 'number', 0) off_y = self.parent().off_y p_width = self.parent().width() start = QPoint(p_width, self._margin + off_y) end = QPoint(p_width - self.width() - self._margin, self._margin + off_y) timer = QTimer(self) timer.timeout.connect( lambda: self._close(timer, animation, end, start)) timer.start(self.ttl * 1000) self._show(animation, start, end) self.parent( ).off_y = self.parent().off_y + self.height() + self._margin self.parent().number += 1
from PyQt5.QtCore import QPropertyAnimation, QEasingCurve animation = QPropertyAnimation() animation.setTargetObject() animation.setStartValue(0) animation.setEndValue(1000) animation.setDuration(1000) animation.setEasingCurve(QEasingCurve.InOutQuad) animation.start()
class BlueApp: def __init__(self, argv): self.app = QApplication(argv) self.mainWindow = QtWidgets.QMainWindow() self.mainWindow.closeEvent = self.onClose self.ui = blueMainUi.Ui_MainWindow() self.ui.setupUi(self.mainWindow) #settings and statistics self.defaultSettings = dict(image_detect=True, text_detect=True, game_type=0, pipeRank=0, goal = 10, startDate = time.time(), avata = "res/icon.png", name = "窜天猴") self.defaultStat = dict(stat = [ [0, 0, 0, 0] for i in range(7)], achivement = 0, lastWater = 0, lastFertilize = 0, cleanHours = 0, cleanMinutes = 0) self.achivementsList = ["大淫魔", "从头开始", "欲火渐盛", "钢筋铁骨", "渐入佳境","心无杂念"] self.achivementsStd = [0, 24, 24 * 3, 24 * 7, 24 * 31, 27 * 365] self.loadSettings() self.validateSettings() self.loadStatistics() #setup the visibles self.setupUi2() self.setupWidget1() self.setupWidget2() self.setupWidget3() self.setupWidget4() self.refreshStatistics() #setup porn_detector self.devMode = False self.timeToExit = False self.pornDectector = porn_detector_final.PornDetector() self.pornDetected = False self.detectThread = threading.Thread(target = self.detectPorn) self.detectThread.start() self.alarm = False #first alarm, then take action #setup timer self.cleanMinute = 0 self.MinuteTimer = QTimer() self.MinuteTimer.setInterval(1000 * 60) self.MinuteTimer.timeout.connect(self.addCleanMinute) self.MinuteTimer.start() #lauch self.mainWindow.show() self.connections() def addCleanMinute(self): self.stat["cleanMinutes"] += 1 if self.stat["cleanMinutes"] == 60: self.self.stat["cleanMinutes"] = 0 self.stat["cleanHours"] += 1 self.saveStatistics() self.refreshStatistics() self.checkLevel() def call_zqz(self): if self.settings["game_type"] == 0: os.system("python2 easy_maze/PyMaze.py") else : os.system("python2 esay_game/play.py") QtWidgets.QMessageBox.information(None, "bluer", "你有10s的时间关掉黄黄的东西。") time.sleep(10) def detectPorn(self): while(True): if "PORN_DETECTED" == self.pornDectector.porn_detector(self.settings["image_detect"], self.settings["text_detect"], self.devMode): if self.alarm: self.call_zqz() self.stat["cleanHours"] -= 24 if self.stat["cleanHours"] < 0: self.stat["cleanHours"] = 0 l = self.stat["stat"][time.localtime(time.time())[6]] h = time.localtime(time.time())[3] if h >= 0 and h < 6: l[0] = 1 elif h >= 6 and h < 12: l[1] = 1 elif h >= 12 and h < 18: l[2] = 1; else: l[3] = 1; else: self.alarm = True else: self.alarm = True self.saveStatistics() self.refreshStatistics() time.sleep(10) def onClose(self, event): self.mainWindow.hide() event.ignore() def onTrayClicked(self, event): if event == QSystemTrayIcon.Trigger or event == QSystemTrayIcon.DoubleClick: self.mainWindow.show() def saveSettings(self, event): QtWidgets.QMessageBox.Question = QIcon("res/logo-tray.png") if self.settings["goal"] != self.ui.spin_goal.value(): ret = QtWidgets.QMessageBox.question(self.mainWindow, "Blue", "确定要将目标改为" + str(self.ui.spin_goal.value()) + "天吗?\n" "此操作会重置当前任务的进度。") if ret != QtWidgets.QMessageBox.No: self.settings["goal"] = self.ui.spin_goal.value() self.saveStatistics() self.refreshStatistics() QtWidgets.QMessageBox.information(None, "Blue", "新目标设置为" + str(self.settings["goal"]) + "天") else: QtWidgets.QMessageBox.information(None, "Blue", "目标没有被重置") try: sfile = open(PATH_TO_SETTINGS, "w") json.dump(self.settings, sfile) sfile.close() except Exception: return QtWidgets.QMessageBox.information(None, "Blue", "设置已保存:D") self.refreshStatistics() def checkLevel(self): for i in range(5, -1, -1): if self.stat["cleanHours"] >= self.achivementsStd[i] and self.stat["achivement"] < i: QtWidgets.QMessageBox.information(None, "Blue", "等级提升为Lv. " + str(i) + " :" + self.achivementsList[i]) self.stat["achivement"] = i self.saveStatistics() break def saveStatistics(self): json.dump(self.stat, open(PATH_TO_STATISTICS, "w")) def refreshStatistics(self): days = time.localtime(time.time()) delta = self.settings["goal"] - self.stat["cleanHours"] if delta == 0: QtWidgets.QMessageBox.information(None, "Blue", "目标达成!!!\n请设置新的目标!!!") self.slideClicked3(None) self.ui.lb_days.setText(str(delta)) self.ui.lb_goal.setText(str(self.settings["goal"])) self.ui.lb_achv.setText(self.achivementsList[self.stat["achivement"]]) self.ui.lb_lv.setText("Lv. " + str(self.stat["achivement"])) self.ui.lb_growth.setText(str(self.stat["cleanHours"] // 24)) #setup the water and ferilization if days[7] == time.localtime(self.stat["lastWater"])[7]: self.ui.lb_jiaoshui.setPixmap(QPixmap("res/ack.png")) self.watered = True else: self.watered = False if days[7] == time.localtime(self.stat["lastFertilize"])[7]: self.ui.lb_shifei.setPixmap(QPixmap("res/ack.png")) self.fertilized = True else: self.fertilized = False #setup the calendar pixmapA = QPixmap("res/lu.png") pixmapB = QPixmap("res/blue.png") h = days[3] if h >= 0 and h < 6: r = 0 elif h >= 6 and h < 12: r = 1 elif h >= 12 and h < 18: r = 2 else: r = 3 for i in range(days[6]): for j in range(4): if self.stat["stat"][i][j] == 0: self.statLabels[i][j].setPixmap(pixmapA) else: self.statLabels[i][j].setPixmap(pixmapB) day = days[6] for j in range(r): if self.stat["stat"][day][j] == 0: self.statLabels[day][j].setPixmap(pixmapA) else: self.statLabels[day][j].setPixmap(pixmapB) #setup the wall for i in range(6): self.achivIcons[i].setPixmap(QPixmap("res/" + str(i) * 2)) for i in range(self.stat["achivement"] + 1): self.achivIcons[i].setPixmap(QPixmap("res/" + str(i))) def loadSettings(self): try: sfile = open(PATH_TO_SETTINGS, "r") self.settings = json.load(sfile) sfile.close() except: self.settings = self.defaultSettings self.saveSettings(None) def validateSettings(self): for keys in self.defaultSettings: try: self.settings[keys] except: self.settings[keys] = self.defaultSettings[keys] def loadStatistics(self): try: sfile = open(PATH_TO_STATISTICS, "r") self.stat = json.load(sfile) except: self.stat = self.defaultStat for keys in self.defaultStat: try: self.stat[keys] except: self.stat[keys] = self.defaultStat[keys] self.saveStatistics() def refreshInfo(self): #setup avata pixmap = QPixmap() pixmap.load("res/avata_mask") pixmap.scaled(115, 115) self.ui.lb_avata.setMask(pixmap.mask()) pixmap.load(self.settings["avata"]) self.ui.lb_avata.setPixmap(pixmap) # self.ui.lb_avata2.setMask(pixmap.mask()) # pixmap.load(self.settings["avata"]) # self.ui.lb_avata2.setPixmap(pixmap) #setup the name self.ui.lb_welcomname.setText(self.settings["name"]) self.ui.lb_nick.setText(self.settings["name"]) def appExit(self, event): if self.devMode == False: QtWidgets.QMessageBox.information(None, "bluer", "开发者模式开启") self.devMode = True else: QtWidgets.QMessageBox.information(None, "bluer", "开发者模式关闭") self.devMode = False def avataEdit(self, event): openDlg = QtWidgets.QFontDialog() openDlg.open() def setupUi2(self): #setup event handling self.sideButtons = [self.ui.lb1, self.ui.lb2, self.ui.lb3, self.ui.lb4] self.ui.lb_exit.mousePressEvent = self.appExit self.setupAnimes() self.setupSideButtons() self.refreshInfo() #setup tray self.icon = QIcon("res/logo-tray.png") self.trayIcon = QSystemTrayIcon() self.trayIcon.setIcon(self.icon) self.trayIcon.activated.connect(self.onTrayClicked) self.trayIcon.show() #setup the info edit self.ui.lb_avata.mousePressEvent = self.avataEdit def setupAnimes(self): self.shiftAnime1 = QPropertyAnimation() self.shiftAnime1.setTargetObject(self.ui.widget1) self.shiftAnime1.setPropertyName("geometry".encode()) self.shiftAnime1.setDuration(400) self.shiftAnime1.setStartValue(QRect(177, 29, 0, 571)) self.shiftAnime1.setEndValue(QRect(177, 29, 623, 571)) self.shiftAnime2 = QPropertyAnimation() self.shiftAnime2.setTargetObject(self.ui.widget2) self.shiftAnime2.setPropertyName("geometry".encode()) self.shiftAnime2.setDuration(400) self.shiftAnime2.setStartValue(QRect(800, 29, 0, 571)) self.shiftAnime2.setEndValue(QRect(177, 29, 623, 571)) self.shiftAnime3 = QPropertyAnimation() self.shiftAnime3.setTargetObject(self.ui.widget3) self.shiftAnime3.setPropertyName("geometry".encode()) self.shiftAnime3.setDuration(400) self.shiftAnime3.setStartValue(QRect(800, 29, 623, 571)) self.shiftAnime3.setEndValue(QRect(177, 29, 623, 571)) self.shiftAnime4 = QPropertyAnimation() self.shiftAnime4.setTargetObject(self.ui.widget4) self.shiftAnime4.setPropertyName("geometry".encode()) self.shiftAnime4.setDuration(400) self.shiftAnime4.setStartValue(QRect(800, 29, 623, 571)) self.shiftAnime4.setEndValue(QRect(177, 29, 623, 571)) self.selectedWidget = self.ui.widget1 def setSlideMid(self, bt): if self.selectedSideButton != bt: bt.setStyleSheet(slide_bt_mid) def setSlideUp(self, bt): if self.selectedSideButton != bt: bt.setStyleSheet(slide_bt_up) def setSlideDown(self, bt): self.selectedSideButton.setStyleSheet(slide_bt_up) self.selectedSideButton = bt bt.setStyleSheet(slide_bt_down) def slideEnter1(self, event): self.setSlideMid(self.ui.lb1) def slideEnter2(self, event): self.setSlideMid(self.ui.lb2) def slideEnter3(self, event): self.setSlideMid(self.ui.lb3) def slideEnter4(self, event): self.setSlideMid(self.ui.lb4) def slideLeave1(self, event): self.setSlideUp(self.ui.lb1) def slideLeave2(self, event): self.setSlideUp(self.ui.lb2) def slideLeave3(self, event): self.setSlideUp(self.ui.lb3) def slideLeave4(self, event): self.setSlideUp(self.ui.lb4) def slideBack(self, event): self.setSlideDown(self.ui.lb1) self.ui.widget1.raise_() self.shiftAnime1.start() self.selectedWidget = self.ui.widget1 def slideClicked1(self, event): self.setSlideDown(self.ui.lb1) if self.selectedWidget != self.ui.widget1: self.ui.widget1.raise_() self.shiftAnime1.start() self.selectedWidget = self.ui.widget1 def slideClicked2(self, event): self.setSlideDown(self.ui.lb2) if self.selectedWidget != self.ui.widget2: self.ui.widget2.raise_() self.shiftAnime2.start() self.selectedWidget = self.ui.widget2 def slideClicked3(self, event): self.setSlideDown(self.ui.lb3) if self.selectedWidget != self.ui.widget3: self.ui.widget3.raise_() self.shiftAnime3.start() self.selectedWidget = self.ui.widget3 def jiaoshuiCheck(self, event): pixmap = QPixmap() pixmap.load("res/ack.png") self.ui.lb_jiaoshui.setPixmap(pixmap) self.stat["lastWater"] = time.time() self.saveStatistics() def shifeiCheck(self, event): pixmap = QPixmap() pixmap.load("res/ack.png") self.ui.lb_shifei.setPixmap(pixmap) self.stat["lastFertilize"] = time.time() self.saveStatistics() def slideClicked4(self, event): self.setSlideDown(self.ui.lb4) if self.selectedWidget != self.ui.widget4: self.ui.widget4.raise_() self.shiftAnime4.start() self.selectedWidget = self.ui.widget4 def setupWidget1(self): #setup the tree movie = QMovie() movie.setFileName("res/tree.gif") self.ui.lb_tree.setMovie(movie) self.ui.lb_tree_big.setMovie(movie) movie.start() #setup the statistics self.ui.gridLayout.setHorizontalSpacing(60) self.ui.gridLayout.setVerticalSpacing(10) self.ui.gridLayout.setGeometry(QRect(0, 51, 291, 224)) self.ui.gridLayout.setAlignment(QtCore.Qt.AlignCenter) self.statLabels = [] for i in range(7): self.statLabels.append([]) for j in range(4): self.statLabels[i].append(QLabel()) self.statLabels[i][j].setScaledContents(True) self.statLabels[i][j].setAutoFillBackground(False) self.statLabels[i][j].setAlignment(QtCore.Qt.AlignCenter) self.ui.gridLayout.addWidget(self.statLabels[i][j], i, j, 1, 1) def setupWidget2(self): self.ui.lb_jiaoshui.mousePressEvent = self.jiaoshuiCheck self.ui.lb_shifei.mousePressEvent = self.shifeiCheck def setupWidget3(self): self.ui.check_maze.mousePressEvent = self.mazeCliked self.ui.check_paper.mousePressEvent = self.paperCliked self.ui.check_pic.mousePressEvent = self.picCliked self.ui.check_text.mousePressEvent = self.textClicked self.ui.lb_save.mousePressEvent = self.saveSettings self.ui.spin_goal.setValue(self.settings["goal"]) if self.settings["game_type"] == 0: self.mazeCliked(None) else: self.paperCliked(None) self.picCliked(None) self.picCliked(None) self.textClicked(None) self.textClicked(None) def setupWidget4(self): self.achivIcons = [self.ui.lb_a0, self.ui.lb_a1, self.ui.lb_a2, self.ui.lb_a3, self.ui.lb_a4, self.ui.lb_a5] for i in range(6): self.achivIcons[i].setPixmap(QPixmap("res/" + str(i) * 2)) def mazeCliked(self, event): pixmap = QPixmap() pixmap.load("res/checked.png") self.ui.check_maze.setPixmap(pixmap) pixmap.load("res/unchecked.png") self.ui.check_paper.setPixmap(pixmap) self.settings["game_type"] = 0 def paperCliked(self, event): pixmap = QPixmap() pixmap.load("res/checked.png") self.ui.check_paper.setPixmap(pixmap) pixmap.load("res/unchecked.png") self.ui.check_maze.setPixmap(pixmap) self.settings["game_type"] = 1 def picCliked(self, event): pixmap = QPixmap() pixmap.load("res/checked.png") self.ui.check_pic.setPixmap(pixmap) pixmap.load("res/unchecked.png") self.ui.check_text.setPixmap(pixmap) self.settings["pic_detect"] = 1 self.settings["text_detect"] = 0 def textClicked(self, event): pixmap = QPixmap() pixmap.load("res/checked.png") self.ui.check_text.setPixmap(pixmap) pixmap.load("res/unchecked.png") self.ui.check_pic.setPixmap(pixmap) self.settings["pic_detect"] = 1 self.settings["text_detect"] = 1 def setupSideButtons(self): self.ui.lb1.enterEvent = self.slideEnter1 self.ui.lb1.leaveEvent = self.slideLeave1 self.ui.lb1.mousePressEvent = self.slideClicked1 self.ui.lb2.enterEvent = self.slideEnter2 self.ui.lb2.leaveEvent = self.slideLeave2 self.ui.lb2.mousePressEvent = self.slideClicked2 self.ui.lb3.enterEvent = self.slideEnter3 self.ui.lb3.leaveEvent = self.slideLeave3 self.ui.lb3.mousePressEvent = self.slideClicked3 self.ui.lb4.enterEvent = self.slideEnter4 self.ui.lb4.leaveEvent = self.slideLeave4 self.ui.lb4.mousePressEvent = self.slideClicked4 self.ui.lb4.enterEvent = self.slideEnter4 self.ui.lb4.leaveEvent = self.slideLeave4 self.ui.lb4.mousePressEvent = self.slideClicked4 self.ui.lb_back2.mousePressEvent = self.slideBack self.ui.lb_back3.mousePressEvent = self.slideBack self.ui.lb_back4.mousePressEvent = self.slideBack for lb in self.sideButtons: lb.setStyleSheet(slide_bt_up) self.selectedSideButton = self.ui.lb1 self.slideClicked1(None) def connections(self): pass
class Invite(QWidget): """ An invite is a small notification being displayed in the bottom right corner of the window. It fades in and out, and is used to invite an user to jump to a certain location. Some other uses might be added later. """ def __init__(self, plugin, parent=None): super(Invite, self).__init__(parent) self._plugin = plugin self._time = 0 self.setWindowFlags(Qt.FramelessWindowHint | Qt.Tool | Qt.WindowStaysOnTopHint) self.setAttribute(Qt.WA_ShowWithoutActivating) self.setAttribute(Qt.WA_TranslucentBackground) self._icon = QLabel() self._icon.setAutoFillBackground(False) self._icon.setAttribute(Qt.WA_TranslucentBackground) self._text = QLabel() self._text.setAlignment(Qt.AlignHCenter | Qt.AlignVCenter) self._layout = QHBoxLayout() self._layout.addWidget(self._text) self.setLayout(self._layout) # Fade in and out animation self._popup_opacity = 0.0 self._animation = QPropertyAnimation() self._animation.setTargetObject(self) self._animation.setPropertyName("popup_opacity") self._animation.finished.connect(self.hide) # Timer used to auto-close the window self._timer = QTimer() self._timer.timeout.connect(self.hide_animation) self._callback = None self._triggered = False @property def time(self): return self._time @time.setter def time(self, time): self._time = time @property def text(self): return self._text.text() @text.setter def text(self, text): self._text.setText(text) self.adjustSize() @property def icon(self): return self._icon.pixmap() @icon.setter def icon(self, pixmap): # Resize the given pixmap pixmap_height = self._text.sizeHint().height() self._icon.setPixmap( pixmap.scaled( pixmap_height, pixmap_height, Qt.KeepAspectRatio, Qt.SmoothTransformation, )) self._layout.insertWidget(0, self._icon) @property def callback(self): return self._callback @callback.setter def callback(self, callback): self._callback = callback @property def triggered(self): return self._triggered @triggered.setter def triggered(self, triggered): self._triggered = triggered def paintEvent(self, event): # noqa: N802 """We override the painting event to draw the invite ourselves.""" painter = QPainter(self) painter.setRenderHint(QPainter.Antialiasing) rect = QRect(self.rect()) # Draw the border painter.setBrush(QBrush(QColor(122, 122, 122))) painter.setPen(Qt.NoPen) painter.drawRect(rect) rect.setX(rect.x() + 1) rect.setY(rect.y() + 1) rect.setWidth(rect.width() - 1) rect.setHeight(rect.height() - 1) # Draw the background painter.setBrush(QBrush(QColor(255, 255, 225))) painter.setPen(Qt.NoPen) painter.drawRect(rect) def mouseReleaseEvent(self, event): # noqa: N802 """ This function is called when the user clicks the invite. It triggers the callback function is it has been specified, and hides the invite. """ if self._callback: self._callback() self._triggered = True self._popup_opacity = 0.0 self.hide() def show(self): """Shows the invite to user. It triggers a fade in effect.""" self._plugin.logger.debug("Showing invite %s" % self.text) self.setWindowOpacity(0.0) self._animation.setDuration(500) self._animation.setStartValue(0.0) self._animation.setEndValue(1.0) # Map the notification to the bottom right corner pos = QPoint(self.parent().width() - 25, self.parent().height() - 50) pos = self.parent().mapToGlobal(pos) self.setGeometry( pos.x() - self.width(), pos.y() - self.height(), self.width(), self.height(), ) super(Invite, self).show() self._animation.start() self._timer.start(3500) def hide(self): """Hides the invite only if it is fully transparent.""" if self._popup_opacity == 0.0: self._plugin.interface.widget.refresh() super(Invite, self).hide() def hide_animation(self): """Hides the invite. It triggers the fade out animation.""" self._timer.stop() self._animation.setDuration(500) self._animation.setStartValue(1.0) self._animation.setEndValue(0.0) self._animation.start() @pyqtProperty(float) def popup_opacity(self): return self._popup_opacity @popup_opacity.setter def popup_opacity(self, opacity): self._popup_opacity = opacity self.setWindowOpacity(opacity)