時刻の表示をすることができるようになったが、定期的に回すのはどうすればいいのか。
しらべると、time.sleep()を使っている例を見かける。
v = ui.load_view() label2=v['label2'] while True: label2.text=format(dt,'%H:%M:%S') time.sleep(1) v.present('sheet')
ループしているようだが、windowが表示されない。v.present('sheet')まで行かないせいだと思う。なので、presentより後にループを持ってきたらいいかなと思った。さらに調べていたら、並列処理する場合はThreadingを使うんだよって書いてあるものがあった。
import threading ut=time.time() dt=datetime.datetime.fromtimestamp(ut) def countdown( ut ): t=threading.Timer(1,countdown,args=[ut]) t.start() ut=time.time() dt=datetime.datetime.fromtimestamp(ut) print(ut) label2.text=format(dt,'%H:%M:%S') v = ui.load_view() label2=v['label2'] label2.text=format(dt,'%H:%M:%S') countdown(ut) v.present('sheet')
ここまで記載できるまで紆余曲折、何度もカットトライで至っているんだが、time.time()は、unixタイムスタンプを返すかんん数で、それを読める日時に変換して表示します。countdown( ut )という関数を定義して、引数をutにして、関数内で、自身を再帰呼び出ししてます。
t=threading.Timer(1,countdown,args=[ut])
数字の1は秒です。1秒毎に再帰呼び出し、で、argsは関数に渡す引数なのですが、ここに直接書くと
TypeError: countdown() argument after * must be an iterable, not float
という、反復可能じゃなきゃだめ、floatじゃないよ。と言ってる、意味不明。さらに調査の末、どうやら変数ではなくリストやタプルのようなものを指定するらしい。なので、[ ]がついている。
そして、最後のpresentの前にcountdown(ut)として呼び出す。これで、1秒おきに表示が更新できるようになった。
しかーし!。windowを閉じても止まらない。プログラムが止まらない。上の例ではconsoleにutがいつまでも表示される。MacでSpyderを使ってもやはり止まらないが、Ctrl-Cでブレークできる。しかし、iPadだと、Ctrl-Cが入れられない。だめだ!
これ以上情報がないので、自己解決するしかないと思い、Pythonista 導入した中にサンプルがあってそれをみてたらAnimateというフォルダの中にAnalogClock.pyってのがあり、割と短いソースだが、アナログ時計が表示され(しかも全画面)ずっと動いている。これだ!、やりたいのは。どうも、sceneというのを使うらしい。いきなり、classとか出てきて、アレですが。見様見真似でいけねーかな。
New...でファイルを作るとき、「Script with UI」を使ってたが、「Scene Game Animation」を選んで作成すると雛形が作られる。おー。検索をSceneでぐぐり始めたら、少しヒットするようなものがあった。(情報は少ないですが)
from scene import * import sound import random import math import time import datetime A = Action class MyScene (Scene): def setup(self): self.background_color = 'black' ut=time.time() dt=datetime.datetime.fromtimestamp(ut) dt2=datetime.datetime(year=2024,month=12,day=25) dd=dt2-dt label1=LabelNode(text=format(dd.days),font=('Arial-Black',60)) label1.color='white' label1.position=self.size/2 self.label2=LabelNode(text=format(dt,'%H:%M:%S'),parent=self) self.label2.position=self.size/2 + (0,30) self.add_child(label1) #self.add_child(label2) pass def did_change_size(self): pass def update(self): ut=time.time() dt=datetime.datetime.fromtimestamp(ut) self.label2.text=format(dt,'%H:%M:%S') pass def touch_began(self, touch): pass def touch_moved(self, touch): pass def touch_ended(self, touch): pass if __name__ == '__main__': run(MyScene(), show_fps=False)
期待通りに更新されて表示される。。。。覚えなきゃいけないことが、さらに増えてちょっと憂鬱だが、一つ溝は乗り越えたんだろうか。
https://se.miyabikno-jobs.com/pythonista-scene-font/
ここを参考したけど、関数名と変数名を同じにして記載されてて、思いっきり混乱してなかなか理解できんかった。
コメントを追加