¿Por qué estoy experimentando lo que parece ser un retraso en la actualización de este QGraphicsItem móvil de PyQt5, y cómo puedo solucionarlo?
Cuando ejecuto este código en mi computadora, funciona bien en su mayor parte. Pero si hago clic y arrastro el círculo muy rápidamente, el lado que está “adelante” en términos de movimiento será ocultado por el color de fondo. Si arrastro muy rápido, obtengo imágenes residuales discretas y blancas del objeto (aunque el objeto es rojo). Supongo que el código que actualiza el lienzo tarda demasiado en llegar con el primero; Realmente no sé acerca de las imágenes residuales.
Es difícil de describir, así que recomiendo que mires este screencast del comportamiento.
El código está debajo. ¿Hay alguna forma de solucionar esto?
import sys
from PyQt5.QtWidgets import QApplication, QGraphicsView, QGraphicsScene
from PyQt5.QtWidgets import QGraphicsEllipseItem, QGraphicsRectItem, QGraphicsItem
from PyQt5.QtGui import QBrush, QPen
from PyQt5.QtCore import Qt
app = QApplication(sys.argv)
scene = QGraphicsScene(0,0,600,400)
rect = QGraphicsRectItem(50,20,200,50)
circle = QGraphicsEllipseItem(75,30,100,100)
brush = QBrush(Qt.red)
pen = QPen(Qt.black)
pen.setWidth(2)
circle.setBrush(brush)
circle.setPen(pen)
rect.setBrush(brush)
rect.setPen(pen)
scene.addItem(circle)
scene.addItem(rect)
scene.setBackgroundBrush(QBrush(Qt.cyan))
circle.setFlag(QGraphicsItem.ItemIsMovable)
rect.setFlag(QGraphicsItem.ItemIsMovable)
view = QGraphicsView(scene)
view.show()
app.exec_()
davy.ai
El problema con el código es que la escena gráfica no se actualiza lo suficientemente rápido cuando el círculo se arrastra rápidamente. Una forma de solucionar esto es llamar a
QCoreApplication.processEvents()
dentro del métodomouseMoveEvent
deQGraphicsEllipseItem
. Esto asegura que la cola de eventos se procese entre cada evento de movimiento del ratón, permitiendo que la escena se actualice con mayor frecuencia.Así es cómo puedes modificar el código para solucionar este problema:
Al crear una nueva subclase de
QGraphicsEllipseItem
y sobrescribir el métodomouseMoveEvent
, agregamos la llamada aQCoreApplication.processEvents()
después de la llamada al métodosuper()
. Esto asegura que la escena se actualice con mayor frecuencia cuando el círculo se arrastra rápidamente, evitando el problema de la ocultación y las imágenes residuales blancas.