Start_python’s diary

ふたり暮らし

アラフィフ夫婦のフリーランスプラン

Python ファイル一覧にサムネイルを付ける(Kivy Image画像で一覧を作る)

f:id:Start_python:20200107155653p:plain

はじめに

前回の続きです。フォルダ内のファイル名一覧にサムネイルを表示しました。

 

プログラムのコード

# フル画面を解除して画面の幅と高さを設定
from kivy.config import Config
Config.set('graphics', 'fullscreen', 0)
Config.set('graphics', 'width', 320)
Config.set('graphics', 'height', 568)
Config.set('graphics', 'resizable', 1)

import os
import glob
import cv2
import numpy as np
from PIL import Image

from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.gridlayout import GridLayout
from kivy.uix.button import Label
from kivy.uix.button import Button
from kivy.uix.image import Image as Img
from kivy.graphics.texture import Texture

from kivy.core.text import LabelBase, DEFAULT_FONT
from kivy.resources import resource_add_path

resource_add_path('c:/Windows/Fonts')
LabelBase.register(DEFAULT_FONT, 'msgothic.ttc')


class CustomLayout(BoxLayout):
    pass


class MainScreen(BoxLayout):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)

        files = glob.glob('./data/*.gif')
        for file in files:
            gif = cv2.VideoCapture(file)
            is_success, img = gif.read()

            image = np.array(img)
            image = image[:, :, [2, 1, 0]]    # BGR <-> RGB
            image = Image.fromarray(image)

            texture = Texture.create(size=image.size) 
            texture.blit_buffer(image.tobytes())
            texture.flip_vertical()

            self.ids.sv.add_widget(Img(texture = texture, size_hint_x=None))
            btn = Button(text=os.path.basename(file), on_release=self.on_command,
                    size_hint_y=None, height=80, color=(0,0,0,1), background_color=(1,1,1,0.1))
            self.ids.sv.add_widget(btn)

    def on_command(self,btn):
        print(btn.text)


class TestApp(App):
    def build(self):
        self.title = 'テスト'
        return MainScreen()

if __name__ == '__main__':
    TestApp().run()

kvファイル(test.kv)

<MainScreen>:
    CustomLayout:
        orientation: "vertical"

        BoxLayout:
            orientation: "vertical"

            BoxLayout:
                Button:
                    size_hint_x: 0.2
                    text: "1"
                Label:
                    size_hint_x: 0.6
                    text: "today"
                    color: 0, 0, 0, 1
                Button:
                    size_hint_x: 0.2
                    text: "2"

            ScrollView:
                size_hint_y: 10
                GridLayout:
                    id: sv
                    cols: 2
                    size_hint_y: None
                    orientation: "vertical"
                    height: self.minimum_height

            BoxLayout:
                Button:
                    text: "3"
                Button:
                    text: "4"
                Button:
                    text: "5"

<CustomLayout>:
    canvas.before:
        Color:
            rgba: 1, 1, 1, 1
        Rectangle:
            pos: self.pos
            size: self.size

 

解説

画像の表示

ここは苦労しました。ImageモジュールのTextureメソッドを使って画像表示するのですが、「from PIL import Image」と「from kivy.uix.image import Image」で両方にImageを使ってしまうためエラーになります。

from kivy.uix.image import Image as Img

にすることで解決しました。KivyのImageを呼び出すときは「Img」を使います。

GridLayout:

「cols: 2」で2列に設定して左にサムネ、右にファイル名を表示します。

self.ids.sv.add_widget(Img(texture = texture, size_hint_x=None))

「size_hint_x=None」にすることで「width=100」になるような気がします。

btn = Button(text=os.path.basename(file), on_release=self.on_command,
        size_hint_y=None, height=80, color=(0,0,0,1), background_color=(1,1,1,0.1))
self.ids.sv.add_widget(btn)

「size_hint_y=None, height=80」で高さ設定です。「background_color=(1,1,1,0.1)」で少し色を付けて境界線がわかるようにしました。
on_release=self.on_command」でボタンを押した(離した)ときの処理を呼び出します。ここでも苦労しました。

def on_command(self):」にしたらエラーになりました。

TypeError: on_command() takes 1 positional argument but 2 were given

引数が2つ必要みたいなので「def on_command(self,a):」に変更して「print(a)」で確認したところ、<kivy.uix.button.Button object at 0x0000020E2F16C4A8>と表示されました。kivy.uix.button.Buttonのオブジェクトとは何かわからず悩みました。

「print(a.text)」で確認してみるとファイル名が表示されました。

 

まとめ

サムネが表示できるようになり、ボタンを押すとファイル名を呼び出せるようになりました。

次回はGIFファイルを表示して再生したりカットしたりできるようにしたいと思います。

 

 

保存ファイル

lesson78.py

test.kv

 

 

文責:Luke