pyqt5 QGraphicsView颜色动画问题(不兼容,运行不了动画)
2018-03-01 09:43 yongchin 阅读(1424) 评论(0) 编辑 收藏 举报初学动画。无敌踩坑,资料真的是太少了。。。。。本坑是一个大坑,只有解决方法,但实质原因仍不清楚
在一篇资料中了解到我们可以通过QGraphicsView来实现动画QPropertyAnimation
自己随意写了一个测试界面大致如下
#!/usr/bin/python3 # -*- coding: utf-8 -*- """ Author: semishigure Website: zetcode.com Last edited: 2018.03.01 """ from PyQt5.QtCore import * from PyQt5.QtGui import * from PyQt5.QtWidgets import * import cgitb import sys cgitb.enable(format='text') # 解决pyqt5异常只要进入事件循环,程序就崩溃,而没有任何提示 class Ball(QObject): def __init__(self): super().__init__() # self.pixmap_item = QGraphicsPixmapItem(QPixmap("ball.png")) self.pixmap_item = QGraphicsEllipseItem(5, 30, 20, 20) self._set_pos(QPointF(5, 30)) def _set_pos(self, pos): self.pixmap_item.setPos(pos) pos = pyqtProperty(QPointF, fset=_set_pos) class Myview(QGraphicsView): def __init__(self): super().__init__() self._set_color(QColor(105, 105, 105)) self.iniAnimation() def _set_color(self, col): self.palette = QPalette() # self.palette.setColor(self.backgroundRole(), col) self.palette.setBrush(self.backgroundRole(), col) self.setPalette(self.palette) def iniAnimation(self): self.anim2 = QPropertyAnimation(self, b'color') self.anim2.setDuration(1000) self.anim2.setStartValue(QColor(105, 105, 105)) self.anim2.setKeyValueAt(0.1, QColor(255, 255, 240)) self.anim2.setKeyValueAt(0.3, QColor(219, 225, 171)) self.anim2.setKeyValueAt(0.7, QColor(148, 214, 184)) self.anim2.setEndValue(QColor(86, 199, 170)) color = pyqtProperty(QColor, fset=_set_color) class Example(Myview): def __init__(self): super().__init__() self.initView() self.iniui() def initView(self): self.ball = Ball() self.anim = QPropertyAnimation(self.ball, b'pos') self.anim.setDuration(1000) self.anim.setStartValue(QPointF(5, 30)) self.anim.setKeyValueAt(0.3, QPointF(80, 30)) self.anim.setKeyValueAt(0.5, QPointF(200, 30)) self.anim.setKeyValueAt(0.8, QPointF(250, 250)) self.anim.setEndValue(QPointF(290, 30)) # self.anim.start() # self.linearGradient = QLinearGradient(100, 100, 200, 200) # self.linearGradient.setColorAt(0.2,QColor(255, 255, 240)) # self.linearGradient.setColorAt(0.6,QColor(255, 0, 0)) # self.linearGradient.setColorAt(1.0,QColor(255, 255, 0)) # self._set_color(self.linearGradient) self.scene = QGraphicsScene(self) self.scene.setSceneRect(0, 0, 300, 300) self.scene.addItem(self.ball.pixmap_item) self.setScene(self.scene) self.setWindowTitle("Ball animation") self.setRenderHint(QPainter.Antialiasing) self.setGeometry(300, 300, 500, 350) self.show() def iniui(self): self.btn = QPushButton("开始") self.btn2 = QPushButton("结束") self.maingrid = QGridLayout() self.setLayout(self.maingrid) self.maingrid.addWidget(self.btn, 0, 0) self.maingrid.addWidget(self.btn2, 1, 0) self.btn.clicked.connect(self.runAnim) def runAnim(self): self.anim.start() self.anim2.start() if __name__ == '__main__': app = QApplication(sys.argv) ex = Example() sys.exit(app.exec_())
主要是一个颜色渐变的动画和一个物体移动的动画,让我把这段代码拷贝到实际项目中时,意想不到的结果发生了
问题现象:
动画只有物体移动生效了,颜色变化没有生效
问题原因:
本质原因不明,经过自己研究调试发现是因为自己实际项目中用了qss,只要.setStyleSheet了后,就会与QGraphicsView的背景颜色动画产生冲突
解决方法
搞了大概一天,第二天来重整思绪。
自己回顾代码发现
self.scene = QGraphicsScene(self) self.scene.setSceneRect(0, 0, 300, 300) self.scene.addItem(self.ball.pixmap_item) self.setScene(self.scene)
物体移动是把对象添加到了场景中,而颜色变化,却是直接改变的QGraphicsView的颜色
于是我尝试着放弃改变QGraphicsView而去改变QGraphicsScene的颜色,就解决了!so,原本的这段代码:
class Myview(QGraphicsView): def __init__(self): super().__init__() self._set_color(QColor(105, 105, 105)) self.iniAnimation() def _set_color(self, col): self.palette = QPalette() # self.palette.setColor(self.backgroundRole(), col) self.palette.setBrush(self.backgroundRole(), col) self.setPalette(self.palette) def iniAnimation(self): self.anim2 = QPropertyAnimation(self, b'color') self.anim2.setDuration(1000) self.anim2.setStartValue(QColor(105, 105, 105)) self.anim2.setKeyValueAt(0.1, QColor(255, 255, 240)) self.anim2.setKeyValueAt(0.3, QColor(219, 225, 171)) self.anim2.setKeyValueAt(0.7, QColor(148, 214, 184)) self.anim2.setEndValue(QColor(86, 199, 170)) color = pyqtProperty(QColor, fset=_set_color)
应该改为(QGraphicsView改变颜色不生效,那么重写QGraphicsScene改变颜色即可):
class TcpBackgroudScene(QGraphicsScene): def __init__(self, widget): super(TcpBackgroudScene, self).__init__(widget) self.iniAnimation() def _set_color(self, col): self.setBackgroundBrush(col) def iniAnimation(self): """动画""" # 颜色动画 self.anim3 = QPropertyAnimation(self, b'color') self.anim3.setDuration(1000) self.anim3.setStartValue(QColor(105, 105, 105)) self.anim3.setKeyValueAt(0.1, QColor(255, 255, 240)) self.anim3.setKeyValueAt(0.3, QColor(219, 225, 171)) self.anim3.setKeyValueAt(0.7, QColor(148, 214, 184)) self.anim3.setEndValue(QColor(86, 199, 170)) color = pyqtProperty(QColor, fset=_set_color)
注意这里改变QGraphicsScene的背景方法为 self.setBackgroundBrush(col)
最后再self.anim3.start()即可启动动画了!并且能与stylesheet兼容!