Reputation: 357
I tried using the Qt documentation example to restrict the rectangle to the area of the scene but it still fails, someone has an alternative to do this?
My code, the QGraphicsView instance was created in Qt Desginer:
# -*- coding: utf-8 -*-
from PyQt4.QtCore import *
from PyQt4.QtGui import *
import sys
from screen import *
class MovableItem(QGraphicsRectItem):
def __init__(self, rectang, *args, **kwargs):
QGraphicsRectItem.__init__(self, rectang, *args, **kwargs)
self.setFlags(QGraphicsItem.ItemIsMovable |
QGraphicsItem.ItemSendsGeometryChanges)
self.pen = QPen(Qt.darkMagenta)
self.pen.setWidth(4)
self.setPen(self.pen)
def itemChange(self, change, value):
if change == QGraphicsItem.ItemPositionChange and self.scene():
# value is the new position.
self.newPos = value.toPointF()
self.rect = self.scene().sceneRect()
if not(self.rect.contains(self.newPos)):
# Keep the item inside the scene rect.
self.newPos.setX(min(self.rect.right(), max(self.newPos.x(), self.rect.left())))
self.newPos.setY(min(self.rect.bottom(), max(self.newPos.y(), self.rect.top())))
return self.newPos
return QGraphicsRectItem.itemChange(self, change, value)
class Main(QWidget, Ui_Form):
def __init__(self, parent=None):
super(Main, self).__init__(parent)
self.setupUi(self)
self.scene = QGraphicsScene()
self.cena.setScene(self.scene)
self.scene.addPixmap(QPixmap("01.png"))
self. graph = MovableItem(2, 2, 300, 150)
self.scene.addItem(self.graph)
def showEvent(self, event):
self.cena.fitInView(self.scene.sceneRect(), Qt.IgnoreAspectRatio)
app = QApplication(sys.argv)
window = Main()
window.show()
sys.exit(app.exec_())
Upvotes: 1
Views: 582
Reputation: 148
First:
Use setSceneRect()
in your main Main()
, to set the size of the scene.
Second:
Actually the example of the documentation is wrong, therefore, to adjust the rectangle to the scene, delete this if
and subtract, in min
, the parameters right
and bottom
by the rectangle dimensions right
and bottom
in setX
and setY
. Replace this part of your code:
if not(self.rect.contains(self.newPos)):
# Keep the item inside the scene rect.
self.newPos.setX(min(self.rect.right(), max(self.newPos.x(), self.rect.left())))
self.newPos.setY(min(self.rect.bottom(), max(self.newPos.y(), self.rect.top())))
return self.newPos
For:
self.newPos.setX(min(self.rect.right()-self.boundingRect().right(), max(self.newPos.x(), self.rect.left())))
self.newPos.setY(min(self.rect.bottom()-self.boundingRect().bottom(), max(self.newPos.y(), self.rect.top())))
return self.newPos
Upvotes: 1