diff --git a/app.py b/app.py index 98fad8e..e07fd05 100644 --- a/app.py +++ b/app.py @@ -38,6 +38,7 @@ MIN_CONFIDENCE = 0 MAX_CONFIDENCE = 100 DEFAULT_CONFIDENCE = 50 +CONFIDENCE_OPTIONS = [0, 25, 50, 75, 100] # 5段階の確信度 # Image display settings DEFAULT_IMAGE_WIDTH = 600 # Default image width in pixels (デフォルトより少し縮小) @@ -383,11 +384,13 @@ min_value=0, max_value=len(images) - 1, value=st.session_state[frame_key], - key=f"frame_slider_{case_id}" + key=f"frame_slider_{case_id}", + on_change=lambda: None # Ensure state updates ) - # Update session state - st.session_state[frame_key] = frame_idx + # Update session state from slider + if frame_idx != st.session_state[frame_key]: + st.session_state[frame_key] = frame_idx # Display image with custom width try: @@ -422,48 +425,52 @@ container.caption("💡 ヒント: スライダーをクリックしてから矢印キー(←→)でフレーム移動、または◀▶ボタンをクリックできます") -def render_annotation_form(case_id: Union[int, float]) -> dict: +def render_annotation_form(container, case_id: Union[int, float]) -> dict: """ アノテーション入力フォームを表示。 Args: + container: Streamlit container to render in case_id: 現在の症例ID Returns: アノテーションデータの辞書 """ - st.sidebar.markdown("---") - st.sidebar.header("アノテーション") + container.markdown("---") + container.header("アノテーション") # Display annotator name (read-only) - st.sidebar.text(f"アノテーター: {st.session_state.annotator}") - st.sidebar.markdown("---") + container.text(f"アノテーター: {st.session_state.annotator}") + container.markdown("---") # Q1: Prediction - prediction = st.sidebar.radio( + prediction = container.radio( "Q1: 合併症予測 (No reflow/Slow flow)", PREDICTION_OPTIONS, key=f"prediction_{case_id}" ) - # Q2: Confidence - confidence = st.sidebar.slider( - "Q2: 確信度 (%)", - min_value=MIN_CONFIDENCE, - max_value=MAX_CONFIDENCE, - value=DEFAULT_CONFIDENCE, - key=f"confidence_{case_id}" + # Q2: Confidence (5段階、横並び) + container.markdown("**Q2: 確信度 (%)**") + confidence = container.radio( + "確信度を選択", + CONFIDENCE_OPTIONS, + index=2, # デフォルトは50% + format_func=lambda x: f"{x}%", + key=f"confidence_{case_id}", + label_visibility="collapsed", + horizontal=True # 横並びに表示 ) # Q3: Reasons - st.sidebar.markdown("**Q3: 判断根拠** (複数選択可)") + container.markdown("**Q3: 判断根拠** (複数選択可)") reasons = [] for reason in REASONS_OPTIONS: - if st.sidebar.checkbox(reason, key=f"reason_{case_id}_{reason}"): + if container.checkbox(reason, key=f"reason_{case_id}_{reason}"): reasons.append(reason) # Q4: Free text comment - comment = st.sidebar.text_area( + comment = container.text_area( "Q4: 自由記述欄", value="", key=f"comment_{case_id}", @@ -494,18 +501,19 @@ return True, "" -def save_and_advance(case_id: Union[int, float], annotation_data: dict): +def save_and_advance(container, case_id: Union[int, float], annotation_data: dict): """ アノテーションを保存して次の症例へ進む。 Args: + container: Streamlit container to display messages in case_id: 現在の症例ID annotation_data: アノテーションフィールドの辞書 """ is_valid, error_msg = validate_annotation(annotation_data) if not is_valid: - st.sidebar.error(error_msg) + container.error(error_msg) return try: @@ -527,7 +535,7 @@ st.session_state.annotated_cases.add(case_id) # Show success message - st.sidebar.success(f"✓ 症例 {case_id} を保存しました!") + container.success(f"✓ 症例 {case_id} を保存しました!") # Auto-advance to next unannotated case next_idx = st.session_state.current_case_idx + 1 @@ -544,10 +552,10 @@ st.session_state.current_case_idx = next_idx st.rerun() else: - st.sidebar.info("全症例のアノテーションが完了しました! 🎉") + container.info("全症例のアノテーションが完了しました! 🎉") except Exception as e: - st.sidebar.error(f"保存エラー: {e}") + container.error(f"保存エラー: {e}") def main(): @@ -591,15 +599,15 @@ # Right side: Navigation and Annotation with right_col: + # Navigation section render_case_selector(right_col) - st.markdown("---") - # Annotation form in sidebar (keeps original position) - annotation_data = render_annotation_form(current_case_id) + # Annotation form section + annotation_data = render_annotation_form(right_col, current_case_id) - # Save button - if st.sidebar.button("💾 保存して次へ", type="primary", use_container_width=True): - save_and_advance(current_case_id, annotation_data) + # Save button + if st.button("💾 保存して次へ", type="primary", use_container_width=True, key=f"save_{current_case_id}"): + save_and_advance(right_col, current_case_id, annotation_data) if __name__ == "__main__":