7月
8月
9月
10月
11月
12月
全2件 (2件中 1-2件目)
1
フローをまとめておきます。1. 起動__main__ から KeibaApp.__init__() が呼ばれます。変数の初期化、pyxel.init()、そして pyxel.run(update, draw) でメインループを開始します。2. index.json の取得 (scene = LOADING)_start_index_fetch() が pyodide.http.pyfetch で index.json の非同期取得を開始します。取得中は update() が毎フレーム _upd_loading() を呼び、完了を待ちます。完了すると _on_index_loaded() でレースファイルのリストを作り、scene = FILE に切り替わります。3. レース選択画面 (scene = FILE)_drw_file() がファイル一覧を描画します。ユーザーがレースを選んで決定すると _open_file() が呼ばれ、対象の race JSON の非同期取得を開始します。4. race JSON の取得待ちupdate() の冒頭で _race_loader がロード中かどうかを確認し、中なら _poll_race_loader() を呼んで完了を待ちます。完了すると parse_races_from_json() でデータを変換し、scene = LIST に切り替わります。5. 出走馬一覧 (scene = LIST)_drw_list() が馬の一覧を描画します。Tab でソート切替、Enter または クリックで馬を選ぶと scene = DETAIL に進みます。ESC で FILE に戻ります。6. 詳細画面 (scene = DETAIL)_drw_detail() が選んだ馬の詳細情報を表示します。スクロールで全情報を確認でき、ESC で LIST に戻ります。非同期処理のポイントWeb版 (Pyodide) ではネットワーク通信を同期で止められないため、asyncio.ensure_future() で取得を「投げっぱなし」にして、Pyxel の 30fps ループの中で毎フレーム完了を確認するポーリング方式を取っています。これが今回の修正の核心です。
May 31, 2026
コメント(0)
競馬予想ビューア出来ました。ダービーと目黒記念の予想を掲載しましたPyxel Web版(GitHub Pages) デバッグ記録概要Pyxelで作成した競馬予想ビューアをGitHub Pages上で動作させる際、index.jsonは取得できるものの、レースデータ(json)の読み込みに失敗する問題が発生した。また、ローカル版とWeb版でファイル読み込み方式が異なるため、それぞれ別の問題が存在していた。問題1 : index.jsonが取得できない症状起動時に「jsonが見つかりません」と表示される。原因Web版では os.walk() によるディレクトリ走査が利用できない。ローカル版では DATA フォルダを直接検索できるが、GitHub Pages上ではサーバー側のディレクトリ一覧取得機能が存在しないため、ファイル一覧を取得できなかった。解決DATA/index.json を作成し、利用可能な予想ファイル名一覧を格納する方式へ変更。例["260531_東京芝2400m_東京優駿_予想中.json","260531_東京芝2500m_目黒記念_予想中.json"]問題2 : Pyodide API変更症状cannot import name 'to_py' from pyodide.ffi原因Pyodideの新しいバージョンではfrom pyodide.ffi import to_pyが廃止されていた。解決js_obj.to_py()を使用する方式へ変更。問題3 : race.json取得失敗症状レース一覧は表示されるが、選択すると「読込中...」が一瞬表示された後、PythonError : pyodide.ffi.JsExceptionで失敗する。当初の実装JavaScriptのfetchを直接利用していた。promise = js.fetch(url)promise.then(create_proxy(on_response)).then(create_proxy(on_json)).catch(create_proxy(on_error))問題点Pyodide + Promise + Pyxel の updateループとの相性問題により、Promise解決後のコールバックが正常に実行されない場合があった。また、resp.json()↓JavaScript Object↓to_py()↓Python Objectという変換処理も不安定要素となっていた。最終解決方法Pyodide公式推奨の pyfetch を使用。import pyodide.httpimport asyncioasync def _do_fetch():response = await pyodide.http.pyfetch(url)text = await response.string()self.result = json.loads(text)self.state = self.STATE_DONEasyncio.ensure_future(_do_fetch())利点JavaScript Promiseを直接扱わない。JS Object → Python Object の変換が不要。JSON文字列として取得し、json.loads()でPython側のみで処理できる。Pyodideのイベントループと自然に統合されるため安定して動作する。問題4 : ローカル版のファイル読み込み症状urlopen errorが発生する。原因ローカルファイルをurllib.request.urlopen()で読み込もうとしていた。urlopen() はURL向けであり、C:\DATA\race.jsonのような通常ファイルパスには適していない。解決ローカル版は通常のファイル読み込みへ変更。with open(path, "r", encoding="utf-8") as f:data = json.load(f)最終構成Web版pyodide.http.pyfetch()↓response.string()↓json.loads()ローカル版open()↓json.load()今回の教訓問題の本質はGitHub PagesやJSONファイル配置ではなく、「Pyodide + Promise + Pyxel」の非同期処理の組み合わせだった。Pyodide環境ではjs.fetch()よりもpyodide.http.pyfetch()を利用し、Python側で async/await を用いて処理する方が圧倒的に安定する。今後PyxelのWebアプリを作成する際は、「pyfetch + asyncio + json.loads」を標準構成とする。
May 31, 2026
コメント(0)
全2件 (2件中 1-2件目)
1