【问题标题】:Moving a circle randomly in PyQt5 on its own?自己在 PyQt5 中随机移动一个圆圈?
【发布时间】:2020-12-14 00:09:37
【问题描述】:

我正在尝试创建两个圆圈,它们在一个区域内随机移动并在它们碰撞时改变它们的颜色。

有很多创建圆圈并通过鼠标拖动来移动它们的例子,但我没有找到任何东西,对象必须自己移动。

这是我已经拥有的:

from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QApplication, QGraphicsView, QGraphicsScene, QGraphicsEllipseItem
import sys, random

class Circle (QGraphicsEllipseItem):
    def __init__(self, x, y, r, condition):
        super().__init__(0,0,r,r)
        self.setPos(x,y)
        self.condition = condition

    def setColor(self):
        if self.condition == "changable":
            self.setBrush(Qt.blue)
        elif self.condition == "notChangable":
            self.setBrush(Qt.black)

class GraphicView(QGraphicsView):
    def __init__(self):
        super().__init__()

        self.scene = QGraphicsScene()
        self.setScene(self.scene)
        self.setSceneRect(0, 0, 600, 600)

        self.circle1 = Circle(random.randint(0,600), random.randint(0,600), 20, "changable")
        self.circle2 = Circle(random.randint(0,600), random.randint(0,600), 20, "notChangable")
        self.circle1.setColor()
        self.circle2.setColor()
        self.scene.addItem(self.circle1)
        self.scene.addItem(self.circle2)

app = QApplication(sys.argv)

view = GraphicView()
view.show()
sys.exit(app.exec_())

如果“可变”-圆与“不可更改”-圆发生碰撞,则“可变”-圆应将其条件更新为“不可更改”。

那么,我怎样才能让这些圆圈在区域内随机移动,让它们改变状态呢?

【问题讨论】:

  • Circle.conditon 改变时是否要运行函数?
  • 如果两个圈子发生碰撞,他们应该更新他们的条件。运动方向不应受到碰撞的影响。他们应该继续他们的随机运动

标签: python pyqt5


【解决方案1】:

要创建一个随机但平滑的移动,你必须使用QVariantAnimation,要检查项目的碰撞,你必须使用collidingItems()方法,但你必须在每次项目的位置改变时都这样做,这可以在itemChange() 方法中完成:

from PyQt5.QtCore import Qt, QPointF, QTimer, QVariantAnimation
from PyQt5.QtWidgets import (
    QApplication,
    QGraphicsItem,
    QGraphicsView,
    QGraphicsScene,
    QGraphicsEllipseItem,
)
import sys, random


class Circle(QGraphicsEllipseItem):
    def __init__(self, x, y, r):
        super().__init__(0, 0, r, r)
        self.setFlag(QGraphicsItem.ItemSendsGeometryChanges)
        self.setPos(x, y)
        self.setBrush(Qt.black)

        self._animation = QVariantAnimation(duration=1000)
        self._animation.valueChanged.connect(self.setPos)
        self._animation.finished.connect(self.create_random_point)

    def create_random_point(self):
        pos = random.sample(range(0, 600), 2)
        self.move_to(*pos)

    def move_to(self, x, y):
        self._animation.setStartValue(self.pos())
        self._animation.setEndValue(QPointF(x, y))
        self._animation.start()

    def itemChange(self, change, value):
        if change == QGraphicsItem.ItemPositionHasChanged:
            self.setBrush(Qt.blue if self.collidingItems() else Qt.black)
        return super().itemChange(change, value)


class GraphicView(QGraphicsView):
    def __init__(self):
        super().__init__()

        scene = QGraphicsScene(self)
        self.setScene(scene)
        self.setSceneRect(0, 0, 600, 600)

        for _ in range(10):
            pos = random.sample(range(0, 600), 2)
            circle = Circle(*pos, 20)
            circle.create_random_point()
            self.scene().addItem(circle)


app = QApplication(sys.argv)

view = GraphicView()
view.show()
sys.exit(app.exec_())

【讨论】:

  • 您的回答对我帮助很大。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-06-29
  • 2020-09-06
  • 2015-12-10
  • 1970-01-01
相关资源
最近更新 更多