import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *
SCENESIZE = 500
def makeBrushSetter(color, colorName):
a = (lambda obj: obj.items["main"].setBrush(QBrush(color)))
a.__doc__ = "Fill the shape with %s"%colorName
return a
def makePenColorSetter(color, colorName):
a = (lambda obj:
obj.items["main"].setPen(QPen(QBrush(color),
obj.items["main"].pen().width()))
)
a.__doc__ = "Stroke the shape with %s"%colorName
return a
def makePenWidthSetter(step):
def moreThanOne(value):
if value < 1:
return 1
else:
return value
def currentPen(obj):
return obj.items["main"].pen()
def currentColor(obj):
return obj.items["main"].pen().brush().color()
a = (lambda obj:
obj.items["main"].setPen(QPen(QBrush(currentColor(obj)),
moreThanOne(currentPen(obj).width()
+ step)))
)
doc = "Increase the pen width %d" % step
a.__doc__ = doc
return a
def key_to_string(key, shift):
c = None
if Qt.Key_Space <= key <= Qt.Key_AsciiTilde:
c = "%c" % key
if not shift:
c = c.lower()
return c
class Keymap( object ):
def indexFor(self, control, alt):
index = 0;
if control:
index = index + 1
if alt:
index = index + 2
return index
def __init__(self):
super(Keymap, self).__init__()
self.table = {}
self.parent = None
def define_key(self, key, control, alt, action):
index = self.indexFor(control, alt)
entry = self.table.get(key, [None, None, None, None])
entry[index] = action
self.table[key] = entry
return entry
def lookup_key(self, key, control, alt):
index = self.indexFor(control, alt)
tuple = self.table.get(key, [None, None, None, None])
action = tuple[index];
if not action:
action = lambda obj: None
return action
def keys(self):
result_ = []
result_control = []
result_alt = []
result_control_alt = []
for k in self.table:
a = self.lookup_key(k, False, False)
if a:
result_.append({"keystr": k, "control": False, "alt": False})
a = self.lookup_key(k, True, False)
if a:
result_control.append({"keystr": k, "control": True, "alt": False})
a = self.lookup_key(k, False, True)
if a:
result_alt.append({"keystr": k, "control": False, "alt": True})
a = self.lookup_key(k, True, True)
if a:
result_control_alt.append({"keystr": k, "control": True, "alt": True})
return result_ + result_control + result_alt + result_control_alt
class Window(QMainWindow):
def __init__(self, parent=None):
super(Window, self).__init__(parent)
self.scene = QGraphicsScene(self)
self.scene.setSceneRect(0, 0, SCENESIZE, SCENESIZE)
self.view = QGraphicsView()
self.view.setRenderHint(QPainter.Antialiasing)
self.view.setScene(self.scene)
self.view.setFocusPolicy(Qt.NoFocus)
self.setCentralWidget(self.view)
self.items = {}
self.items["main"] = QGraphicsEllipseItem(0, 0, SCENESIZE, SCENESIZE)
self.items["main"].setPen(QPen(QBrush(Qt.black), 5))
self.items["main"].setBrush(QBrush(Qt.white))
self.scene.addItem(self.items["main"])
self.keymap = Keymap()
def define_key(self, keystr, control, alt, action):
return self.keymap.define_key(keystr, control, alt, action)
def describe_bindings(self):
slot = "describe-bindings"
item = self.items.get(slot, None)
if item and item.isVisible():
self.scene.removeItem(self.items[slot])
self.items[slot] = None
self.items["main"].show()
return
self.items["main"].hide()
help_strings = []
keys = self.keymap.keys()
for k in keys:
if (not k["control"]) and (not k["alt"]):
a = self.keymap.lookup_key(k["keystr"], False, False)
if a.__doc__:
help_strings.append ("%s: %s"%(k["keystr"],
a.__doc__))
for k in keys:
if (k["control"]) and (not k["alt"]):
a = self.keymap.lookup_key(k["keystr"], True, False)
if a.__doc__:
help_strings.append ("\\C-%s: %s"%(k["keystr"],
a.__doc__))
for k in keys:
if (not k["control"]) and (k["alt"]):
a = self.keymap.lookup_key(k["keystr"], False, True)
if a.__doc__:
help_strings.append ("\\M-%s: %s"%(k["keystr"],
a.__doc__))
for k in keys:
if (k["control"]) and (k["alt"]):
a = self.keymap.lookup_key(k["keystr"], True, True)
if a.__doc__:
help_strings.append ("\\C-\\M-%s: %s"%(k["keystr"],
a.__doc__))
help_string = ""
for s in help_strings:
help_string = help_string + s + "\n"
self.items["describe-bindings"] = QGraphicsSimpleTextItem(help_string)
self.scene.addItem(self.items["describe-bindings"])
def switchItem(self):
oi = self.items["main"]
p = oi.pen()
b = oi.brush()
t = oi.transform()
if type(oi) == QGraphicsEllipseItem:
ni = QGraphicsRectItem(0, 0, SCENESIZE, SCENESIZE)
elif type(oi) == QGraphicsRectItem:
ni = QGraphicsPathItem()
path = QPainterPath()
h = (1.732 * SCENESIZE / 2)
offset = (SCENESIZE - h) / 2.0
path.moveTo(0, SCENESIZE - offset )
path.lineTo(SCENESIZE, SCENESIZE - offset)
path.lineTo(SCENESIZE/2, SCENESIZE - (1.732 * SCENESIZE /2) - offset)
path.closeSubpath()
ni.setPath(path)
else:
ni = QGraphicsEllipseItem(0, 0, SCENESIZE, SCENESIZE)
self.scene.removeItem(oi)
ni.setPen(p)
ni.setBrush(b)
ni.setTransform(t)
self.items["main"] = ni
self.scene.addItem(self.items["main"])
def keyPressEvent(self, event):
k = event.key()
m = event.modifiers()
kstr = key_to_string(k, m & Qt.ShiftModifier)
if kstr:
a = self.keymap.lookup_key(kstr,
m & Qt.ControlModifier,
m & Qt.AltModifier)
a(self)
def zoomIn(self, obj):
self.zoom(obj, 1.01, 1.01)
def zoomOut(self, obj):
self.zoom(obj, 0.99, 0.99)
def zoom(self, obj, sx, sy):
obj = self.items[obj]
otform = obj.transform()
ntform = QTransform()
ntform.translate(SCENESIZE/2, SCENESIZE/2)
# TODO
m11 = otform.m11()
m22 = otform.m22()
if m11 < 0.01:
m11 = 0.01
if m22 < 0.01:
m22 = 0.01
ntform.scale(sx * m11, sy * m22)
ntform.translate(-SCENESIZE/2, -SCENESIZE/2)
obj.setTransform(ntform)
app = QApplication(sys.argv)
form = Window()
def_key = form.define_key
def_key("b", False, False, makeBrushSetter(Qt.blue,
"blue"))
def_key("b", True, False, makePenColorSetter(Qt.blue,
"blue"))
def_key("f", False, False, makePenWidthSetter(1))
def_key("g", False, False, makeBrushSetter(Qt.green,
"green"))
def_key("g", True, False, makePenColorSetter(Qt.green,
"green"))
def_key("k", False, False, makeBrushSetter(Qt.black,
"black"))
def_key("k", True, False, makePenColorSetter(Qt.black,
"black"))
def_key("m", False, False, makeBrushSetter(QColor(0xa0, 0x20, 0xf0),
"purple"))
def_key("m", True, False, makePenColorSetter(QColor(0xa0, 0x20, 0xf0),
"purple"))
def_key("n", False, False, makePenWidthSetter(-1))
def_key("o", False, False, makeBrushSetter(QColor(0xff, 0x7f, 0x50),
"orange"))
def_key("o", True, False, makePenColorSetter(QColor(0xff, 0x7f, 0x50),
"orange"))
def_key("p", False, False, makeBrushSetter(QColor(0xff, 0xc0, 0xcb),
"pink"))
def_key("p", True, False, makePenColorSetter(QColor(0xff, 0xc0, 0xcb),
"pink"))
quit = (lambda obj: sys.exit(0))
quit.__doc__ = "Quit"
def_key("q", False, True, quit)
def_key("r", False, False, makeBrushSetter(Qt.red,
"red"))
def_key("r", True, False, makePenColorSetter(Qt.red,
"red"))
switchItem = (lambda obj: obj.switchItem())
switchItem.__doc__ = "Toggle the shape: Circle <-> Rectangle"
def_key("t", False, False, switchItem)
def_key("w", False, False, makeBrushSetter(Qt.white,
"white"))
def_key("w", True, False, makePenColorSetter(Qt.white,
"white"))
def_key("y", False, False, makeBrushSetter(Qt.yellow,
"yellow"))
def_key("y", True, False, makePenColorSetter(Qt.yellow,
"yellow"))
zoomIn = (lambda obj: obj.zoomIn("main"))
zoomIn.__doc__ = "Zoom in"
def_key("u", False, False, zoomIn)
zoomOut = (lambda obj: obj.zoomOut("main"))
zoomOut.__doc__ = "Zoom out"
def_key("d", False, False, zoomOut)
describe_bindings = (lambda obj: obj.describe_bindings())
describe_bindings.__doc__ = "Describe key bindings"
def_key("?", False, False, describe_bindings)
rect = QApplication.desktop().availableGeometry()
form.resize(int(rect.width() * 0.9), int(rect.height() * 0.9))
form.show()
app.exec_()