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
Qt Code:
  1. def exch(x, i, j):
  2. x[i], x[j] = x[j], x[i]
  3.  
  4.  
  5. def selection_sort(x):
  6. for i in range(len(x)):
  7. _min, index = x[i], i
  8. for j in range(i, len(x)):
  9. if _min > x[j]:
  10. _min, index = x[j], j
  11. exch(x, i, index)
To copy to clipboard, switch view to plain text mode 

view.py
Qt Code:
  1. import sys
  2. import random
  3. import logging
  4.  
  5. from PyQt4.QtCore import *
  6. from PyQt4.QtGui import *
  7.  
  8. import sort as _sort
  9.  
  10.  
  11. class SortableItem(QGraphicsObject):
  12.  
  13. move_finished = pyqtSignal()
  14.  
  15. def __init__(self, h, *args, **kwargs):
  16. super().__init__(*args, **kwargs)
  17. self.h = h
  18. self.brush = QColor(255, 0, 0)
  19.  
  20. def paint(self, p, *args):
  21. print(self.h)
  22. p.setBrush(self.brush)
  23. p.drawRect(self.boundingRect())
  24.  
  25. def __lt__(self, o):
  26. return self.h < o.h
  27.  
  28. def boundingRect(self):
  29. return QRectF(0, 0, 10, -self.h)
  30.  
  31. def pre_move_finished(self):
  32. self.brush = QColor(255, 0, 0)
  33. self.setZValue(0)
  34. self.move_finished.emit()
  35.  
  36. def move_to(self, x):
  37. self.anim = QPropertyAnimation(self, 'x')
  38. self.brush = QColor(0, 255, 0)
  39. self.setZValue(1)
  40. self.anim.finished.connect(self.pre_move_finished)
  41. self.anim.setDuration(1000)
  42. self.anim.setEndValue(x)
  43. self.anim.start()
  44.  
  45.  
  46. def exch(items, i, j):
  47. logging.debug('exch %d and %d' % (i, j))
  48. event = QEventLoop()
  49. items[j].move_finished.connect(event.quit)
  50. items[i].move_to(j * 10)
  51. items[j].move_to(i * 10)
  52. event.exec_()
  53. items[i], items[j] = items[j], items[i]
  54.  
  55.  
  56. def create_items(N):
  57. items = []
  58. for i in range(1, N + 1):
  59. item = SortableItem(i * 10)
  60. items.insert(0, item)
  61. return items
  62.  
  63.  
  64. def add_items(scene, items):
  65. for i, t in enumerate(items):
  66. scene.addItem(t)
  67. t.setX(i * 10) # t.move_to(i * 10) animation ok
  68.  
  69.  
  70. if __name__ == '__main__':
  71. logging.basicConfig(
  72. level=logging.DEBUG,
  73. format='[%(asctime)s] - %(levelname)s - %(message)s')
  74. setattr(_sort, 'exch', exch) # monkey patch
  75. app = QApplication(sys.argv)
  76.  
  77. mw = QMainWindow()
  78. scene = QGraphicsScene()
  79. view = QGraphicsView()
  80. view.setScene(scene)
  81.  
  82. mw.resize(400, 400)
  83. mw.setCentralWidget(view)
  84. mw.show()
  85.  
  86. items = create_items(25)
  87. random.shuffle(items)
  88.  
  89. add_items(scene, items)
  90. _sort.selection_sort(items)
  91.  
  92. sys.exit(app.exec_())
To copy to clipboard, switch view to plain text mode 

ps: sorry for my poor english