我正在用我的QGraphicsitems
. 我已经选择了场景中的所有项目并粘贴了它。但是它没有遵循相同的模式。我们可以让项目以我们最初创建的模式粘贴到相同的模式中吗?——
我已尝试使用以下代码
from PyQt5.QtCore import (QByteArray,QDataStream, QIODevice,pyqtSlot, 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
import random
custom_mimeType = "application/x-qgraphicsitems"
pos1 = QPointF()
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()
posdiff = it.pos().x() -pos1().x()
pos1 = QPointF(it.pos().x(),it.pos().y())
# 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)(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)
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.gridOn = 0
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.createToolbars()
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 createToolbars(self):
GridButton = QToolButton()
GridButton.setCheckable(True)
GridButton.setIcon(QIcon('images/GridButton.png'))
GridButton.clicked.connect(self.GridOnOffControl)
GridButton.setToolTip("Grid Control")
self.pointerToolbar = self.addToolBar("Pointer type")
self.pointerToolbar.addWidget(GridButton)
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 GridOnOffControl(self):
if self.scene.gridOn == 0:
self.scene.gridOn = 1
else:
self.scene.gridOn = 0
if self.scene.gridOn == 1:
self.scene.setBackgroundBrush(QBrush(QPixmap('images/Grid.png')))
else:
self.scene.setBackgroundBrush(QBrush(Qt.black))
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:
objectDrop = None
# 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:
objectDrop = None
selectedObjType = "line"
objectDrop = sketchBook.SketchBook(selectedObjType)
print("line",self.scene.grid)
objectDrop.setFlag(QGraphicsItem.ItemIsSelectable)
objectDrop.setFlag(QGraphicsItem.ItemIsMovable)
objectDrop._type1 = "line"
objectDrop.setPos(self.scene.grid.x(),self.scene.grid.y()-48+5)
self.scene.addItem(objectDrop)
elif action == Coaction:
self.copy()
elif action == Paaction:
self.paste()
@pyqtSlot()
def copy(self):
mimedata = QMimeData()
ba = QByteArray()
ds = QDataStream(ba, QIODevice.WriteOnly)
for it in self.scene.selectedItems():
self.posdiff=item_to_ds(it, ds)
mimedata.setData(custom_mimeType, ba)
clipboard = QApplication.clipboard()
clipboard.setMimeData(mimedata)
@pyqtSlot()
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)
it.setBrush(QBrush(gradient))
it.setPos(pos2.x()+self.posdiff().x(),pos2.y()-48)
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 后跟 item3,它们的距离分别是 当我们复制和粘贴它时,它应该遵循相同的模式。
QGraphicsItem.setPos()
是绝对的场景(或相对于其父),替代解决方案是使用moveBy(x, y)
(与 相同setPos(self.pos() + deltaPos)
,但您必须根据参考点考虑点击的相对位置。
我建议您在添加所有项目之前不要设置位置,然后根据将用作“锚”点的特定项目设置它们的位置。
@pyqtSlot()
def paste(self):
pos2=self.scene.grid
clipboard = QApplication.clipboard()
mimedata = clipboard.mimeData()
items = []
topLeft = None
if mimedata.hasFormat(custom_mimeType):
ba = mimedata.data(custom_mimeType)
ds = QDataStream(ba)
while not ds.atEnd():
it = ds_to_item(ds)
items.append(it)
if not topLeft:
topLeft = it
elif it.y() < topLeft.y() or it.x() < topLeft.x():
# find a possible topmost/leftmost item
topLeft = it
# add items, but do not set their position here
# ...
delta = self.scene.grid - topLeft.pos()
[i.moveBy(delta.x(), delta.y()) for i in items]
另一种方法是在复制过程中找到“锚点”,并在数据流中设置每个项目相对于该点的位置,这样您就可以moveBy(pos2.x(), pos2.y())
在添加项目后直接使用。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句