🐈‍⬛

Python + Kivy で作ってみた【Ⅴ】

2023/06/28に公開

ファイル選択

任意のPDFファイルを表示できなければ、ビューワーとはいえないな
確かに、基本機能だな💦

ヘッダー部にファイル選択のボタンを配置する

Button:
    id:                 filechoose_btn
    text:               '変更'
    color:              [ 0, 0, 0, 1 ]
    background_color:   [ 0.3, 0.9, 0.7, 1 ]
    background_normal:  ''
    on_press:           viewer.change()

ヘッダー部にボタンを配置する
ViewAreaWidgetに「change」というメソッドを新設し
ボタンがクリックされた時に呼ぶ

色を設定する時は、background_normalプロパティにブランクを設定する必要がある
これを忘れると、色が反映されない
kivyには何かと細々とした「お約束」が存在する…

FileChooser

kivyにはファイルを選択するモジュールとしてFileChooserがある
FileChooser
参照 : ( kivy API Reference )

これでは、決められたフォルダー内のファイルしか選択できない
\textcolor{red}{\textbf{不採用!}}

FileBrowser

しかたないので、Googl先生にお伺いを立てることにした…
すると、「FileBrowser」というご神託を得られた
しかし、kivy API Referenceではそんなものはない!と叱られる🤔

よくよく調べてみると、FileBrowserはkivyのアドオンらしい
そのようなアドオンを集中管理しているのがkivy.gardenプロジェクトで
その中にFileBrowserがあった

FileBrowser
参照 : (FileBrowser’s documentation)

フォルダーの移動もできるし、ファイルのフィルタリングもできそうだ
FileBrowserを使ってみよう
早速、「pip install kivy_garden.filebrowser」でインストールした

ポップアップダイアログ

続いて、kivyのPopupを使ってFileBrowserをモーダル表示させる

class FileBrowseDlg() :

    def FileChoose( self, objSuccess, objCancel ) :
        browser = FileBrowser( cancel_string = '中止', select_string = '開く' )
        browser.multiselect = False
        browser.filters = [ '*.pdf' ]
        browser.bind( on_success = objSuccess, on_canceled = objCancel )

        self._popup = Popup( title = 'ファイル選択', content = browser, size_hint = ( 0.8, 0.8 ), auto_dismiss = True )
        self._popup.open()
    
    def CloseDialog( self ) :
        self._popup.dismiss()

FileBrowserダイアログを扱うクラスを定義する
ダイアログを表示するメソッド、FileChooseメソッド内で
FileBrowserの初期設定を行う

今回設定したのは次の三つ

  1. ボタンの名称
  2. ファイル選択は単一選択
  3. ファイルのフィルタリングは「*.pdf」

続いてFileBrowserダイアログをモーダル表示させるために
FileBrowserをPopupオブジェクトに乗せる
ダイアログの大きさはアプリケーションウインドウよりやや小さくして0.8倍
ダイアログ以外の場所をクリックして閉じないようにする

このFileBrowseDlgクラスのFileChooseメソッドを
ViewAreaWidgetに新設した「change」メソッド内で呼び出す

class ViewAreaBase( Widget ) :
    ...
    ...
    ...
    def change( self ) :
        self._filechoose = FileBrowseDlg()
        self._filechoose.FileChoose( self.select_file, self.cancel_choose )
        
    def select_file( self, fbw ) :
        if( fbw.filename != '' ) :
            di_texture = pdf_to_texture( fbw.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

            root_ids    = self.parent.parent.ids
            root_ids[ 'header' ].title_str = fbw.filename

        self._filechoose.CloseDialog()

    def cancel_choose( self, fbw ) :
        self._filechoose.CloseDialog()

FileChooseメソッドを呼ぶ時に「開くボタン」と「中止ボタン」がクリックされた時の
コールバック関数を指定する

「開くボタン」のコールバック関数を「select_file」メソッド、
「中止ボタン」のコールバック関数を「cancel_choose」メソッドとした

ファイル読込

FileBrowserダイアログで「開くボタン」をクリックすると
select_fileメソッドが呼ばれる
ファイルが選択されている場合は、引数の「fbw」オブジェクトの
filename」プロパティにファイル名がフルパスで格納されている

filename」プロパティのファイル名をPDF画像に変換するメソッドに渡す
後は、PDF画像の大きさ、位置をViewAreaWidgetの独自プロパティに渡す

filename」プロパティのファイル名はヘッダーに表示する
(リテラルのままだった定数型にしないと…💦)

これで、PDFファイルを選んで表示するPDFビューワーアプリらしくなった
次回は、付加機能を実装しよう…

Discussion