Python 一部のレイアウトだけ変更する(kivy 画面遷移)
はじめに
前回の続きでGIFファイルを表示しようと思いましたが、先にレイアウトの切り替えが必要になりました。画面のスライドで使ったCarouselを利用します。
プログラムのコード
# フル画面を解除して画面の幅と高さを設定 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, width=80)) 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): self.ids.label1.text = btn.text self.ids.carousel.load_next() def on_btn1(self): self.ids.carousel.load_previous() def on_btn2(self): self.ids.carousel.load_next() 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: "<" on_release: root.on_btn1() Label: id: label1 size_hint_x: 0.6 text: "today" color: 0, 0, 0, 1 Button: size_hint_x: 0.2 text: ">" on_release: root.on_btn2() Carousel: id: carousel size_hint_y: 10 scroll_timeout: 0 anim_move_duration: 0.1 ScrollView: GridLayout: id: sv cols: 2 size_hint_y: None orientation: "vertical" height: self.minimum_height BoxLayout: Button: text: "test" 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
解説
「Carousel」の親ウェジットに「ScrollView」と「BoxLayout」の子ウェジットを作ります。これで2つのレイアウトをスライドで移動できるようになります。
scroll_timeout: 0
スライド可能な時間(ミリ秒)を「0」にすることでスライドでは移動できなくします。スライドしたい場合は省略するとデフォルトで「200ミリ秒」です。
anim_move_duration: 0.1
画面が切り替わるのが遅く感じたので「0.1秒」にしました。「0」にすると一瞬(アニメーションなし)で画面が変わります。省略するとデフォルトで「0.5秒」です。
self.ids.carousel.load_next()
次のスライドへ移動します。
self.ids.carousel.load_previous()
前のスライドへ移動します。
まとめ
いろいろ調べましたが「ScreenManager」や「clear_widgets、add_widget」を利用するやり方は一部レイアウトを切り替えるにはややこしく感じて正直あきらめました。
おそらく「Carousel」を利用するのが一番簡単な気がします。
なにが正解かはまだわかりませんが決められたパーツ(部品)を使って完成させるのはパズルのようで面白いです。
次回は選択したGIFファイルを再生させてみたいと思います。
保存ファイル
lesson79.py
test.kv
文責:Luke