大家好,我正在开发一个项目,该项目要求我创建一个自定义 QGraphicsItemGroup,当检查小部件时该项目会捕捉到网格。捕捉到网格逻辑(部分)工作,因为当我移动项目时,它每次移动移动 10 个像素(捕捉)。然而,它从场景中的 0, 0 移动,这意味着如果该组是在 100, 100 创建的,它将像在 0, 0 创建的位置一样移动。我不知道我是否真的很好地解释了这个问题,所以随意自己玩一下吧。
class CustomGraphicsItemGroup(QGraphicsItemGroup):
def __init__(self, widget):
super().__init__()
self.widgets = widget
def paint(self, painter, option, widget=None):
# Call the parent class paint method first
super().paint(painter, option, widget)
# If the item is selected, draw a custom selection highlight
if option.state & QStyle.State_Selected:
pen = painter.pen()
pen.setColor(QColor('#e00202'))
pen.setWidth(2)
pen.setCapStyle(Qt.RoundCap)
painter.setPen(pen)
painter.drawRect(self.boundingRect())
def mouseMoveEvent(self, event: QGraphicsSceneMouseEvent):
if self.widgets.isChecked():
block_size = 10
# Calculate the position relative to the scene's coordinate system
scene_pos = event.scenePos()
x = int(scene_pos.x() / block_size) * block_size
y = int(scene_pos.y() / block_size) * block_size
# Set the position relative to the scene's coordinate system
self.setPos(x, y)
else:
# Call the superclass's mouseMoveEvent to move the item as normal
super().mouseMoveEvent(event)
我尝试使用不同的数字、除法、乘法,但没有任何效果。任何帮助或代码片段表示赞赏。
所以首先,在继承
QGraphicsItemGroup
时,应该考虑它的概念。该组不希望在构造函数中拥有子级。相反,项目会添加到组中。该组本身就是所有添加项目的代理。
有两种方法可以在场景中创建组。可以在场景中创建自定义组的选项如下。
group = CustomGraphicsItemGroup()
group.setFlag(QGraphicsItem.GraphicsItemFlag.ItemIsSelectable, True)
group.setFlag(QGraphicsItem.GraphicsItemFlag.ItemIsMovable, True)
scene.addItem(group)
group.addToGroup(red_item)
group.addToGroup(blue_item)
您应该始终使用 Qt 可用的工具,而不是重新发明轮子。设置正确的标志非常重要,以便项目(或组)可以选择和移动。然后使用该项目本身的
self.isSelected
。
对于您的问题,必须以某种方式应用鼠标的偏移量,以便不会发生突然的跳跃。这可以存储在
mousePressEvent
中。
import sys
from PySide6.QtCore import QRect, QPoint
from PySide6.QtGui import QColor, Qt
from PySide6.QtWidgets import (
QGraphicsItemGroup,
QStyle,
QGraphicsItem,
QGraphicsScene,
QGraphicsView,
QApplication,
QGraphicsRectItem,
)
class CustomGraphicsItemGroup(QGraphicsItemGroup):
def __init__(self, parent=None):
super().__init__(parent)
self.mouse_offset = QPoint(0, 0)
self.block_size = 10
def paint(self, painter, option, widget=None):
# Call the parent class paint method first
super().paint(painter, option, widget)
# If the item is selected, draw a custom selection highlight
if option.state & QStyle.State_Selected:
pen = painter.pen()
pen.setColor(QColor("#e00202"))
pen.setWidth(2)
pen.setCapStyle(Qt.RoundCap)
painter.setPen(pen)
painter.drawRect(self.boundingRect())
def mousePressEvent(self, event):
if event.button() == Qt.MouseButton.LeftButton:
self.mouse_offset = event.pos()
super().mousePressEvent(event)
def mouseMoveEvent(self, event):
if self.isSelected():
# Calculate the position relative to the scene's coordinate system
scene_pos = event.scenePos()
x = (
int(scene_pos.x() / self.block_size) * self.block_size
- self.mouse_offset.x()
)
y = (
int(scene_pos.y() / self.block_size) * self.block_size
- self.mouse_offset.y()
)
# Set the position relative to the scene's coordinate system
self.setPos(x, y)
else:
# Call the superclass's mouseMoveEvent to move the item as normal
super().mouseMoveEvent(event)
if __name__ == "__main__":
app = QApplication(sys.argv)
scene = QGraphicsScene()
view = QGraphicsView(scene)
scene.setSceneRect(QRect(0, 0, 500, 500))
view.setFixedWidth(500)
view.setFixedHeight(500)
view.show()
group = CustomGraphicsItemGroup()
group.setFlag(QGraphicsItem.GraphicsItemFlag.ItemIsSelectable, True)
group.setFlag(QGraphicsItem.GraphicsItemFlag.ItemIsMovable, True)
scene.addItem(group)
red_item = QGraphicsRectItem()
red_item.setFlag(QGraphicsItem.GraphicsItemFlag.ItemIsSelectable, True)
red_item.setFlag(QGraphicsItem.GraphicsItemFlag.ItemIsMovable, True)
red_item.setBrush(QColor("red"))
red_item.setRect(0, 0, 80, 80)
red_item.setPos(150, 150)
group.addToGroup(red_item)
blue_item = QGraphicsRectItem()
blue_item.setFlag(QGraphicsItem.GraphicsItemFlag.ItemIsSelectable, True)
blue_item.setFlag(QGraphicsItem.GraphicsItemFlag.ItemIsMovable, True)
blue_item.setBrush(QColor("blue"))
blue_item.setRect(0, 0, 100, 100)
blue_item.setPos(100, 100)
group.addToGroup(blue_item)
scene.addItem(blue_item)
scene.addItem(red_item)
sys.exit(app.exec())