Python + Kivy で作ってみた【Ⅰ】
UI構成
お試しだから凝ってもしょうがないので…
- ヘッダー
- 表示部
- フッター
の単純構成
それぞれにkivyのwidgetクラスを割りあて、
全体のkivyのwidgetクラス(CtrlPanelWidget)にぶら下げる
CtrlPanelWidget
├─HeaderWidget
├─ViewAreaWidget
└─FooterWidget
ヘッダーにはファイル名を表示、フッターには終了ボタンを置く予定
なお、各部の高さは1:8:1とした
PDFの表示
PDFを表示するにはどうするか…
PDF ⇒ Imageに変換できれば話は早いが、できるのか?
Googl先生にお伺いを立ててみると
Pythonでpdf2imageを使用しPDFファイルを画像に変換する
というブログ記事のご神託をいただいた
popplerというライブラリーをWindowsにインストールしないといけないのは気になるが、記事を参考にしてPDF変換モジュールを作っていく
from kivy.graphics.texture import Texture
from pypdf import PdfReader
from pdf2image.pdf2image import convert_from_path
def pdf_to_texture( filepath, p_dpi = 200 ) :
with open( filepath, 'rb' ) as f :
objPdf = PdfReader( f )
countPdf = len( objPdf.pages )
print( countPdf )
pages = convert_from_path( filepath, last_page=1, poppler_path='C:\\poppler\\bin', dpi=p_dpi )
img = pages[ 0 ]
texture = Texture.create( size=img.size )
texture.blit_buffer( img.tobytes(), colorfmt='rgb' )
texture.flip_vertical()
return texture
引数はPDFファイル名と解像度(これは後付け)
返値はkivy.graphics.textureオブジェクトとした
当初の予定ではkivyのImageに表示させるつもりだったが、
Widgetのcanvasのtextureに設定しても画像が表示できるため、
kivy.graphics.textureオブジェクトを返すようにした
モジュール中の「texture.flip_vertical」は、
画像(texture)を上下反転させている
これは、kivyの座標系が左下が原点となっているため
textureは上下反対の状態で生成されてしまうから
ひとまず完成とするが、popplerはなんとかしたい…
Widgetへpythonから画像設定
ViewAreaWidgetにPDFの画像を表示させる
まず、UIを記述するkvファイルには
ViewAreaWidget:
canvas:
Rectangle:
texture: self.image_texture
と記述する
それに対応するpythonのコード部は
from lib.library import pdf_to_texture
class ViewAreaWidget( Widget ) :
image_texture = ObjectProperty( None )
def on_kv_post( self, base_widget ) :
self.image_texture = pdf_to_texture( self.filename )
と記述する
ViewAreaWidgetにimage_textureというオブジェクトプロパティを設定する
on_kv_postはViewAreaWidgetがインスタンス化されたタイミングで呼ばれる
そのタイミングでPDFの画像(kivy.graphics.textureオブジェクト)を設定する
これで実行すると、ViewAreaWidget内に収まるようにPDFが表示される
表示領域より大きければ縮小、反対に小さければそのままの大きさとなる
常にそのままの大きさで表示させるにはどうしたらよいか…
ViewAreaWidgetのcanvasのRectangleの大きさを
textureの大きさに設定すればいいのではないか?
と考えて、次のように変更した
ViewAreaWidget:
canvas:
Rectangle:
texture: self.image_texture
size: self.image_width, self.image_height
from lib.library import pdf_to_texture
class ViewAreaWidget( Widget ) :
image_texture = ObjectProperty( None )
image_width = NumericProperty( 0 )
image_height = NumericProperty( 0 )
def on_kv_post( self, base_widget ) :
di_texture = pdf_to_texture( self.filename )
self.image_width = di_texture.width
self.image_height = di_texture.height
self.image_texture = di_texture
image_width、image_heightという画像サイズのプロパティを追加した
これで実行すると、そのままの大きさで表示されるようにはなった
しかし、
- 位置が正しくない
- 画像がヘッダー部にはみ出して表示される
という問題が生じた
1の問題は位置を指定すれば良さそうだが、2の問題は見当がつかない
しばらく考えることにするので、今回はここまで
Discussion