I'm trying to create two Qgraphicscene where I can drag an item from the left scene and drop it on the rigth scene. I succeed in making the drad and drop, but I don't understand how I can create an overlay of the svg item during the drag. What I would like to have is at least display the overlay when the mouse is on the rigth scene.
So far I have this code:
import sys
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
from PyQt5.QtSvg import QGraphicsSvgItem
class myQGraphicsScene(QGraphicsScene):
def __init__(self,parent=None):
super(myQGraphicsScene, self).__init__()
self.parent = parent
def dragEnterEvent(self, event):
event.accept()
def dragMoveEvent(self, event):
event.accept()
def dragLeaveEvent(self, event):
event.accept()
def dropEvent(self, event):
text = event.mimeData().text()
item = self.parent.getSelecedItemfromname(text)
br = item.boundingRect()
s = item.scale()
w = int(br.width() * s)/2
h = int(br.height() * s)/2
pos = event.scenePos()
item.setPos(pos - QPointF(w,h))
self.addItem(item)
event.accept()
class myQGraphicsScene2(QGraphicsScene):
def __init__(self, parent=None):
super(myQGraphicsScene2, self).__init__()
self.parent = parent
def dragEnterEvent(self, event):
event.setDropAction(Qt.MoveAction)
event.accept()
def startDrag(self, event):
item = self.itemAt(event.scenePos(), QTransform())
print(item)
if item is None:
return
# selected = self.model().data(item, Qt.DisplayRole)
name = self.parent.getSelecedNamefromitem(item)
mimeData = QMimeData()
mimeData.setText(name )
drag = QDrag(self)
drag.setMimeData(mimeData)
result = drag.exec(Qt.MoveAction)
if result: # == Qt.MoveAction:
pass
def mouseMoveEvent(self, event):
self.startDrag(event)
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setMouseTracking(True)
self.names = ['fjJ.svg','fjJ.svg','fjJ.svg']
self. items = []
shift = 200
for i, n in enumerate(self.names):
item = QGraphicsSvgItem(n)
# item.setFlag(QGraphicsItem.ItemIsMovable)
item.setFlag(not QGraphicsItem.ItemIsMovable)
# item.setFlag(QGraphicsItem.ItemIsSelectable)
item.setScale(0.25)
item.setPos(0, i * shift)
self.items.append(item)
self.scene = myQGraphicsScene2(self)
for i in self.items:
self.scene.addItem(i)
self.scene2 = myQGraphicsScene(self)
self.view = QGraphicsView()
self.view.setScene(self.scene)
self.view2 = QGraphicsView()
self.view2.setMouseTracking(True)
self.view2.setScene(self.scene2)
HBOX = QHBoxLayout()
HBOX.addWidget(self.view)
HBOX.addWidget(self.view2)
widget = QWidget()
widget.setLayout(HBOX)
self.setCentralWidget(widget)
self.setFixedSize(QSize(800,600))
def getSelecedItem(self):
item = -1
for k, i in enumerate(self.items):
if i.isSelected():
item = k
if not item == -1:
new_item = QGraphicsSvgItem(self.names[item])
new_item.setFlag(QGraphicsItem.ItemIsMovable)
new_item.setScale(0.25)
return new_item
else:
return None
def getSelecedNamefromitem(self,itemfrom):
item = -1
for k, i in enumerate(self.items):
if i == itemfrom:
item = k
if not item == -1:
return self.names[k]
else:
return None
def getSelecedItemfromname(self,name):
item = -1
for k, n in enumerate(self.names):
if n == name:
item = k
if not item == -1:
new_item = QGraphicsSvgItem(self.names[item])
new_item.setFlag(QGraphicsItem.ItemIsMovable)
new_item.setScale(0.25)
return new_item
else:
return None
def getSelecedName(self):
item = -1
for k, i in enumerate(self.items):
if i.isSelected():
item = k
if not item == -1:
return self.names[item]
else:
return None
if __name__ == '__main__':
app = QApplication(sys.argv)
w = MainWindow()
w.show()
app.exec()
Here the .svg https://svgshare.com/i/fjJ.svg
I found a solution myself. It is not a perfect one but it works. You can put other solutions if they are more optimized.
import sys
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
from PyQt5.QtSvg import QGraphicsSvgItem
class myQGraphicsScene(QGraphicsScene):
def __init__(self,parent=None):
super(myQGraphicsScene, self).__init__()
self.parent = parent
def dragEnterEvent(self, event):
print('dragEnterEvent')
event.accept()
def dragMoveEvent(self, event):
print('dragMoveEvent')
event.accept()
def dragLeaveEvent(self, event):
print('dragLeaveEvent')
event.accept()
def dropEvent(self, event):
text = event.mimeData().text()
item = self.parent.getSelecedItemfromname(text)
br = item.boundingRect()
s = item.scale()
w = int(br.width() * s)/2
h = int(br.height() * s)/2
pos = event.scenePos()
item.setPos(pos - QPointF(w,h))
self.addItem(item)
event.accept()
class myQGraphicsScene2(QGraphicsScene):
def __init__(self, parent=None):
super(myQGraphicsScene2, self).__init__()
self.parent = parent
def dragEnterEvent(self, event):
event.setDropAction(Qt.MoveAction)
event.accept()
def startDrag(self, event):
item = self.itemAt(event.scenePos(), QTransform())
print(item)
if item is None:
return
# # selected = self.model().data(item, Qt.DisplayRole)
name = self.parent.getSelecedNamefromitem(item)
# mimeData = QMimeData()
# mimeData.setText(name )
#
# drag = QDrag(self)
# drag.setMimeData(mimeData)
#
# result = drag.exec(Qt.MoveAction)
# if result: # == Qt.MoveAction:
# pass
pixmap = self.parent.getSelecedimagefromname(name)
drag = QDrag(self)
mimedata = QMimeData()
mimedata.setText(name)
mimedata.setImageData(pixmap.toImage())
drag.setMimeData(mimedata)
painter = QPainter(pixmap)
painter.drawPixmap(pixmap.rect(), pixmap)
painter.end()
drag.setPixmap(pixmap)
# drag.setHotSpot(QPoint(event.scenePos().x(),event.scenePos().y()))
drag.setHotSpot(QPoint((pixmap.size()/2).width(),(pixmap.size()/2).height()))
drag.exec_(Qt.CopyAction | Qt.MoveAction)
def mouseMoveEvent(self, event):
self.startDrag(event)
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setMouseTracking(True)
self.names = ['function.svg','multiply.svg','minus.svg']
self.items = []
shift = 200
for i, n in enumerate(self.names):
item = QGraphicsSvgItem(n)
# item.setFlag(QGraphicsItem.ItemIsMovable)
item.setFlag(not QGraphicsItem.ItemIsMovable)
# item.setFlag(QGraphicsItem.ItemIsSelectable)
item.setScale(0.25)
item.setPos(0, i * shift)
self.items.append(item)
self.scene = myQGraphicsScene2(self)
for i in self.items:
self.scene.addItem(i)
self.scene2 = myQGraphicsScene(self)
self.view = QGraphicsView()
self.view.setScene(self.scene)
self.view2 = QGraphicsView()
self.view2.setMouseTracking(True)
self.view2.setScene(self.scene2)
self.view2.setFixedSize(QSize(400,600))
self.view2.setSceneRect(0,0,400,600)
# self.view2.setTransformationAnchor(QGraphicsView.NoAnchor)
# self.view2.setResizeAnchor(QGraphicsView.NoAnchor)
HBOX = QHBoxLayout()
HBOX.addWidget(self.view)
HBOX.addWidget(self.view2)
widget = QWidget()
widget.setLayout(HBOX)
self.setCentralWidget(widget)
# self.setFixedSize(QSize(800,600))
def getSelecedItem(self):
item = -1
for k, i in enumerate(self.items):
if i.isSelected():
item = k
if not item == -1:
new_item = QGraphicsSvgItem(self.names[item])
new_item.setFlag(QGraphicsItem.ItemIsMovable)
new_item.setScale(0.25)
return new_item
else:
return None
def getSelecedNamefromitem(self,itemfrom):
item = -1
for k, i in enumerate(self.items):
if i == itemfrom:
item = k
if not item == -1:
return self.names[item]
else:
return None
def getSelecedItemfromname(self,name):
item = -1
for k, n in enumerate(self.names):
if n == name:
item = k
if not item == -1:
new_item = QGraphicsSvgItem(self.names[item])
new_item.setFlag(QGraphicsItem.ItemIsMovable)
new_item.setScale(0.25)
return new_item
else:
return None
def getSelecedimagefromname(self,name):
item = -1
for k, n in enumerate(self.names):
if n == name:
item = k
if not item == -1:
new_item = QIcon(self.names[item]).pixmap(self.items[item].boundingRect().size().toSize() * self.items[item].scale())
return new_item
else:
return None
def getSelecedName(self):
item = -1
for k, i in enumerate(self.items):
if i.isSelected():
item = k
if not item == -1:
return self.names[item]
else:
return None
if __name__ == '__main__':
app = QApplication(sys.argv)
w = MainWindow()
w.show()
app.exec()