Я решил, что основная идея состоит в том, чтобы отслеживать перемещение элемента, что можно сделать, реализовав обработчик событий itemChange. Псевдо-реализация (не вдаваясь в подробности Qt) будет выглядеть так:
Код: Выделить всё
def itemChange(newPosition):
if newPosition.x < scene.x:
newPosition.x = scene.x
return newPosition
Я рассмотрел несколько разных вопросов по stackoverflow, но, похоже, все еще не понимаю, что происходит.
Минимальный рабочий пример с квадратом, который распечатывает координаты X при перетаскивании квадрата. Когда вы перетаскиваете прямоугольник влево от сцены, я ожидаю, что хотя бы одно из значений X приблизится к нулю.
Код: Выделить всё
import sys
from PySide6 import QtWidgets
from PySide6.QtCore import QPointF, QRectF
from PySide6.QtGui import QBrush, QColor, QPen
from PySide6.QtWidgets import QApplication, QMainWindow, QGraphicsScene, QGraphicsRectItem, QGraphicsItem, QGraphicsView
class BoundableItem(QGraphicsRectItem):
def __init__(self, *args, **kwargs):
super(BoundableItem, self).__init__(*args, **kwargs)
# Our items are movable and they send geometry change events
self.setFlag(QtWidgets.QGraphicsItem.GraphicsItemFlag.ItemIsMovable)
self.setFlag(QtWidgets.QGraphicsItem.GraphicsItemFlag.ItemSendsGeometryChanges)
def itemChange(self, change, value: QPointF):
if change == QGraphicsItem.GraphicsItemChange.ItemPositionChange and self.scene():
print(f"X=> As passed: {value.x()} mapToScene: {self.mapToScene(value).x()} mapFromItem: {self.mapFromItem(self, value).x()}")
return super(BoundableItem, self).itemChange(change, value)
class MyWindow(QMainWindow):
def __init__(self):
super(MyWindow, self).__init__()
# Basic window setup
self.setWindowTitle("Bounding Test")
self.setFixedSize(320, 320)
# Set up a fixed-sized screen
scene = QGraphicsScene(0, 0, 240, 240)
scene.setBackgroundBrush(QBrush(QColor.fromRgb(24, 24, 48)))
# Draw a border around the scene
scene.addRect(scene.sceneRect(), QPen(QColor.fromRgb(255, 255, 255)))
# A blue square, offset by 32
rect = BoundableItem(QRectF(32.0, 32.0, 32.0, 32.0))
rect.setBrush(QBrush(QColor.fromRgb(0, 0, 255)))
scene.addItem(rect)
# Make a graphics view for the scene
self.view = QGraphicsView()
self.view.setScene(scene)
self.setCentralWidget(self.view)
if __name__ == '__main__':
app = QApplication()
window = MyWindow()
window.show()
sys.exit(app.exec())
Код: Выделить всё
X=> As passed: -40.0 mapToScene: -79.0 mapFromItem: -40.0Подробнее здесь: https://stackoverflow.com/questions/767 ... oordinates