Python + Kivy で作ってみた【Ⅱ】
canvasの謎
ヘッダーに画像がはみ出して表示される問題を考えていて
canvasの認識が違うのではないかと思い始めた
なぜかというと、画像の表示位置をを指定できるようにプロパティを追加して
表示位置をいろいろと設定してみると、フッターにはみ出して表示されることがない
widgetの範囲だけcanvasの内容が見えるものだと考えていたが、
どうやら違うようだ⚡
各widgetのcanvasはwindow全体が見える範囲となっている
ただし、widgetの階層構造に従って各widgetのcanvasの見える範囲が変わる
今、widgetの階層構造は下からヘッダー、表示部、フッターの順となっている
そのため
- ヘッダーで指定したcanvasはヘッダーの範囲
- 表示部で指定したcanvasはヘッダーと表示部の範囲
- フッターで指定したcanvasはヘッダー、表示部、フッターの範囲
が見えることになる
ただし、
階層構造変更
widgetの階層構造を次のように変更した
- ヘッダー
- 表示部
- フッター
⬇️ - 表示部
- ヘッダー
- フッター
kvファイル変更
<CtrlPanelWidget>:
FloatLayout:
ViewAreaWidget:
size_hint: None, None
size: self.parent.width, self.parent.height * 8 / 10
x: 0
y: self.parent.height / 10
canvas:
Rectangle:
texture: self.image_texture
size: self.image_width, self.image_height
pos: self.to_parent( self.image_x, self.image_y, relative = True )
HeaderWidget:
size_hint: None, None
size: self.parent.width, self.parent.height / 10
x: 0
y: self.parent.height * 9 / 10
canvas.before:
Color:
rgb: [ 1, 1, 1 ]
Rectangle:
size: self.size
pos: self.pos
FooterWidget:
size_hint: None, None
size: self.parent.width, self.parent.height / 10
x: 0
y: 0
canvas.before:
Color:
rgb: [ 1, 1, 1 ]
Rectangle:
size: self.size
pos: self.pos
階層構造の順序は、kvファイルの記述順となる
それ故に、ViewAreaWidget、HeaderWidget、FooterWidgetと記述すると
表示部の下にヘッダーが表示されてしまう
そこで、CtrlPanelWidget内を任意の位置に配置できるFloatLayoutにする
そして、ViewAreaWidget、HeaderWidget、FooterWidget各widgetの
x,yプロパティを設定して表示位置を指定する(座標はwindow左下が原点)
なお、widgetのサイズを指定する場合は、
size_hint: None, None
を必ず記述しないといけない
また、HeaderWidget、FooterWidgetのcanvasは
各widgetの位置とサイズ部分を忘れずにベタ塗りする
ViewAreaWidgetのcanvasにはPDF画像表示の仕込みを行う
表示位置は便宜上ViewArewidgetの左下を原点として考える
一方、canvasはwindowの左下が原点となっている
そのため、PDF画像を描画するRectangleのposに
座標を変換する「to_parent」メソッドを使っている
pythonコード部変更
class ViewArea( Widget ) :
image_texture = ObjectProperty( None )
image_x = NumericProperty( 0 )
image_y = NumericProperty( 0 )
image_width = NumericProperty( 0 )
image_height = NumericProperty( 0 )
def on_kv_post( self, base_widget ) :
di_texture = pdf_to_texture( self.filename )
self.image_x = 0
self.image_y = self.height - di_texture.height
self.image_width = di_texture.width
self.image_height = di_texture.height
self.image_texture = di_texture
新たに表示位置を指定するimage_x、image_yプロパティを追加する
image_yには、PDF画像をその高さ分下へ動かしViewAreaWidgetの高さ分戻す
そんなイメージで値を設定すれば、左上から表示されるはず?
これで実行してみると…
PDF画像の大きさそのままで、表示部の左上から表示されるようになった
∩(´∀`)∩
次回は、マウスドラッグでPDF画像の表示位置を変えてみよう
Discussion