Abstract
本記事では、日本語情報が皆無に近いPythonista3のuiモジュールの中でも特に情報が少ないui.ActivityIndicator
の使い方と注意点を共有します。本記事ではドキュメントに書かれている内容を日本語でサンプルコードと共に注意点を含めて紹介します。
Pythonista3とは
(任意のPythonやってる人向け説明, リンクはApp store)
Pythonista3とは、Pythonが動くスマホアプリです。それだけだと他の競合がいくつかありますが、Pythonista3はuiモジュールやsceneモジュールを提供しており、Pythonで比較的簡単にスマホで動くGUIアプリを作ることができるのです!!
1200円と少々高いですが、私は4,5年使っていますが価値はあったと十分に感じています。最近アプデがなくて不安です。
前提
- uiモジュール自体の説明は省略します
- pyuiは使いません。
scene.Scene
の上に画面を作成します。
- pyuiは使いません。
- Pythonのclass程度の文法を仮定します
- 環境
- iPhone 14
- iOS 16.0
- Pythonista3 version 3.3
Preliminary
インジケーターとは
もう少し一般には、「プログレスインジケーター」とか呼ばれる、処理中であることをユーザーに示すUIのことです。
プログレスインジケータの役割とは?デザイナーのためのインジケータ設計アイデア では、様々なインジケーターのデザイン例が採用例と同時に紹介されています。
Pythonista3 でアプリを作るモチベとしては、携帯で簡単にAPIを叩いてその結果を可視化できるとか、まぁ多岐に渡ります。
しかしやはりAPIを叩くにしろ、処理の待ち時間は長くなりがちですよね。個人的に使うにしろ、簡単に次の図のようなインジケーターは欲しいというニーズはありますよね(え…ありますよね...?)。
図: サーキュラーインジケータ, https://goodpatch.com/blog/progress-indicator より
気が利く Pythonista3 にはそのためのパーツui.ActivityIndicator
が準備されています。しかしこれ、めちゃくちゃ端的にしかドキュメントが書かれていないので、使い方が紹介されている日本語情報、多分ないです。
scene.Scene
Pythonista3 ではuiモジュール以外にも提供しているモジュールがあり、sceneモジュールもその一つです。
ゲームとかを作成する目的ですが、デフォルトでフルスクリーンに画面が描画されます。
今回例のコードはscene.Sceneの上に作成しますが、これはui.View
がモーダルウィンドウになるからです。完全に好みです。
またそもそも本質的な部分はui.View
でも変わらないので、安心して参考にしてください(?)。
↓ 昔書いたscene.Scene
のタッチ関係メソッドの実装例です。何かの参考に。
ui.in_background
uiなどのGUI表示部分の処理とは異なるスレッドで処理させるデコレーションです。多分。
ボタンのactionなどのコールバック関数にデコレーションをすると、別スレッドで処理が走ります。
よくわかりゃん!!の場合は、下記のようにアクションを行う部分に@でつけるとだけ覚えておけばよいです。
import ui
@ui.in_background
def btn_action(sender):
# 何か重い処理
pass
... # ui.Buttonのactionに`btn_action`を登録する
デコレータについて詳しくなりたい方は、Pythonのデコレータについてを参照してください。
ui.ActivityIndicator
のサンプルコードとその補足
-
ui.in_background
でデコレーションされた関数 / メソッドの中で、start()
する必要があります
import time
import ui
import scene
class MyApp(scene.Scene):
def setup(self):
self.background_color = 'orange'
# 画面中央の座標(x, y)
c = ui.get_screen_size() / 2
# ボタン
btn = ui.Button(title='Start', action=self.btn_tapped)
btn.center = (c[0], c[1] * 2/3)
btn.bounds = (0, 0, 50, 50)
self.view.add_subview(btn)
# ローダー
self.loader = ui.ActivityIndicator()
self.loader.center = c
self.view.add_subview(self.loader)
return super().setup()
@ui.in_background
def btn_tapped(self, sender: ui.Button):
# アニメーションスタート
self.loader.start()
# 何か長い処理
time.sleep(3)
# アニメーション終わり
self.loader.stop()
def main():
app = MyApp()
scene.run(app)
if __name__ == '__main__':
main()
コードを動かして、ボタンを押すと次の図のようなくるくる回るインジケーターが表示されます。
ui.ActivityIndicator
には設定できるデザインが3つあります。以下の3つのうち1つをstyle
属性にセットすることで変更できます。
-
ui.ACTIVITY_INDICATOR_STYLE_GRAY
- 灰色のスピナー。既定でこれ。サンプルコードもこれです。
-
ui.ACTIVITY_INDICATOR_STYLE_WHITE
- 白色のスピナー。
-
ui.ACTIVITY_INDICATOR_STYLE_WHITE_LARGE
- 大きな白色のスピナー。
class MyApp(scene.Scene):
def setup(self):
...
# ローダー
self.loader = ui.ActivityIndicator()
self.loader.center = c
self.loader.style = ui.ACTIVITY_INDICATOR_STYLE_WHITE # ← こんな感じで設定
self.view.add_subview(self.loader)
return super().setup()
次の図の二つがそれぞれ白色のスピナーと大きな白色のスピナーに対応します。
補足
あまり使うケースが想定できませんが、ui.ActivityIndicator
は常に表示させることもできます。
hides_when_stopped = False
とすると常に表示され(ただしアニメーションは動かない)、start()
が呼ばれるとアニメーションが動き、stop()
でアニメーションが止まります。
まとめ
本記事ではui.ActivityIndicator
のサンプルコードと注意点を紹介しました。
Pythonista3 は色々と便利ではありますが、日本語情報がないのが少しネックです。
日本人のPythonista3愛好家の集まるディスコがあるらしいので、そちらにアドバイスを求めていくのもよいでしょう。
そして何か知見が得られたら積極的に記事を書いてね!
というかこのインジケーター、カスタマイズできないのかな。カスタマイズ出来たら別記事書くかも。
Pythonista3でアプリを作る、誰かの役に立てば幸いです。