我正在创建一个支持复制粘贴和拖动操作的应用。复制粘贴时,粘贴的项目没有用户定义的属性。
我在复制时有一个Qgraphicsitem,我们可以获取自己的属性,但不能获取用户定义的属性。
例如:
我正在将类型设置为图形项目。复制并粘贴该类型时,该类型未设置为粘贴的项目。
from PyQt5.QtCore import (QByteArray, QDataStream, QIODevice, QMimeData, QPointF, QPoint, Qt, QRect, QTimer, QLineF,
QEvent, QRectF)
from PyQt5.QtGui import QColor, QDrag, QPainter, QPixmap, QFont, QFontMetrics, QBrush, QLinearGradient, QIcon, QPen, \
QPainterPath, QTransform, QCursor, QMouseEvent, QClipboard
from PyQt5.QtWidgets import QApplication, QGraphicsTextItem, QGraphicsItemGroup, QSizePolicy, QScrollArea, QPushButton, \
QLineEdit, QMainWindow, QInputDialog, QGraphicsPathItem, QDialog, QVBoxLayout, QGraphicsItem, QStatusBar, QTextEdit, \
QAction, QMenu, qApp, QSplitter, QButtonGroup, QToolButton, QFrame, QHBoxLayout, QGraphicsView, QGraphicsItem, \
QGraphicsPixmapItem, QLabel, QGraphicsScene, QWidget
import importlib
import random
import SketchBook as sketchBook
import Block as blocks
custom_mimeType = "application/x-qgraphicsitems"
def item_to_ds(it, ds):
if not isinstance(it, QGraphicsItem):
return
ds.writeQString(it.__class__.__module__)
ds.writeQString(it.__class__.__name__)
ds.writeInt(it.flags())
ds << it.pos()
ds.writeFloat(it.opacity())
ds.writeFloat(it.rotation())
ds.writeFloat(it.scale())
if isinstance(it, QGraphicsItem):
ds << it.brush() << it.pen()
if isinstance(it, QGraphicsPathItem):
ds << it.path()
def ds_to_item(ds):
module_name = ds.readQString()
class_name = ds.readQString()
mod = importlib.import_module(module_name)
it = getattr(mod, class_name)(blocks.selectedObjType)
flags = QGraphicsItem.GraphicsItemFlag(ds.readInt())
pos = QPointF()
ds >> pos
it.setFlags(flags)
it.setPos(pos)
it.setOpacity(ds.readFloat())
it.setRotation(ds.readFloat())
it.setScale(ds.readFloat())
if isinstance(it, QGraphicsItem):
pen, brush = QPen(), QBrush()
ds >> brush
ds >> pen
it.setPen(pen)
it.setBrush(brush)
if isinstance(it, QGraphicsPathItem):
path = QPainterPath()
ds >> path
it.setPath(path)
return it
class GraphicsSceneClass(QGraphicsScene):
global selectedObjType
def __init__(self, parent=None):
super(GraphicsSceneClass, self).__init__(parent)
self.setSceneRect(0, 0, 1920, 1080)
self.setItemIndexMethod(QGraphicsScene.NoIndex)
self.setBackgroundBrush(QBrush(Qt.black))
def mousePressEvent(self, event):
sampleTransform = QTransform()
objectAtMouse = self.itemAt(event.scenePos(), sampleTransform)
if objectAtMouse and event.button() == Qt.LeftButton:
objectAtMouse.setSelected(True)
elif objectAtMouse == None and event.button() == Qt.RightButton:
self.grid = self.TargPosForLine(event.scenePos(), "ForLine")
def TargPosForLine(self, position, mode):
clicked_column = int((position.y() // 16)) * 16
clicked_row = int((position.x() // 16)) * 16
if clicked_column < 0:
clicked_column = 0
if clicked_row < 0:
clicked_row = 0
if (mode == "ForRect"):
return QRect(clicked_row, clicked_column, 16, 16)
elif (mode == "ForLine"):
return QPointF(clicked_row, clicked_column)
class MainWindow(QMainWindow):
global selectedObjType
# global item
def __init__(self, ):
super(MainWindow, self).__init__()
self.scene = GraphicsSceneClass()
MainWindow.obj = self.scene
self.view = QGraphicsView(self.scene)
self.view.setMouseTracking(True)
self.view.setRenderHint(QPainter.HighQualityAntialiasing)
self.widg = QWidget()
self.horizontalLayout = QHBoxLayout()
self.horizontalLayout.addWidget(self.view)
self.widg.setMouseTracking(True)
self.widget = QWidget()
self.widget.setLayout(self.horizontalLayout)
self.setCentralWidget(self.widget)
self.obj = None
def contextMenuEvent(self, event):
global selectedObjType
contextMenu = QMenu(self)
Cutaction = contextMenu.addAction("Cut")
Coaction = contextMenu.addAction("Copy")
Paaction = contextMenu.addAction("Paste")
Propaction = contextMenu.addAction("draw")
quitAct = contextMenu.addAction("quit")
action = contextMenu.exec_(self.mapToGlobal(event.pos()))
if action == quitAct:
self.close()
elif action == Propaction:
selectedObjType = "line"
objectDrop = sketchBook.SketchBook(selectedObjType)
self.scene.addItem(objectDrop)
objectDrop.setPos(self.scene.grid)
objectDrop.setFlag(QGraphicsItem.ItemIsSelectable)
objectDrop._type1 = "line"#user defined property
# self.scene.addPath(painterPath)
elif action == Coaction:
self.copy()
elif action == Paaction:
self.paste()
def copy(self):
mimedata = QMimeData()
ba = QByteArray()
ds = QDataStream(ba, QIODevice.WriteOnly)
for it in self.scene.selectedItems():
item_to_ds(it, ds)
mimedata.setData(custom_mimeType, ba)
clipboard = QApplication.clipboard()
clipboard.setMimeData(mimedata)
def paste(self):
pos2 = self.scene.grid
clipboard = QApplication.clipboard()
mimedata = clipboard.mimeData()
if mimedata.hasFormat(custom_mimeType):
ba = mimedata.data(custom_mimeType)
ds = QDataStream(ba)
while not ds.atEnd():
it = ds_to_item(ds)#it should also get type1 property
self.scene.addItem(it)
it.setPos(pos2)
def selectedItem(self):
items = self.scene.selectedItems()
if len(items) == 1:
return items[0]
return None
if __name__ == "__main__":
import sys
app = QApplication(sys.argv)
mainWindow = MainWindow()
mainWindow.show()
sys.exit(app.exec_())
如何在复制粘贴时获取用户定义的属性?