From 096331239823c4b30037c8c9fb9737f8f84dcd9f Mon Sep 17 00:00:00 2001 From: Martin Baeuml Date: Thu, 5 May 2011 17:31:47 +0200 Subject: [PATCH] move inserters to sceneitems --- annotationscene.py | 131 +------------------------- sceneitems/annotationitem.py | 173 +++++++++++++++++++++++++++++++++++ 2 files changed, 174 insertions(+), 130 deletions(-) diff --git a/annotationscene.py b/annotationscene.py index 1f6c3c4..9ceaf50 100644 --- a/annotationscene.py +++ b/annotationscene.py @@ -1,140 +1,11 @@ from PyQt4.QtGui import * from PyQt4.QtCore import * from sceneitems import * -from annotationmodel import ImageRole +from annotationmodel import TypeRole, ImageRole import math import okapy from okapy.guiqt.utilities import toQImage -class ItemInserter: - def __init__(self, scene, mode=None): - self.scene_ = scene - self.mode_ = mode - - 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() - - def keyPressEvent(self, event, index): - event.ignore() - -class PointItemInserter(ItemInserter): - def mousePressEvent(self, event, index): - pos = event.scenePos() - ann = {'type': 'point', - 'x': event.pos().x(), 'y': event.pos().y()} - index.model().addAnnotation(index, ann) - event.accept() - -class RectItemInserter(ItemInserter): - def __init__(self, scene, mode=None): - ItemInserter.__init__(self, scene, mode) - self.current_item_ = None - self.init_pos_ = None - - def mousePressEvent(self, event, index): - pos = event.scenePos() - item = QGraphicsRectItem(QRectF(pos.x(), pos.y(), 0, 0)) - item.setPen(Qt.red) - 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 - rect = QRectF(self.init_pos_, event.scenePos()).normalized() - self.current_item_.setRect(rect) - - 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: - rect = self.current_item_.rect() - ann = {'type': 'rect', - 'x': rect.x(), 'y': rect.y(), - 'width': rect.width(), 'height': rect.height()} - index.model().addAnnotation(index, ann) - self.scene().removeItem(self.current_item_) - self.current_item_ = None - self.init_pos_ = None - - event.accept() - -class FixedRatioRectItemInserter(RectItemInserter): - def __init__(self, scene, mode=None): - RectItemInserter.__init__(self, scene, mode) - self.ratio_ = 1 - if mode is not None: - self.ratio_ = float(mode.get('_ratio', 1)) - - def setMode(self, mode): - if mode is not None: - self.ratio_ = float(mode.get('_ratio', 1)) - RectItemInserter.setMode(self, mode) - - def mouseMoveEvent(self, event, index): - if self.current_item_ is not None: - new_geometry = QRectF(self.current_item_.rect().topLeft(), event.scenePos()) - dx = new_geometry.width() - dy = new_geometry.height() - d = math.sqrt(dx*dx + dy*dy) - r = self.ratio_ - k = math.sqrt(r*r+1) - h = d/k - w = d*r/k - new_geometry.setWidth(w) - new_geometry.setHeight(h) - self.current_item_.setRect(new_geometry.normalized()) - - event.accept() - -class PolygonItemInserter(ItemInserter): - def __init__(self, scene, mode=None): - ItemInserter.__init__(self, scene, mode) - 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 diff --git a/sceneitems/annotationitem.py b/sceneitems/annotationitem.py index d8a4372..5bd6a95 100644 --- a/sceneitems/annotationitem.py +++ b/sceneitems/annotationitem.py @@ -218,6 +218,179 @@ class AnnotationGraphicsPointItem(AnnotationGraphicsItem): self.data_ = self.index().data(DataRole).toPyObject() self.updatePoint() +class ItemInserter: + def __init__(self, scene, mode=None): + self.scene_ = scene + self.mode_ = mode + + 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() + + def keyPressEvent(self, event, index): + event.ignore() + +class PointItemInserter(ItemInserter): + def mousePressEvent(self, event, index): + pos = event.scenePos() + ann = {'type': 'point', + 'x': event.pos().x(), 'y': event.pos().y()} + index.model().addAnnotation(index, ann) + event.accept() + +class RectItemInserter(ItemInserter): + def __init__(self, scene, mode=None): + ItemInserter.__init__(self, scene, mode) + self.current_item_ = None + self.init_pos_ = None + + def mousePressEvent(self, event, index): + pos = event.scenePos() + item = QGraphicsRectItem(QRectF(pos.x(), pos.y(), 0, 0)) + item.setPen(Qt.red) + 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 + rect = QRectF(self.init_pos_, event.scenePos()).normalized() + self.current_item_.setRect(rect) + + 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: + rect = self.current_item_.rect() + ann = {'type': 'rect', + 'x': rect.x(), 'y': rect.y(), + 'width': rect.width(), 'height': rect.height()} + index.model().addAnnotation(index, ann) + self.scene().removeItem(self.current_item_) + self.current_item_ = None + self.init_pos_ = None + + event.accept() + +class FixedRatioRectItemInserter(RectItemInserter): + def __init__(self, scene, mode=None): + RectItemInserter.__init__(self, scene, mode) + self.ratio_ = 1 + if mode is not None: + self.ratio_ = float(mode.get('_ratio', 1)) + + def setMode(self, mode): + if mode is not None: + self.ratio_ = float(mode.get('_ratio', 1)) + RectItemInserter.setMode(self, mode) + + def mouseMoveEvent(self, event, index): + if self.current_item_ is not None: + new_geometry = QRectF(self.current_item_.rect().topLeft(), event.scenePos()) + dx = new_geometry.width() + dy = new_geometry.height() + d = math.sqrt(dx*dx + dy*dy) + r = self.ratio_ + k = math.sqrt(r*r+1) + h = d/k + w = d*r/k + new_geometry.setWidth(w) + new_geometry.setHeight(h) + self.current_item_.setRect(new_geometry.normalized()) + + event.accept() + +class PolygonItemInserter(ItemInserter): + def __init__(self, scene, mode=None): + ItemInserter.__init__(self, scene, mode) + 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 AnnotationGraphicsItemFactory: + def __init__(self): + self.items_ = {} + self.inserters_ = {} + + def register(self, _type, item, inserter, replace=False): + _type = _type.lower() + + if _type in self.items_ and not replace: + raise Exception("Type %s already has an item: %s" % \ + (_type, str(self.items_[_type]))) + else: + self.items_[_type] = item + + if _type in self.inserters_ and not replace: + raise Exception("Type %s already has an inserter: %s" % \ + (_type, str(self.inserters_[_type]))) + else: + self.inserters_[_type] = inserter + + def clear(self, _type=None): + if _type is None: + self.items_ = {} + self.inserters_ = {} + else: + _type = _type.lower() + if _type in self.items_: + del self.items_[_type] + if _type in self.inserters_: + del self.inserters_[_type] + + def createItem(self, _type, *args, **kwargs): + _type = _type.lower() + + if _type not in self.items_: + return None + return self.items_[_type](*args, **kwargs) + + def createItemInserter(self, _type, *args, **kwargs): + _type = _type.lower() + + if _type not in self.inserters_: + return None + return self.inserters_[_type](*args, **kwargs) # register common item types AnnotationGraphicsItem.addItemType('rect', AnnotationGraphicsRectItem)