mirror of
https://github.com/wassname/sloth.git
synced 2026-06-28 19:33:33 +08:00
a modularized approach to item adding
This commit is contained in:
+174
-38
@@ -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
|
||||
|
||||
|
||||
+4
-4
@@ -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():
|
||||
|
||||
Reference in New Issue
Block a user