我正在尝试构建一组 GraphicItems,我可以在布局中移动它们并切换它们的位置。我遇到的问题是子项目中没有触发拖动事件。 我一直在搜索并建议创建一个覆盖事件的自定义场景的其他一些主题。
我在子方法中设置了 setAcceptDrops 并设置了这个标志:QGraphicsItem.ItemIsMovable | QGraphicsItem.ItemIsSelectable | QGraphicsItem.ItemSendsGeometryChanges 没有运气。
在下面找到我的例子:
from PySide6 import QtCore
from PySide6.QtWidgets import *
class CustomRect(QGraphicsRectItem):
def __init__(self, parent=None):
super(CustomRect, self).__init__(parent)
self.setRect(0.0, 0.0, 80.0, 80.0)
class MyProxy(QGraphicsProxyWidget):
def dragEnterEvent(self, e):
e.acceptProposedAction()
def dropEvent(self, e):
# pass drop event to child widget
return self.widget().dropEvent(e)
def dragMoveEvent(self, e):
e.acceptProposedAction()
class RectGroup(QGraphicsItemGroup):
def __init__(self, text, parent=None):
super(RectGroup, self).__init__(parent)
self.setHandlesChildEvents(False)
self.addToGroup(CustomRect())
label = QLabel(text)
self.proxy = MyProxy()
self.proxy.setHandlesChildEvents(False)
self.proxy.setAcceptDrops(True)
self.proxy.setWidget(label)
self.proxy.setPos(30, 30)
self.addToGroup(self.proxy)
def dropEvent(self, e):
e.accept()
def dragEnterEvent(self, e):
e.accept()
def dragMoveEvent(self, e):
e.accept()
class Item(QGraphicsLayoutItem):
def __init__(self, graphics_group, parent=None):
super(Item, self).__init__(parent)
self.gg = graphics_group
def dropEvent(self, e):
e.accept()
def dragEnterEvent(self, e):
e.accept()
def dragMoveEvent(self, e):
e.accept()
def sizeHint(self, *args, **kwargs):
boundingrec = self.gg.boundingRect()
r = QtCore.QSizeF()
r.setHeight(boundingrec.height())
r.setWidth(boundingrec.width())
return r
def setGeometry(self, x):
self.gg.setPos(x.topLeft())
class Container(QGraphicsWidget):
def __init__(self, parent=None):
super(Container, self).__init__(parent)
self.setAcceptDrops(True)
self.layout = QGraphicsGridLayout()
self.setLayout(self.layout)
def add_item(self, item, row, col):
self.layout.addItem(item, row, col)
class MyScene(QGraphicsScene):
def dragEnterEvent(self, e):
e.acceptProposedAction()
def dropEvent(self, e):
# find item at these coordinates
item = self.itemAt(e.scenePos())
if item.setAcceptDrops == True:
# pass on event to item at the coordinates
try:
item.dropEvent(e)
except RuntimeError:
pass # This will supress a Runtime Error generated when dropping into a widget with no MyProxy
def dragMoveEvent(self, e):
e.acceptProposedAction()
class MainWindow(QMainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.central_widget = QWidget(self)
central_layout = QHBoxLayout()
self.central_widget.setLayout(central_layout)
self.setCentralWidget(self.central_widget)
self.resize(500, 500)
view = QGraphicsView()
scene = MyScene()
view.setScene(scene)
container = Container()
scene.addItem(container)
for i in range(3):
rg = RectGroup(f"foo_{i}", container)
rg.setFlags(
QGraphicsItem.ItemIsMovable | QGraphicsItem.ItemIsSelectable | QGraphicsItem.ItemSendsGeometryChanges)
rg.setAcceptDrops(True)
f = Item(rg)
container.add_item(f, i, 0)
central_layout.addWidget(view)
app = QApplication([])
main = MainWindow()
main.show()
app.exec()