はじめに
Kivyのgraphics周りのDocumentationは抜けているところが多いので、ソースコードを読まないとわからないことが多いです。その上ソースコードはcython用なので、私のEditor(SublimeText)の持つソースコード参照機能や__doc__
参照機能が使えず、調べるのに時間を要する事が多いです。なので自分なりによく使う機能や忘れやすい事をまとめました。
canvas命令全体図
InstructionGroup
doc, src
さっそくですがDocに載っていない物があります。ただもしかすると内部用の物で意図的に載せてないのかもしれません。
-
length()
...持っている描画命令の数を返すMethod -
indexof(inst)
...instが内部の描画命令のlist上の何番目に位置するかを返すMethod
またmethodではないので明らかに内部用ですが、便利そうなので次の属性も挙げておきます。
-
children
...持っている描画命令のlist
from kivy.lang import Builder
from kivy.app import runTouchApp
root = Builder.load_string(r'''
FloatLayout:
canvas:
Rectangle:
size: self.size
pos: self.pos
''')
canvas = root.canvas
print('命令の総数は', canvas.length())
for inst in canvas.children:
print(inst)
print('{}の序数は{}'.format(inst, canvas.indexof(inst)))
runTouchApp(root)
命令の総数は 2
<kivy.graphics.context_instructions.BindTexture object at 0x7f14b7a8ef78>
<kivy.graphics.vertex_instructions.Rectangle object at 0x7f14b7ee1688>
<kivy.graphics.vertex_instructions.Rectangle object at 0x7f14b7ee1688>の序数は1
Callback
canvas命令ですがFactoryに登録されていないのでKv言語からは利用できません。
追記2018/07/29
最新版(master branch)のKivyではKv言語からも利用可能になりました。
Widget:
canvas:
Callback:
callback: lambda __: setattr(self, 'callback_test', 'TEST')
ScissorPush, ScissorPop
描画範囲を指定した長方形内に制限します。
from kivy.lang import Builder
from kivy.app import runTouchApp
root = Builder.load_string(r'''
FloatLayout:
canvas:
ScissorPush:
size: int(self.width *0.7), int(self. height *0.7)
pos: 0, 0
Ellipse:
size: self.size
pos: self.pos
ScissorPop:
''')
runTouchApp(root)
ScissorPush
に渡す長方形の座標は
- int型で指定しないといけない
- 常にWindow座標系
なのが注意点。またここでもDocの書き忘れがあり、それはx
,y
を纏めて設定できるpos
とwidth
,height
を纏めて設定できるsize
です。
StencilXXX系
doc,src
ScissorXXXとは違って自由度の高い描画領域の制限が行える。
from kivy.lang import Builder
from kivy.app import runTouchApp
root = Builder.load_string(r'''
RelativeLayout:
canvas:
StencilPush:
# 段階1: ここでの描画は実際には行われず、段階2での描画の範囲を決めるのにだけ使われる
Rectangle:
size: self.width * 0.7, self.height * 0.7
pos: 0, 0
Ellipse:
size: self.width * 0.7, self.height * 0.7
pos: self.width * 0.3, self.height * 0.3
StencilUse:
# 段階2: 段階1で決められた範囲制限のもと、描画が行われる
Color:
rgba: 1, 1, 1, 1
Rectangle:
size: self.size
pos: 0, 0
StencilUnUse:
# 段階3: ここでは段階1と全く同じ描画を行わなければならない。正しく後始末する為にこの手順が必要らしいです。
Rectangle:
size: self.width * 0.7, self.height * 0.7
pos: 0, 0
Ellipse:
size: self.width * 0.7, self.height * 0.7
pos: self.width * 0.3, self.height * 0.3
StencilPop:
''')
runTouchApp(root)
楕円と長方形の重なっている部分が描画範囲から外れています。多分段階1で奇数回描画されたPixelのみが段階2における描画可能な範囲になるのだと思います。
VertexInstruction
VertexInstruction
はsource
とtexture
というpropertyを持っています。Rectangle
やMesh
等で何気なく使っていたこのpropertyはここで実装されたものでした。という事はLine
やPoint
にもTextureを貼り付けれるはずです。
LineへのTexture貼り付け
from kivy.lang import Builder
from kivy.app import runTouchApp
root = Builder.load_string(r'''
RelativeLayout:
canvas:
Line:
points:
[
0, 0,
self.width / 3, self.height,
self.width * 2 / 3, 0,
self.width, self.height,
]
width: 30
source: 'python-logo.png'
''')
runTouchApp(root)
PointへのTexture貼り付け
from kivy.lang import Builder
from kivy.app import runTouchApp
root = Builder.load_string(r'''
RelativeLayout:
canvas:
Point:
points:
[
0, 0,
self.width / 3, self.height,
self.width * 2 / 3, 0,
self.width, self.height,
]
pointsize: 100
source: 'python-logo.png'
''')
runTouchApp(root)
図形の塗りつぶし と 線の描画
通常長方形で塗りつぶす時はRectangle
を使い、辺のみを書きたい時にはLine
を使う事になると思います。この時のパラメータの渡し方が異なっていて非常にややこしいのでメモしておきます。
長方形
Rectangle:
pos: self.pos
size: self.size
Line:
rectangle: [*self.pos, *self.size, ] # python3.5以降じゃないと使えない構文
楕円
Ellipse:
pos: self.pos
size: self.size
Line:
ellipse: [*self.pos, *self.size, ]
Ellipse:
pos: self.pos
size: self.size
angle_start: 0
angle_end: 270
Line:
ellipse: [*self.pos, *self.size, 0, 270, ]
角の丸い長方形
RoundedRectangle:
pos: self.pos
size: self.size
radius: [30, ]
Line:
rounded_rectangle: [*self.pos, *self.size, 30, ]
RoundedRectangle:
pos: self.pos
size: self.size
radius: [(10, 10), (40, 40), (100, 100), (200, 200), ]
Line:
rounded_rectangle: [*self.pos, *self.size, 200, 100, 40, 10, ] # 注意: radiusの部分の順番と形式が異なる
真円
真円に特化した塗りつぶし命令は無いのでEllipseで代用する
Line:
circle: [*self.center, min(*self.size) / 2]
Line:
circle: [*self.center, min(*self.size) / 2, 0, 270]
他
Quad
は四角形を描く命令です。Mesh
は別の記事で取り扱った事があるので割愛します。
ContextInstruction
doc, doc, src
自分でShaderを書かないのならContextInstructionの中で使う物は Scale
, Rotate
, Translate
, Color
, PushMatrix
, PopMatrix
の6つだけになると思います。この内のColor
以外の5つは行列を操作する命令で、詳しくは過去の記事にて書いたので割愛します。
Clear
ClearはInstruction
の派生Classではありません。それどころかClassですらありません。これはKv言語のcanvas内でのみ使える特殊な描画命令です。
from kivy.lang import Builder
from kivy.app import runTouchApp
root = Builder.load_string(r'''
Label:
text: 'TEST'
canvas:
Color: # A
rgb: 0, 1, 0 # A
Clear: # B
Rectangle:
size: self.size
pos: self.pos
texture: self.texture
''')
runTouchApp(root)
B行を消した場合の結果
Clear
によってClear
の前に追加された描画命令であるColor(A行)とLabel
が元々持っていた描画命令が消されていた事が分かります。