diff --git a/app.py b/app.py
index 96172d0..a0d8e12 100644
--- a/app.py
+++ b/app.py
@@ -4,6 +4,7 @@
"""
import streamlit as st
+import streamlit.components.v1 as components
from PIL import Image
import os
from typing import Optional, Union
@@ -52,6 +53,58 @@
)
+def inject_keyboard_shortcuts():
+ """
+ JavaScriptを入れて,キーボードの左右矢印キーで画面上の「◀」「▶」ボタンをプログラム的にクリックさせる
+ """
+ js_code = """
+
+ """
+ components.html(js_code, height=0)
+
def open_folder_dialog(initial_dir: str = ".") -> str:
"""
Windows標準のフォルダ選択ダイアログを開き、選択されたパスを返す。
@@ -339,17 +392,28 @@
st.markdown("---")
# --- 画像拡大率 ---
- st.subheader("表示設定")
- zoom_percent = st.select_slider(
- "画像拡大率",
- options=[30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150],
- value=st.session_state.zoom_percent,
- format_func=lambda x: f"{x}%",
- key="global_zoom"
- )
- if zoom_percent != st.session_state.zoom_percent:
- st.session_state.zoom_percent = zoom_percent
- st.rerun()
+ zoom_levels = [30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150]
+ if st.session_state.zoom_percent not in zoom_levels:
+ st.session_state.zoom_percent = 80
+
+ current_idx = zoom_levels.index(st.session_state.zoom_percent)
+
+ col_z1, col_z2, col_z3 = st.columns([1, 2, 1])
+
+ with col_z1:
+ if st.button("-", key="zoom_out", use_container_width=True):
+ if current_idx > 0:
+ st.session_state.zoom_percent = zoom_levels[current_idx - 1]
+ st.rerun()
+
+ with col_z2:
+ st.markdown(f"
{st.session_state.zoom_percent} %
", unsafe_allow_html=True)
+
+ with col_z3:
+ if st.button("+", key="zoom_in", use_container_width=True):
+ if current_idx < len(zoom_levels) - 1:
+ st.session_state.zoom_percent = zoom_levels[current_idx + 1]
+ st.rerun()
def render_image_viewer(case_id: Union[int, float], container):
@@ -371,19 +435,28 @@
if frame_key not in st.session_state:
st.session_state[frame_key] = 0
+ # ボタンが押されたときに実行される関数
+ def change_frame(amount: int):
+ current = st.session_state[frame_key]
+ new_val = current + amount
+ if 0 <= new_val < len(images):
+ st.session_state[frame_key] = new_val
+ # st.rerun()
+
# Image slider
frame_idx = container.slider(
"フレーム番号",
min_value=0,
max_value=len(images) - 1,
value=st.session_state[frame_key],
- key=f"frame_slider_{case_id}",
- on_change=lambda: None # Ensure state updates
+ key=frame_key,
+ label_visibility="collapsed",
+ # on_change=lambda: None # Ensure state updates
)
# Update session state from slider
- if frame_idx != st.session_state[frame_key]:
- st.session_state[frame_key] = frame_idx
+ # if frame_idx != st.session_state[frame_key]:
+ # st.session_state[frame_key] = frame_idx
# Display image with custom width based on global zoom level
try:
@@ -403,19 +476,34 @@
with col1:
st.write("") # Spacer
with col2:
- if st.button("◀", key=f"prev_frame_{case_id}", disabled=frame_idx == 0, use_container_width=True):
- st.session_state[frame_key] = frame_idx - 1
- st.rerun()
+ st.button(
+ "◀",
+ key=f"prev_{case_id}",
+ on_click=change_frame,
+ args=(-1,),
+ )
+ # if st.button("◀", key=f"prev_{case_id}"):
+ # if frame_idx > 0:
+ # st.session_state[frame_key] = frame_idx - 1
+ # st.rerun()
with col3:
- if st.button("▶", key=f"next_frame_{case_id}", disabled=frame_idx >= len(images) - 1, use_container_width=True):
- st.session_state[frame_key] = frame_idx + 1
- st.rerun()
+ st.button(
+ "▶",
+ key=f"next_{case_id}",
+ on_click=change_frame,
+ args=(1,),
+ )
+ # if st.button("▶", key=f"next_{case_id}", disabled=frame_idx >= len(images) - 1):
+ # if frame_idx < len(images) - 1:
+ # st.session_state[frame_key] = frame_idx + 1
+ # st.rerun()
except Exception as e:
container.error(f"画像読み込みエラー: {e}")
# Keyboard navigation support (キーボードの矢印キーでフレーム移動)
container.caption("💡 ヒント: スライダーをクリックしてから矢印キー(←→)でフレーム移動、または◀▶ボタンをクリックできます")
+ inject_keyboard_shortcuts()
def render_annotation_form(container, case_id: Union[int, float]) -> dict: