是否有将一个Qgraphicsitem的属性设置为另一个?

时间:2019-08-14 08:55:56

标签: pyqt5

我正在创建一个支持复制粘贴和拖动操作的应用。复制粘贴时,粘贴的项目没有用户定义的属性。

我在复制时有一个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_())

如何在复制粘贴时获取用户定义的属性?

0 个答案:

没有答案