PDA

View Full Version : [PyQt] QGraphicsObject and QPropertyAnimation do not work properly



445141126
20th February 2016, 15:00
1. I use QGraphicsObject and QPropertyAnimation to make item animation.
2. When i add QGraphicsObject item to scene, that animation work ok.
3. When i try to sort item, that animation didn't work well, it update pos x, but paint is not called, i have to resize(which force paint call), then item pos x on scene changed.
4. Why animation didn't woking.

sort.py


def exch(x, i, j):
x[i], x[j] = x[j], x[i]


def selection_sort(x):
for i in range(len(x)):
_min, index = x[i], i
for j in range(i, len(x)):
if _min > x[j]:
_min, index = x[j], j
exch(x, i, index)


view.py


import sys
import random
import logging

from PyQt4.QtCore import *
from PyQt4.QtGui import *

import sort as _sort


class SortableItem(QGraphicsObject):

move_finished = pyqtSignal()

def __init__(self, h, *args, **kwargs):
super().__init__(*args, **kwargs)
self.h = h
self.brush = QColor(255, 0, 0)

def paint(self, p, *args):
print(self.h)
p.setBrush(self.brush)
p.drawRect(self.boundingRect())

def __lt__(self, o):
return self.h < o.h

def boundingRect(self):
return QRectF(0, 0, 10, -self.h)

def pre_move_finished(self):
self.brush = QColor(255, 0, 0)
self.setZValue(0)
self.move_finished.emit()

def move_to(self, x):
self.anim = QPropertyAnimation(self, 'x')
self.brush = QColor(0, 255, 0)
self.setZValue(1)
self.anim.finished.connect(self.pre_move_finished)
self.anim.setDuration(1000)
self.anim.setEndValue(x)
self.anim.start()


def exch(items, i, j):
logging.debug('exch %d and %d' % (i, j))
event = QEventLoop()
items[j].move_finished.connect(event.quit)
items[i].move_to(j * 10)
items[j].move_to(i * 10)
event.exec_()
items[i], items[j] = items[j], items[i]


def create_items(N):
items = []
for i in range(1, N + 1):
item = SortableItem(i * 10)
items.insert(0, item)
return items


def add_items(scene, items):
for i, t in enumerate(items):
scene.addItem(t)
t.setX(i * 10) # t.move_to(i * 10) animation ok


if __name__ == '__main__':
logging.basicConfig(
level=logging.DEBUG,
format='[%(asctime)s] - %(levelname)s - %(message)s')
setattr(_sort, 'exch', exch) # monkey patch
app = QApplication(sys.argv)

mw = QMainWindow()
scene = QGraphicsScene()
view = QGraphicsView()
view.setScene(scene)

mw.resize(400, 400)
mw.setCentralWidget(view)
mw.show()

items = create_items(25)
random.shuffle(items)

add_items(scene, items)
_sort.selection_sort(items)

sys.exit(app.exec_())


ps: sorry for my poor english