我正在使用PySide构建T恤设计器。为此,我在场景中将T恤的图像设置为QGraphicsScene作为QPixmapItem。为了将设计覆盖在T恤上,我从用户那里获得了设计图像PNG,并将其设置为另一个QPixmapItem。我使用setPos()方法将它们对齐,然后使用setZValue()方法确保“设计PNG”显示在T恤图像的顶部。
我已为设计图像QPixmapItem启用了标志ItemIsMovable,ItemIsSelectable,ItemSendsScenePositionChanges,ItemIsFocusable。因此,我可以在T恤图像上移动设计。接下来,我想将此移动限制在仅可打印的位置。为此,我遵循this question派生了一个新的QGraphicsPixmapItem类,并尝试重新实现itemChange()和mouseMoveEvent()方法。
在这些方法中,我尝试使用super()和常规方法QGraphicsPixmapItem.itemChange(change,event)调用原始QPixmapItem类的相同方法。但是,似乎什么都没有发生。设计可以很好地移动,但并不受限制。要查看该方法是否被调用,我在这些方法中添加了print语句,但未执行这些语句。
我也尝试过在场景中添加setSceneRect()。我还启用了QGraphicsView上的setMouseTracking。但是,这些都不会触发itemChanged()或mouseMoveEvent()。
还有其他一些问题,人们已经在其中解释了如何使用C ++进行此操作。但是,我无法在python中复制它。
# -*- coding: utf-8 -*-
from PySide import QtCore, QtGui
from os import path
class Pixmap(QtGui.QGraphicsPixmapItem):
def __init__(self, pix):
super(Pixmap, self).__init__()
self.pixmap_item = QtGui.QGraphicsPixmapItem(pix)
self.pixmap_item.setFlag(QtGui.QGraphicsItem.ItemIsMovable, True)
self.pixmap_item.setFlag(QtGui.QGraphicsItem.ItemIsSelectable, True)
self.pixmap_item.setFlag(QtGui.QGraphicsItem.ItemSendsScenePositionChanges, True)
self.pixmap_item.setFlag(QtGui.QGraphicsItem.ItemIsFocusable, True)
def itemChange(self, change, event):
QtGui.QGraphicsPixmapItem.itemChange(change, event)
print "Item Changed"
#Code to restrict to a rectangular area goes here
return QtGui.QGraphicsPixmapItem.itemChange(self, change, event)
def mouseMoveEvent(self, event):
super(Pixmap, self).mouseMoveEvent(event)
print "Mouse Moved"
#Code to restrict to a rectangular area goes here
class Ui_frmSelectRoundNeckHalfSleeve(QtCore.QObject):
def setupUi(self, frmSelectRoundNeckHalfSleeve):
frmSelectRoundNeckHalfSleeve.setObjectName("frmSelectRoundNeckHalfSleeve")
frmSelectRoundNeckHalfSleeve.resize(842, 595)
self.imgRoundNeckTShirt = QtGui.QGraphicsView(frmSelectRoundNeckHalfSleeve)
self.imgRoundNeckTShirt.setGeometry(QtCore.QRect(20, 20, 500, 500))
self.imgRoundNeckTShirt.setObjectName("imgRoundNeckTShirt")
self.imgRoundNeckTShirt.setMouseTracking(True)
self.tShirtScene = QtGui.QGraphicsScene(frmSelectRoundNeckHalfSleeve)
self.tShirtScene.setSceneRect(20, 20, 480, 480)
self.TShirtImage = QtGui.QGraphicsPixmapItem(QtGui.QPixmap("./Images/black-t-shirt.jpg").scaled(480, 480, QtCore.Qt.KeepAspectRatio))
self.designImagePixmap = QtGui.QPixmap("./Designs/test.png")
self.designImagePng = Pixmap(self.designImagePixmap.scaledToWidth(135,QtCore.Qt.SmoothTransformation))
self.TShirtImage.setZValue(10)
self.designImagePng.pixmap_item.setZValue(40)
self.designImagePng.pixmap_item.setPos(167,90)
self.tShirtScene.addItem(self.TShirtImage)
self.tShirtScene.addItem(self.designImagePng.pixmap_item)
self.imgRoundNeckTShirt.setScene(self.tShirtScene)
if __name__ == "__main__":
path = r"E:\\Documents\\T Shirt Designer\\"
QtGui.QApplication.addLibraryPath(path)
app = QtGui.QApplication(sys.argv)
testFile = QtGui.QWidget()
ui = Ui_frmSelectRoundNeckHalfSleeve()
ui.setupUi(testFile)
testFile.show()
sys.exit(app.exec_())
答案 0 :(得分:0)
您遇到的错误是您没有覆盖pixmap_item itemChange,而是覆盖了Pixmap。似乎您将继承与组合混淆了。
一种改进是,基本项(T恤)是设计项的父项,因此设计项的坐标相对于基本项。
考虑到前一件事,我已经实现了将设计项的移动限制在T恤项的空间内的逻辑。
# -*- coding: utf-8 -*-
import sys
from os import path
from PySide import QtCore, QtGui
class Pixmap(QtGui.QGraphicsPixmapItem):
def __init__(self, pix, parent=None):
super(Pixmap, self).__init__(pix, parent)
self.setFlag(QtGui.QGraphicsItem.ItemIsMovable, True)
self.setFlag(QtGui.QGraphicsItem.ItemIsSelectable, True)
self.setFlag(QtGui.QGraphicsItem.ItemSendsScenePositionChanges, True)
self.setFlag(QtGui.QGraphicsItem.ItemIsFocusable, True)
def itemChange(self, change, value):
if change == QtGui.QGraphicsItem.ItemPositionChange:
parent = self.parentItem()
if parent is not None:
r = self.mapToParent(self.boundingRect()).boundingRect()
R = parent.boundingRect()
rR = QtCore.QRectF(R.topLeft(), R.size() - r.size())
if not rR.contains(value):
x = min(max(rR.left(), value.x()), rR.right())
y = min(max(rR.top(), value.y()), rR.bottom())
return QtCore.QPointF(x, y)
return QtGui.QGraphicsPixmapItem.itemChange(self, change, value)
class Ui_frmSelectRoundNeckHalfSleeve(QtCore.QObject):
def setupUi(self, frmSelectRoundNeckHalfSleeve):
frmSelectRoundNeckHalfSleeve.setObjectName(
"frmSelectRoundNeckHalfSleeve"
)
frmSelectRoundNeckHalfSleeve.resize(842, 595)
self.imgRoundNeckTShirt = QtGui.QGraphicsView(
frmSelectRoundNeckHalfSleeve
)
self.imgRoundNeckTShirt.setGeometry(QtCore.QRect(20, 20, 500, 500))
self.imgRoundNeckTShirt.setObjectName("imgRoundNeckTShirt")
self.tShirtScene = QtGui.QGraphicsScene(frmSelectRoundNeckHalfSleeve)
self.tShirtScene.setSceneRect(20, 20, 480, 480)
self.TShirtImage = QtGui.QGraphicsPixmapItem(
QtGui.QPixmap("./Images/black-t-shirt.jpg").scaled(
480, 480, QtCore.Qt.KeepAspectRatio
)
)
designImagePixmap = QtGui.QPixmap("./Designs/test.png").scaledToWidth(
135, QtCore.Qt.SmoothTransformation
)
self.designImagePng = Pixmap(designImagePixmap, self.TShirtImage)
self.designImagePng.setZValue(1)
self.designImagePng.setPos(167, 90)
self.tShirtScene.addItem(self.TShirtImage)
self.imgRoundNeckTShirt.setScene(self.tShirtScene)
if __name__ == "__main__":
path = r"E:\\Documents\\T Shirt Designer\\"
QtGui.QApplication.addLibraryPath(path)
app = QtGui.QApplication(sys.argv)
testFile = QtGui.QWidget()
ui = Ui_frmSelectRoundNeckHalfSleeve()
ui.setupUi(testFile)
testFile.show()
sys.exit(app.exec_())