pyqt5 官方例子笔记 animate-1
来源:互联网 发布:剑灵龙族捏脸数据 编辑:程序博客网 时间:2024/05/22 08:07
animatedtiles.py
总结:这个小程序,主要涉及到控件的布局(boundingRect Method),形状的绘制(shape函数重载来自定义控件的形状),控件图片的加载(资源文件的引入pyrcc,Button对象将资源对象最为初始化参数),整个界面的大体布局(scene view graphicsitem 各种qt对象之间的依赖关系),动态绘图过程(QState状态机)
注释即是笔记,留作下次的备忘
from PyQt5.QtCore import (pyqtProperty, pyqtSignal, QEasingCurve, QObject, QParallelAnimationGroup, QPointF, QPropertyAnimation, qrand, QRectF, QState, QStateMachine, Qt, QTimer)from PyQt5.QtGui import (QBrush, QLinearGradient, QPainter, QPainterPath, QPixmap)from PyQt5.QtWidgets import (QApplication, QGraphicsItem, QGraphicsPixmapItem, QGraphicsRectItem, QGraphicsScene, QGraphicsView, QGraphicsWidget, QStyle)import animatedtiles_rc# PyQt doesn't support deriving from more than one wrapped class so we use# composition and delegate the property.class Pixmap(QObject): def __init__(self, pix): #父类初始化 super(Pixmap, self).__init__() self.pixmap_item = QGraphicsPixmapItem(pix) self.pixmap_item.setCacheMode(QGraphicsItem.DeviceCoordinateCache) def _set_pos(self, pos): self.pixmap_item.setPos(pos) # 类似于C# 字段调用方法 python里面property函数 pos = pyqtProperty(QPointF, fset=_set_pos)class Button(QGraphicsWidget): pressed = pyqtSignal() def __init__(self, pixmap, parent_arg=None): #QGraphicsWidget :_init__ (self, QGraphicsItem parent = None, Qt.WindowFlags wFlags = 0) #The QGraphicsWidget class is the base class for all widget items in a QGraphicsScene super(Button, self).__init__(parent_arg) self._pix = pixmap #设置悬停时间是否接受,系统一直跟随鼠标检测是否悬停在一个控件上 self.setAcceptHoverEvents(True) #设置缓存的模式 加速图形的渲染 这个选项是在绘图层起作用 适用于平移运动的图形,不适用于旋转伸缩变换 self.setCacheMode(QGraphicsItem.DeviceCoordinateCache) #限制绘图的边界 所有的绘图都必须在这个区域的内部,这个区域是矩形的 def boundingRect(self): #将控件的坐标原点设置成了控件的中心 return QRectF(-65, -65, 130, 130) #图形的边界必须是矩形,图形的形状可以是任意图形 def shape(self): #QPainterPath为绘图操作提供了一个容器,为图形形状的构造和重用提供了一种方式 # 初始化方法 #addEllipse (self, QRectF rect) #addEllipse (self, float x, float y, float w, float h) #addEllipse (self, QPointF center, float rx, float ry) path = QPainterPath() path.addEllipse(self.boundingRect()) return path def paint(self, painter, option, widget): #检查是否处于按下的状态 down = option.state & QStyle.State_Sunken r = self.boundingRect() grad = QLinearGradient(r.topLeft(), r.bottomRight()) #这段代码是检查鼠标是否在控件上如果是那么修改亮度渐变的梯度 if option.state & QStyle.State_MouseOver: color_0 = Qt.white else: color_0 = Qt.lightGray color_1 = Qt.darkGray if down: color_0, color_1 = color_1, color_0 grad.setColorAt(0, color_0) grad.setColorAt(1, color_1) painter.setPen(Qt.darkGray) painter.setBrush(grad) painter.drawEllipse(r) color_0 = Qt.darkGray color_1 = Qt.lightGray if down: color_0, color_1 = color_1, color_0 grad.setColorAt(0, color_0) grad.setColorAt(1, color_1) painter.setPen(Qt.NoPen) painter.setBrush(grad) if down: #painter.translate(2,2) 是将原点设置为(2,2) painter.translate(2, 2) # r.adjust对原来的矩形的大小进行调整 获得新的矩形大小 painter.drawEllipse(r.adjusted(5, 5, -5, -5)) painter.drawPixmap(-self._pix.width() / 2, -self._pix.height() / 2, self._pix) def mousePressEvent(self, ev): #出发鼠标按下的事件 self.pressed.emit() self.update() def mouseReleaseEvent(self, ev): self.update()class View(QGraphicsView): def resizeEvent(self, event): #调用父类的事件 super(View, self).resizeEvent(event) #尽量填充该矩形同时保持图片应有的比例 self.fitInView(self.sceneRect(), Qt.KeepAspectRatio) def mouseMoveEvent(self,event): self.setWindowTitle(f'{event.x()},{event.y()}') self.update()if __name__ == '__main__': import sys import math app = QApplication(sys.argv) kineticPix = QPixmap(':/images/kinetic.png') bgPix = QPixmap(':/images/Time-For-Lunch-2.jpg') #param x,y,width,height scene = QGraphicsScene(-350, -350, 700, 700) items = [] for i in range(64): item = Pixmap(kineticPix) item.pixmap_item.setOffset(-kineticPix.width() / 2, -kineticPix.height() / 2) #setZvalue是设置图层的叠加顺序,数字大的叠加在数字小的上方 item.pixmap_item.setZValue(i) items.append(item) scene.addItem(item.pixmap_item) # Buttons. #The QGraphicsRectItem class provides a rectangle item that you can add to a QGraphicsScene buttonParent = QGraphicsRectItem() #buttonparent作为Buttons的父类的初始化参数 ellipseButton = Button(QPixmap(':/images/ellipse.png'), buttonParent) figure8Button = Button(QPixmap(':/images/figure8.png'), buttonParent) randomButton = Button(QPixmap(':/images/random.png'), buttonParent) tiledButton = Button(QPixmap(':/images/tile.png'), buttonParent) centeredButton = Button(QPixmap(':/images/centered.png'), buttonParent) ellipseButton.setPos(-100, -100) figure8Button.setPos(100, -100) randomButton.setPos(0, 0) tiledButton.setPos(-100, 100) centeredButton.setPos(100, 100) scene.addItem(buttonParent) buttonParent.setScale(0.75) buttonParent.setPos(200, 200) buttonParent.setZValue(65) # States. rootState = QState() ellipseState = QState(rootState) figure8State = QState(rootState) randomState = QState(rootState) tiledState = QState(rootState) centeredState = QState(rootState) # Values. for i, item in enumerate(items): # Ellipse. ellipseState.assignProperty(item, 'pos', QPointF(math.cos((i / 63.0) * 6.28) * 250, math.sin((i / 63.0) * 6.28) * 250)) # Figure 8. figure8State.assignProperty(item, 'pos', QPointF(math.sin((i / 63.0) * 6.28) * 250, math.sin(((i * 2)/63.0) * 6.28) * 250)) # Random. #qrand()返回0-randMax之间的数值 qrand()%500 将随机数限制在0-499 randomState.assignProperty(item, 'pos', QPointF(-250 + qrand() % 500, -250 + qrand() % 500)) # Tiled. tiledState.assignProperty(item, 'pos', QPointF(((i % 8) - 4) * kineticPix.width() + kineticPix.width() / 2, ((i // 8) - 4) * kineticPix.height() + kineticPix.height() / 2)) # Centered. centeredState.assignProperty(item, 'pos', QPointF()) # Ui. view = View(scene) view.setWindowTitle("Animated Tiles") view.setViewportUpdateMode(QGraphicsView.BoundingRectViewportUpdate) view.setBackgroundBrush(QBrush(bgPix)) view.setCacheMode(QGraphicsView.CacheBackground) view.setRenderHints(QPainter.Antialiasing | QPainter.SmoothPixmapTransform) view.show() #状态机 states = QStateMachine() states.addState(rootState) states.setInitialState(rootState) rootState.setInitialState(centeredState) group = QParallelAnimationGroup() for i, item in enumerate(items): anim = QPropertyAnimation(item, b'pos') anim.setDuration(750 + i * 25*1) #设置用于动画的擦除效果 每张图片的运动轨迹 # doc http://doc.qt.io/qt-4.8/qeasingcurve.html anim.setEasingCurve(QEasingCurve.InOutBack) group.addAnimation(anim) trans = rootState.addTransition(ellipseButton.pressed, ellipseState) trans.addAnimation(group) trans = rootState.addTransition(figure8Button.pressed, figure8State) trans.addAnimation(group) trans = rootState.addTransition(randomButton.pressed, randomState) trans.addAnimation(group) trans = rootState.addTransition(tiledButton.pressed, tiledState) trans.addAnimation(group) trans = rootState.addTransition(centeredButton.pressed, centeredState) trans.addAnimation(group) timer = QTimer() timer.start(125) timer.setSingleShot(True) trans = rootState.addTransition(timer.timeout, ellipseState) trans.addAnimation(group) states.start() sys.exit(app.exec_())
阅读全文
0 0
- pyqt5 官方例子笔记 animate-1
- PYQT5学习笔记1
- pyqt5 信号槽机制的官方文档笔记
- PyQt5学习笔记(1)
- PyQt5笔记—例子(二) 设置程序图标
- PyQt5笔记 例子(三)—显示悬停信息
- PyQt5笔记
- PyQt5笔记
- PyQt5笔记
- PyQt5笔记
- jquery animate例子实践
- 《PyQt5 快速编程》例子注释
- [tolua++]官方例子1 tarray
- PyQt5 学习笔记
- PyQt5学习笔记1_第一个QML+PyQt程序
- Eric6与pyqt5学习笔记 5【实战1 简易计算器】
- Eric6与pyqt5学习笔记 1【安装和配置】
- jquery中animate动画的小例子
- qml实现简单的时间选择控件
- 程序员必备的600个英语词汇
- ArcGIS Pro开发
- java数据结构排序之快速排序
- 今天你用 === 了吗?
- pyqt5 官方例子笔记 animate-1
- HDU 6059 Kanade's trio 字典树 统计 容斥
- 数据结构之二叉树的一些基本操作
- 设计模式之代理模式
- android 数据库 shared preferences文件查看
- 文章标题
- 浅谈浏览器劫持问题
- 初步探讨数组和指针的区别与联系
- 最小生成树(Kruskal算法和Prim算法)