【发布时间】:2019-12-12 16:04:57
【问题描述】:
我在场景中复制粘贴 QGraphicsitem 时遇到问题。 我已经尝试了以下代码,但它无法正常工作。 如果我尝试粘贴该项目,则它是正确粘贴的第一个实例。对于第二个实例,它正在删除第一个实例项并粘贴第二个实例。
到目前为止,我已经尝试在复制操作中获取项目的路径,并在粘贴操作中将其添加到场景中。
@pos2 是我的网格位置
我只想将复制的项目粘贴 n 次,直到新项目被复制。如果我以错误的方式进行复制粘贴,请纠正我。
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
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):
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:
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))
self.scene.addItem(objectDrop)
objectDrop.setFlag(QGraphicsItem.ItemIsSelectable)
objectDrop._type1="line"
# self.scene.addPath(painterPath)
elif action == Coaction:
self.copy()
elif action == Paaction:
self.paste()
def copy(self):
item = self.selectedItem()
self.dragObject = item
x = str(self.dragObject._type1)
if item is None:
return
if 'text' in x:
self.object = QGraphicsPixmapItem(item.pixmap())
else:
self.object = QGraphicsPathItem(item.path())
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.object.setBrush(QBrush(gradient))
self.object.setPen(QPen(Qt.NoPen))
self.object._type1 = item._type1
def paste(self):
self.scene.addItem(self.object)
self.object.setPos(self.scene.grid.x(), self.scene.grid.y())
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_())
【问题讨论】:
-
复制 QGraphicsItem 的任务并不简单,也不能一概而论,所以这取决于您要复制的小部件类型,因此您需要提供minimal reproducible example
-
我必须在场景中复制并粘贴一个 Qpainterpath 项
-
你的代码非常少见,因为你使用了dragObject,然后检查
if 'text' in x:等。你可以提供一个MRE -
我还有一个问题:假设你要复制的item的位置在(x,y)位置,那么复制的item会粘贴到哪里?
-
对不起..这是我的错误..我的代码中的第二种方法应该是粘贴(def paste(self):)。我把它误认为是副本。
标签: python pyqt pyqt5 qgraphicsitem