【问题标题】:Make graphics item move around another item instead of passing through使图形项目在另一个项目周围移动而不是通过
【发布时间】:2021-12-28 01:26:39
【问题描述】:

我有一个带有可移动 QGraphicsEllipseitem 圆圈的图形场景。我试图让我拖动的那个在另一个圆圈周围移动,而不是让它们重叠也就是碰撞。到目前为止,我能够阻止碰撞,但它不能顺利移动,它会卡到一个角落。我不知道如何解决它。

from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
import math


class Circleitem(QGraphicsEllipseItem):

    def __init__(self, size, brush):
        super().__init__()
        radius = size / -2
        self.setRect(radius, radius, size, size)
        self.setBrush(brush)
        self.setFlag(self.ItemIsMovable)
        self.setFlag(self.ItemIsSelectable)

    def paint(self, painter, option, a):
        option.state = QStyle.State_None
        return super(Circleitem, self).paint(painter,option)
    
    def mouseMoveEvent(self, event):
        super().mouseMoveEvent(event)
        self.scene().views()[0].parent().movearound()



class MainWindow(QMainWindow):

    def __init__(self):
        super().__init__()
        self.gscene = QGraphicsScene(0, 0, 1000, 1000)
        gview = QGraphicsView(self.gscene)
        self.setCentralWidget(gview)
        self.circle1 = Circleitem (123, brush=QColor(255,255,0))
        self.circle2 =Circleitem(80, brush=QColor(0,255,0))
        self.gscene.addItem(self.circle1)
        self.gscene.addItem(self.circle2)
        self.circle1.setPos(500, 500)
        self.circle2.setPos(300, 300)
        self.show()

    def movearound(self):
        if self.gscene.selectedItems()[0] == self.circle1:
            moveditem = self.circle1
            stillitem = self.circle2
        else:
            moveditem = self.circle2
            stillitem = self.circle1
        
        if len(self.gscene.collidingItems(moveditem)) != 0:
            xdist = moveditem.x() - stillitem.x()
            ydist = moveditem.y() - stillitem.y()
            totaldist = moveditem.rect().width()/2 + stillitem.rect().width()/2
            totaldist *= math.sqrt(1 + pow(math.pi, 2)/10)/2
            
            if ( abs(xdist) < totaldist or abs(ydist) < totaldist ):
                if xdist > 0:
                    x = stillitem.x() + totaldist
                else:
                    x = stillitem.x() - totaldist
                if ydist > 0:
                    y = stillitem.y() + totaldist
                else:
                    y = stillitem.y() - totaldist

                moveditem.setPos(x, y)
        


app = QApplication([])
win = MainWindow()
app.exec()

【问题讨论】:

    标签: python pyqt5 qgraphicsscene


    【解决方案1】:

    将逻辑保留在Circleitem.mouseMoveEvent中并使用QLineF查找距离和新位置更简单。

    class Circleitem(QGraphicsEllipseItem):
    
        def __init__(self, size, brush):
            super().__init__()
            radius = size / -2
            self.setRect(radius, radius, size, size)
            self.setBrush(brush)
            self.setFlag(self.ItemIsMovable)
            self.setFlag(self.ItemIsSelectable)
    
        def paint(self, painter, option, a):
            option.state = QStyle.State_None
            return super(Circleitem, self).paint(painter,option)
    
        def mouseMoveEvent(self, event):
            super().mouseMoveEvent(event)
            colliding = self.collidingItems()
            if colliding:
                item = colliding[0]                  # Add offset if points are equal so length > 0
                line = QLineF(item.pos(), self.pos() + QPoint(self.pos() == item.pos(), 0))
                min_distance = (self.rect().width() + item.rect().width()) / 2
                if line.length() < min_distance:
                    line.setLength(min_distance)
                    self.setPos(line.p2())
    

    【讨论】:

    • 谢谢!当移动的物品与 2 个或更多的圆圈发生碰撞时,您能否也说明如何做?
    • @drivereye 这可能更复杂,具体取决于您的意思。你应该问另一个问题(但先试一试)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-07-26
    • 1970-01-01
    • 2021-10-04
    • 2019-02-19
    • 1970-01-01
    • 2013-08-17
    • 2020-08-16
    相关资源
    最近更新 更多