如何通过鼠标单击删除 PlotItem 中的 QGraphicsItem
How to delete a QGraphicsItem in a PlotItem by mouse click on it
如果顶层模块是pg.GraphicsScene,它可以正常工作,当一个rect被添加到场景中时,它可以被itemAt()选择并从场景中移除。但是当顶层模块是一个 pg.GraphicsLayoutWidget 时,通过 addPlot 添加一个 PlotItem,然后将 rect 添加到 PlotItem,现在 itemAt() returns 一个 QGraphicsRectItem 似乎是一些背景的东西但是不指向添加的rect,如果进行删除,则先删除这个QGraphicsRectItem,然后才可以选择添加的rect,为什么QGraphicsRectItem在最上面的选择层的背景是什么?非常感谢任何帮助!
import sys
import pyqtgraph as pg
from PyQt5 import QtWidgets, QtGui
from PyQt5.QtWidgets import QGraphicsRectItem
pg.setConfigOption('background', 'k')
pg.setConfigOption('foreground', 'w')
rect1 = QGraphicsRectItem(120, 120, 60, 60)
rect1.setPen(pg.mkPen((51, 51, 153), width=2))
rect1.setBrush(pg.mkBrush(51, 51, 153, 50))
rect2 = QGraphicsRectItem(200, 200, 80, 80)
rect2.setPen(pg.mkPen((51, 51, 153), width=2))
rect2.setBrush(pg.mkBrush(51, 51, 153, 50))
rect1.setFlag(rect1.ItemIsFocusable)
rect1.setFlag(rect1.ItemIsSelectable)
rect2.setFlag(rect2.ItemIsFocusable)
rect2.setFlag(rect2.ItemIsSelectable)
rect1.setZValue(1000)
rect2.setZValue(1000)
class win(pg.GraphicsLayoutWidget):
def __init__(self):
super().__init__()
self.setWindowTitle('pyqtgraph GraphicsLayoutWidget')
self.plt1 = self.addPlot(title='pyqtgraph PlotItem')
self.plt1.setEnabled(False)
self.plt1.addItem(rect1)
self.plt1.addItem(rect2)
self.plt1.disableAutoRange()
def mousePressEvent(self, event):
#item = self.scene().itemAt(event.pos(), QtGui.QTransform())
item = self.itemAt(event.pos())
print(item)
#self.plt1.removeItem(item)
self.scene().removeItem(item)
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
w = win()
w.show()
sys.exit(app.exec_())
最后,你想删除矩形,但没有别的。
在您当前的实现中,您正在删除您单击的所有内容,并且您必须执行一些逻辑来检测 “这是我要删除的项目吗” ?
相反,您可以创建新的 Class RemovableRect
,这表明它可以从场景中移除 onMousePressEvent
。
对于具有相同行为的其他项目,您可以遵循相同的逻辑。
下面是使用这种可移动矩形的修改代码:
import sys
import pyqtgraph as pg
from PyQt5 import QtWidgets
from PyQt5.QtWidgets import QGraphicsRectItem
pg.setConfigOption('background', 'k')
pg.setConfigOption('foreground', 'w')
class RemovableRect(QGraphicsRectItem):
def mousePressEvent(self, event: 'QGraphicsSceneMouseEvent') -> None:
"""Remove me from the Scene"""
self.scene().removeItem(self)
rect1 = RemovableRect(120, 120, 60, 60)
rect1.setPen(pg.mkPen((51, 51, 153), width=2))
rect1.setBrush(pg.mkBrush(51, 51, 153, 50))
rect2 = RemovableRect(200, 200, 80, 80)
rect2.setPen(pg.mkPen((51, 51, 153), width=2))
rect2.setBrush(pg.mkBrush(51, 51, 153, 50))
rect1.setFlag(rect1.ItemIsFocusable)
rect1.setFlag(rect1.ItemIsSelectable)
rect2.setFlag(rect2.ItemIsFocusable)
rect2.setFlag(rect2.ItemIsSelectable)
class win(pg.GraphicsLayoutWidget):
def __init__(self):
super().__init__()
self.setWindowTitle('pyqtgraph GraphicsLayoutWidget')
self.plt1 = self.addPlot(title='pyqtgraph PlotItem')
self.plt1.addItem(rect1)
self.plt1.addItem(rect2)
self.plt1.disableAutoRange()
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
w = win()
w.show()
sys.exit(app.exec_())
我从您的代码中删除了几行,尤其是 self.plt1.setEnabled(False)
这会禁用事件传播到您的矩形。
如果顶层模块是pg.GraphicsScene,它可以正常工作,当一个rect被添加到场景中时,它可以被itemAt()选择并从场景中移除。但是当顶层模块是一个 pg.GraphicsLayoutWidget 时,通过 addPlot 添加一个 PlotItem,然后将 rect 添加到 PlotItem,现在 itemAt() returns 一个 QGraphicsRectItem 似乎是一些背景的东西但是不指向添加的rect,如果进行删除,则先删除这个QGraphicsRectItem,然后才可以选择添加的rect,为什么QGraphicsRectItem在最上面的选择层的背景是什么?非常感谢任何帮助!
import sys
import pyqtgraph as pg
from PyQt5 import QtWidgets, QtGui
from PyQt5.QtWidgets import QGraphicsRectItem
pg.setConfigOption('background', 'k')
pg.setConfigOption('foreground', 'w')
rect1 = QGraphicsRectItem(120, 120, 60, 60)
rect1.setPen(pg.mkPen((51, 51, 153), width=2))
rect1.setBrush(pg.mkBrush(51, 51, 153, 50))
rect2 = QGraphicsRectItem(200, 200, 80, 80)
rect2.setPen(pg.mkPen((51, 51, 153), width=2))
rect2.setBrush(pg.mkBrush(51, 51, 153, 50))
rect1.setFlag(rect1.ItemIsFocusable)
rect1.setFlag(rect1.ItemIsSelectable)
rect2.setFlag(rect2.ItemIsFocusable)
rect2.setFlag(rect2.ItemIsSelectable)
rect1.setZValue(1000)
rect2.setZValue(1000)
class win(pg.GraphicsLayoutWidget):
def __init__(self):
super().__init__()
self.setWindowTitle('pyqtgraph GraphicsLayoutWidget')
self.plt1 = self.addPlot(title='pyqtgraph PlotItem')
self.plt1.setEnabled(False)
self.plt1.addItem(rect1)
self.plt1.addItem(rect2)
self.plt1.disableAutoRange()
def mousePressEvent(self, event):
#item = self.scene().itemAt(event.pos(), QtGui.QTransform())
item = self.itemAt(event.pos())
print(item)
#self.plt1.removeItem(item)
self.scene().removeItem(item)
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
w = win()
w.show()
sys.exit(app.exec_())
最后,你想删除矩形,但没有别的。
在您当前的实现中,您正在删除您单击的所有内容,并且您必须执行一些逻辑来检测 “这是我要删除的项目吗” ?
相反,您可以创建新的 Class RemovableRect
,这表明它可以从场景中移除 onMousePressEvent
。
对于具有相同行为的其他项目,您可以遵循相同的逻辑。
下面是使用这种可移动矩形的修改代码:
import sys
import pyqtgraph as pg
from PyQt5 import QtWidgets
from PyQt5.QtWidgets import QGraphicsRectItem
pg.setConfigOption('background', 'k')
pg.setConfigOption('foreground', 'w')
class RemovableRect(QGraphicsRectItem):
def mousePressEvent(self, event: 'QGraphicsSceneMouseEvent') -> None:
"""Remove me from the Scene"""
self.scene().removeItem(self)
rect1 = RemovableRect(120, 120, 60, 60)
rect1.setPen(pg.mkPen((51, 51, 153), width=2))
rect1.setBrush(pg.mkBrush(51, 51, 153, 50))
rect2 = RemovableRect(200, 200, 80, 80)
rect2.setPen(pg.mkPen((51, 51, 153), width=2))
rect2.setBrush(pg.mkBrush(51, 51, 153, 50))
rect1.setFlag(rect1.ItemIsFocusable)
rect1.setFlag(rect1.ItemIsSelectable)
rect2.setFlag(rect2.ItemIsFocusable)
rect2.setFlag(rect2.ItemIsSelectable)
class win(pg.GraphicsLayoutWidget):
def __init__(self):
super().__init__()
self.setWindowTitle('pyqtgraph GraphicsLayoutWidget')
self.plt1 = self.addPlot(title='pyqtgraph PlotItem')
self.plt1.addItem(rect1)
self.plt1.addItem(rect2)
self.plt1.disableAutoRange()
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
w = win()
w.show()
sys.exit(app.exec_())
我从您的代码中删除了几行,尤其是 self.plt1.setEnabled(False)
这会禁用事件传播到您的矩形。