paloma blog

NWエンジニアやってます。主に自宅環境のお遊びを書きます。Pythonもちょっと。タイトルは好きなカクテルから。

python kivyで変数を別のScreenへ渡す

以前作成したAndroidアプリ作成の続きで残りの機能作成をします。
get機能は一旦完成しましたので続いてpost機能を作ります。

post機能は映画タイトルを入力してOMDB APIへ投げる→取得した情報を成形してツイッターAPIに投げるという手順になります。
入力と出力を同スクリーンでやるよりはページを分けたほうが見た目も処理もわかりやすく、
やはり1画面で済ませるより画面遷移させたいので別のクラスへ戻り値を渡す方法を探しました。

厳密には渡すという実装ではありませんが一応思う形に出来ました。

アプリ作成シリーズ

pythonでAndroidの野良アプリを作りたい1 kivyで作成編 - paloma blog

pythonでAndroidの野良アプリを作りたい2 buildozerでコンパイル編 - paloma blog

pythonでAndroidの野良アプリを作りたい3 スマホにインストール編 - paloma blog

やりたいこと

とりあえず

  1. 映画タイトルを入力する
  2. 入力した情報を別のページで出力する

という処理を実装したいと思います。

①で入力した値をスクリーンが移ると同時に関数に読ませて次のスクリーン②にアウトプットするというものです。

以前のget機能作成の時はどうしてもできず1画面で収まるよう修正しましたが今回やっとできました。

方法

ちゃんと探したら色々方法はあったのですが、この辺の動画、記事が自分のコードにマッチしました。

www.youtube.com

Change a variable from another class (KIVY) - CodeProject

Kivy: Use .get_screen() to Access Objects from Other Screens | by Rachela | Nerd For Tech | Medium

自分の例でいうと①のスクリーンの処理内で②のスクリーンの値に代入してしまうという方法で出来ました。

ScreenManagerのAttributeでスクリーン名を呼び出せる関数があるので別のスクリーン指定→id指定という方法で格納できました。
これはScreenManagerの仕様を読んでおかないとわからなかったなあ。

無理にreturnで値を返して、インスタンス化して呼び出して…としなくてもシンプルにこんな方法でいいんですね。

コード

今回の対処を抜粋したコードはこちらです。

  • main.py
class Postmenu(Screen):

    def searchtitle(self):
        t = self.ids.movietitle.text
        self.title = '+'.join(t.split())

        # refer to another class ここで別スクリーンのIDに格納する
        self.manager.get_screen('post_second').ids.infomation.text = self.title

    pass
  • my.kv
<Postmenu>:
    name: 'post'

…(略)
            TextInput:
                id: movietitle
                size_hint: .5, .5
                multiline: False
…(略)

            TextInput:
                id: pubyear
                size_hint: .5, .5
                multiline: False
        Button:
            text: 'submit'
            size_hint: .5, .5
            pos_hint: {'center_x': 0.5}
            on_press:  # ホタンを押すと関数事項+別ページへ移動
                root.searchtitle()
                app.root.current = 'post_second'
   
<Postmenu_detail>:
    name: 'post_second'

    BoxLayout:
…(略)
        Label: # このIDのラベルの値として格納されている
            id: infomation
            text: 'Title'
            size_hint: .5, .5
...(略)    

練習

方法がわかったところで入力したタイトルを次のスクリーンに写せるでしょうか。

入力画面。(最近GNOMEのテーマを変えました)

出力画面。

OK。

公開年用の引数処理追加

yearも取れる様にしてAPIのリクエストフォーマットにしました。

  • main.py
class Postmenu(Screen):

    def searchtitle(self):
        t = self.ids.movietitle.text
        self.title = '+'.join(t.split())

        def createrequest(args_title):
            self.getinfo = ''.join([url, '?apikey=', KEY, '&t=', args_title])

            if self.ids.pubyear != None:
                self.getinfo += '&y={}'.format(self.ids.pubyear.text)

            return self.getinfo

        self.gettitle = createrequest(self.title)
        self.posttitle = src.getinfo.getmovieinfo(self.gettitle)

        # refer to another class
        self.manager.get_screen('post_second').ids.infomation.text = self.gettitle

位置の設定が悪かったのかちょっと切れてしまいましたがOMDB APIのリクエストフォーマットになってます。

あとは取得したタイトルにTwitter APIで投稿する処理を挟めば良さそうですね。
ちなみに執筆時に気づきましたが↑の公開年の値をミスっていて、上記のリクエストを投げるとマッチ無しで返ってきます。


というわけでこの連休で作りきりました。
とりあえずタイトルを入れるとシェル版と同じように成形して出力してくれます。
(pulp fictionは1994公開の映画でした。)

kivyはデフォルトだと日本語化対応していないので日本語の出力は化けてしまいますが、格納されている変数は日本語のままなのでこのまま投稿しても大丈夫なはずです。
自分しか使わないツールなのでこのままでもいいかな。

機能はほぼ完成出来たので後はレイアウトをスマホ用に、もう少しいい感じにチューニングしようと思います。

リポジトリ

GitHub - masashi69/movietweetapp_for_android