目前,我正在尝试选择多个QGraphicsitem并使用这些项目执行复制粘贴操作

时间:2019-08-08 11:26:15

标签: pyqt5

在我的应用程序中,我添加了许多QGraphicsitem。选择单个项目并复制粘贴即可正常工作。现在我需要一些帮助来复制粘贴100个项目。

我尝试了以下代码,但未按预期工作

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,QShortcut, 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 SketchBook as sketchBook
import Blocks 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.writeInt(it.UserType)
    ds.writeFloat(it.opacity())
    ds.writeFloat(it.rotation())
    ds.writeFloat(it.scale())
    # ds.writeString(it.type())
    # ds.writeQString(it.type1())
    # if isinstance(it, QGraphicsItem):
    #     ds << it.brush() << it.pen()
    if isinstance(it, QGraphicsPixmapItem):
        ds << it.pixmap()
    if isinstance(it, QGraphicsPathItem):
        ds << it.path()

def ds_to_item(ds):
    module_name = ds.readQString()
    class_name = ds.readQString()
    if class_name == 'QGraphicsPixmapItem':
        mod = importlib.import_module(module_name)
        it = getattr(mod, class_name)()
        # 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())
    else:
        mod = importlib.import_module(module_name)
        it = getattr(mod, class_name)(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)
    if isinstance(it, QGraphicsPixmapItem):
        pixmap = QPixmap()
        # pen, brush = QPen(), QBrush()
        # ds >> brush
        # ds >> pen
        ds >> pixmap
        it.setPixmap(pixmap)

    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:
                # pass
                self.grid = self.TargPosForLine(event.scenePos(), "ForLine")
            self.grid = self.TargPosForLine(event.scenePos(), "ForLine")
            print(self.grid)

            # else:
            #     self.DeselectItems()

            # objectAtMouse.QShortcut
    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)
    def DeselectItems(self):
        selectedObjects = self.selectedItems()
        for object in selectedObjects:
            object.setSelected(False)
    def mouseReleaseEvent(self, event):
        # self.DeselectItems()
        pass
class MainWindow(QMainWindow):
    global selectedObjType
    # global item
    def __init__(self,):
        super(MainWindow, self).__init__()
        self.createActions()
        self.createMenus()
        self.scene = GraphicsSceneClass()
        MainWindow.obj = self.scene
        self.view = QGraphicsView(self.scene)
        # self.view.setDragMode(QGraphicsView.RubberBandDrag)
        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 createMenus(self):
        menuBar = self.menuBar()
        fileMenu = menuBar.addMenu('&File')
        fileMenu.addAction(self.exitAction)

        fileMenu = menuBar.addMenu('&Edit')
        fileMenu.addAction(self.copyAction)
        fileMenu.addAction(self.pasteAction)
        fileMenu.addAction(self.selectAction)
    def createActions(self):

        self.exitAction = QAction("E&xit", self, shortcut="Ctrl+X", statusTip="Quit Scenediagram example",
                                  triggered=self.deleteItem)
        self.copyAction = QAction("C&opy", self, shortcut="Ctrl+C", triggered=self.copy)

        self.pasteAction = QAction("P&aste", self, shortcut="Ctrl+V", triggered=self.paste)

        self.selectAction = QAction("S&electAll", self, shortcut="Ctrl+A", triggered=self.selectAll)

    def deleteItem(self):
        for item in self.scene.selectedItems():
            self.scene.removeItem(item)
    def selectAll(self):

        for item in self.scene.items():
            item.setSelected(True)


    def contextMenuEvent(self, event):
        contextMenu = QMenu(self)

        Cutaction = contextMenu.addAction("Cut")
        Coaction = contextMenu.addAction("Copy")
        Paaction = contextMenu.addAction("Paste")
        Propaction = contextMenu.addAction("draw1")
        Propaction1=contextMenu.addAction("draw2")
        quitAct = contextMenu.addAction("quit")
        action = contextMenu.exec_(self.mapToGlobal(event.pos()))
        if action == quitAct:
            self.close()
        elif action == Propaction:
            # painterPath = QPainterPath()
            #
            # painterPath.moveTo(10, 50.0)
            # painterPath.lineTo(50,50)
            # painterPath.lineTo(50,55)
            # painterPath.lineTo(10,55)
            # gradient = QLinearGradient(1, 1, 1, 5)
            # gradient.setColorAt(0, QColor(Qt.gray))
            # gradient.setColorAt(0.5, QColor(192, 192, 192, 255))
            # gradient.setColorAt(1, QColor(Qt.darkGray))
            # painterPath.closeSubpath()
            #
            # objectDrop = QGraphicsPathItem()
            # objectDrop.setPath(painterPath)
            # objectDrop.setBrush(QBrush(gradient))
            objectDrop = QGraphicsPixmapItem(QPixmap("2AS_HG_RG.png"))
            objectDrop.setPos(self.scene.grid)
            print("sig",self.scene.grid)
            # objectDrop._position = QPointF(gridPos.x() + 2, gridPos.y() + 5.9)
            # objectDrop._type = "2AS_HG_RG"
            objectDrop._type1 = "2AS_HG_RG"
            self.scene.addItem(objectDrop)
            objectDrop.setFlag(QGraphicsItem.ItemIsSelectable)
            objectDrop.setFlag(QGraphicsItem.ItemIsMovable)
            objectDrop._type1="2AS_HG_RG"
            # self.scene.addPath(painterPath)

        elif action==Propaction1:
            selectedObjType = "line"

            objectDrop = sketchBook.SketchBook(selectedObjType)

            self.scene.addItem(objectDrop)
            objectDrop.setPos(self.scene.grid)
            print("line",self.scene.grid)
            objectDrop.setFlag(QGraphicsItem.ItemIsSelectable)
            objectDrop.setFlag(QGraphicsItem.ItemIsMovable)
            objectDrop._type1 = "line"
        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)
            # STR = str(ba)
            # QW = ba.capacity()
            ds = QDataStream(ba)
            while not ds.atEnd():
            # for it in ds:
                it = ds_to_item(ds)


                if isinstance(it, QGraphicsPixmapItem):
                    self.scene.addItem(it)
                    it.setPos(pos2)
                    it._position = QPointF(pos2.x() + 2, pos2.y() + 5.9)
                    print("sig",it._position)
                    it._type1 = "2AS_HG_RG"
                else:
                    gradient = QLinearGradient(1, 1, 1, 5)
                    gradient.setColorAt(0, QColor(Qt.gray))
                    gradient.setColorAt(0.5, QColor(192, 192, 192, 255))
                    gradient.setColorAt(1, QColor(Qt.darkGray))
                    self.scene.addItem(it)
                    # self.setPen(QPen(Qt.NoPen))
                    # self.setPath(painterPath)
                    it.setBrush(QBrush(gradient))
                    it.setPos(pos2)
                    it._position = QPointF(pos2.x() + 2, pos2.y() + 5.9)
                    print(it._position)


                    # it.setFlags(QGraphicsItem.ItemIsSelectable)

                    # it._type1 = "line"


    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_())

1)选择场景中的所有项目。 2)复制 3)再次粘贴场景中的项目。不要更改其样式(即,如果item1和item2的距离为10,则粘贴的项目也应为10的距离。

0 个答案:

没有答案