From 2d657478ffc7eb69737d1519077aa062e298a72f Mon Sep 17 00:00:00 2001 From: Martin Baeuml Date: Fri, 3 Dec 2010 17:59:42 +0100 Subject: [PATCH] a modularized approach to item adding --- annotationscene.py | 212 +++++++++++++++++++++++++++++++++++++-------- object_view.py | 8 +- 2 files changed, 178 insertions(+), 42 deletions(-) diff --git a/annotationscene.py b/annotationscene.py index fd8c555..dbec64d 100644 --- a/annotationscene.py +++ b/annotationscene.py @@ -1,63 +1,199 @@ from PyQt4.QtGui import * from PyQt4.QtCore import * -from pointitem import * +from sceneitems import * import math -modes = range(5) -SELECT, POINT, LINE, RECTANGLE, POLYGON = modes +class ItemInserter: + def __init__(self, scene, model=None): + self.scene_ = scene + self.model_ = model + self.mode_ = None + + def setModel(self, model): + self.model_ = model + def model(self): + return self.model_ + + def setScene(self, scene): + self.scene_ = scene + def scene(self): + return self.scene_ + + def setMode(self, mode): + self.mode_ = mode + def mode(self): + return self.mode + + def mousePressEvent(self, event, index): + event.accept() + + def mouseReleaseEvent(self, event, index): + event.accept() + + def mouseMoveEvent(self, event, index): + event.accept() + +class PointItemInserter(ItemInserter): + def mousePressEvent(self, event, index): + pos = event.scenePos() + # TODO create it in the model instead + item = QGraphicsEllipseItem(QRectF(pos.x()-1, pos.y()-1, 2, 2)) + self.scene().addItem(item) + + event.accept() + +class RectItemInserter(ItemInserter): + def __init__(self, scene, model=None): + ItemInserter.__init__(self, scene, model) + self.current_item_ = None + self.init_pos_ = None + + def mousePressEvent(self, event, index): + pos = event.scenePos() + # TODO create it in the model instead + item = QGraphicsRectItem(QRectF(pos.x(), pos.y(), 0, 0)) + self.current_item_ = item + self.init_pos_ = pos + self.scene().addItem(item) + + event.accept() + + def mouseMoveEvent(self, event, index): + if self.current_item_ is not None: + assert self.init_pos_ is not None + pos = event.scenePos() + rect = QRectF(self.init_pos_.x(), self.init_pos_.y(), + pos.x() - self.init_pos_.x(), pos.y() - self.init_pos_.y()) + self.current_item_.setRect(rect.normalized()) + + event.accept() + + def mouseReleaseEvent(self, event, index): + if self.current_item_ is not None: + if self.current_item_.rect().width() > 1 and \ + self.current_item_.rect().height() > 1: + # TODO commit to the model + print "added rect:", self.current_item_ + self.current_item_ = None + self.init_pos_ = None + + event.accept() + +class PolygonItemInserter(ItemInserter): + def __init__(self, scene, model=None): + ItemInserter.__init__(self, scene, model) + self.current_item_ = None + + def mousePressEvent(self, event, index): + pos = event.scenePos() + if self.current_item_ is None: + item = QGraphicsPolygonItem(QPolygonF([pos])) + self.current_item_ = item + self.scene().addItem(item) + else: + polygon = self.current_item_.polygon() + polygon.append(pos) + self.current_item_.setPolygon(polygon) + + event.accept() + + def mouseMoveEvent(self, event, index): + if self.current_item_ is not None: + pos = event.scenePos() + polygon = self.current_item_.polygon() + assert polygon.size() > 0 + polygon[-1] = pos + self.current_item_.setPolygon(polygon) + + event.accept() class AnnotationScene(QGraphicsScene): + + # TODO signal itemadded + def __init__(self, parent=None): super(AnnotationScene, self).__init__(parent) self.setBackgroundBrush(Qt.darkGray) self.reset() self.setSceneRect(0,0, 640, 480) + self.addRect(QRectF(0, 0, 640, 480), brush=Qt.white) - self.mode_ = None - self.mousePressed_ = None - self.activeItem_ = None + self.mode_ = None + self.inserters_ = {} + self.inserter_ = None + self.debug_ = True + + self.addItemInserter('point', PointItemInserter(self)) + self.addItemInserter('rect', RectItemInserter(self)) + self.addItemInserter('poly', PolygonItemInserter(self)) + self.addItemInserter('polygon', PolygonItemInserter(self)) + + #self.setMode({'type': 'point'}) + #self.setMode({'type': 'rect'}) + self.setMode({'type': 'poly'}) def reset(self): self.clear() def setMode(self, mode): - assert (mode in modes) + print "setMode :", mode self.mode_ = mode - print mode - - - def mousePressEvent(self, event): - if not self.sceneRect().contains(event.scenePos()): - return - elif self.mode_ == SELECT: - QGraphicsScene.mousePressEvent(self, event) - return - elif self.mode_ == POINT: - self.insertItem(AnnotationGraphicsPointItem(event.scenePos())) - event.accept() - elif self.mode_ == LINE: - self.mousePressed_ = event.scenePos() - line = QGraphicsLineItem(QLineF(event.scenePos(), event.scenePos())) - self.activeItem_ = line - self.addItem(line) - event.accept() - self.update() + if self.mode_ == None: + self.inserter_ = None + return + + if not self.mode_['type'] in self.inserters_: + raise InvalidArgumentException("Invalid mode") + + self.inserter_ = self.inserters_[self.mode_['type']] + self.inserter_.setMode(self.mode_) + + def addItemInserter(self, type, inserter): + if type in self.inserters_: + raise Exception("Type %s already has an inserter" % type) + + self.inserters_[type] = inserter + + def removeItemInserter(self, type): + if type in self.inserters_: + del self.inserters_[type] + + def mousePressEvent(self, event): + if self.debug_: + print "mousePressEvent", self.sceneRect().contains(event.scenePos()), event.scenePos() + if not self.sceneRect().contains(event.scenePos()): + # ignore events outside the scene rect + return + elif self.inserter_ is not None: + # insert mode + self.inserter_.mousePressEvent(event, None) + else: + # selection mode + QGraphicsScene.mousePressEvent(self, event) def mouseReleaseEvent(self, event): - self.mousePressed_ = None - QGraphicsScene.mouseReleaseEvent(self, event) - - def mouseMoveEvent(self, event): - print LINE - if not self.sceneRect().contains(event.scenePos()): - return - elif self.mode_ == LINE: - ## TODO - activeItem. + if self.debug_: + print "mouseReleaseEvent", self.sceneRect().contains(event.scenePos()), event.scenePos() + if self.inserter_ is not None: + # insert mode + self.inserter_.mouseReleaseEvent(event, None) else: + # selection mode + QGraphicsScene.mouseReleaseEvent(self, event) + + def mouseMoveEvent(self, event): + if self.debug_: + print "mouseMoveEvent", self.sceneRect().contains(event.scenePos()), event.scenePos() + if self.inserter_ is not None: + # insert mode + self.inserter_.mouseMoveEvent(event, None) + else: + # selection mode QGraphicsScene.mouseMoveEvent(self, event) - def insertItem(self, item): - self.addItem(item) + def addItem(self, item): + QGraphicsScene.addItem(self, item) + # TODO emit signal itemAdded + diff --git a/object_view.py b/object_view.py index 90e3a58..8054b5a 100755 --- a/object_view.py +++ b/object_view.py @@ -39,19 +39,19 @@ class MainWindow(QMainWindow): self.setCentralWidget(central) def clickedSelect(self): - self.scene_.setMode(SELECT) + self.scene_.setMode(None) def clickedPoint(self): - self.scene_.setMode(POINT) + self.scene_.setMode({'type': 'point'}) def clickedRectangle(self): - self.scene_.setMode(RECTANGLE) + self.scene_.setMode({'type': 'rect'}) def clickedLine(self): self.scene_.setMode(LINE) def clickedPolygon(self): - self.scene_.setMode(POLYGON) + self.scene_.setMode({'type': 'polygon'}) def main():