mirror of
https://github.com/wassname/sloth.git
synced 2026-07-12 13:44:00 +08:00
137 lines
4.2 KiB
Python
137 lines
4.2 KiB
Python
from PyQt4.QtGui import *
|
|
from PyQt4.Qt import *
|
|
import math
|
|
|
|
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()
|
|
|
|
def allowOutOfSceneEvents(self):
|
|
return False
|
|
|
|
class PointItemInserter(ItemInserter):
|
|
def mousePressEvent(self, event, index):
|
|
pos = event.scenePos()
|
|
ann = {'type': 'point',
|
|
'x': pos.x(), 'y': 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()
|
|
|