Skip to content

基本を超えて:Streamlit ボタン完全ガイド

Updated on

Streamlit は Python スクリプトをインタラクティブなアプリに簡単に変換でき、ボタンはユーザーが最初に期待する操作です。st.button ウィジェットはミニマルに見えますが、シンプルなトグルから複雑なマルチステップ処理まで多彩なワークフローを実現できます。本ガイドでは最新の API を整理し、よくある誤解を解消しつつ、信頼できるボタン体験を構築するための実践的なパターンを紹介します。

Streamlit プロジェクトにすぐ使えるビジュアル分析コンポーネントをお探しですか?

PyGWalker (opens in a new tab) は Tableau ライクな探索 UI を Streamlit アプリに直接埋め込めます。実際の動きを知りたい方は PyGWalker でデータを探索する方法 (opens in a new tab)統合ガイド をチェックしてください。

st.button を理解する

クイックスタート

st.button はクリック可能な要素を描画し、クリック直後のスクリプト実行中に True を返します。返されるブール値だけでシンプルなフローは十分制御できます。

import streamlit as st
 
if st.button("あいさつする"):
    st.write("Streamlit こんにちは!")

Streamlit はウィジェットが変化するたびにスクリプト全体を再実行します。この仕組みを踏まえて、if ブロック内で行う処理は冪等になるようにするか、追加の状態でガードしましょう。

押さえておきたい主な引数

st.button には多くのカスタマイズ需要を満たすオプション引数があります。

  • key: 同じラベルのボタンを複数配置するときの一意な識別子。
  • help: ホバー時に表示されるツールチップ。
  • on_click: ボタンが押されたときに実行されるコールバック。
  • args / kwargs: コールバックに渡す位置引数・キーワード引数。
  • type: Streamlit テーマに合わせた "primary""secondary" のスタイルプリセット。
  • disabled: ボタンの操作を無効化。
  • use_container_width: 親コンテナの幅いっぱいにボタンを広げる。
def refresh_data(verbose: bool = False, limit: int | None = None) -> None:
    st.session_state["last_result"] = load_data(limit=limit)
    if verbose:
        st.success("データを更新しました")
 
st.button(
    "データを更新",
    key="refresh",
    help="API から最新レコードを取得",
    type="primary",
    use_container_width=True,
    on_click=refresh_data,
    args=(True,),
    kwargs={"limit": 500},
)

戻り値を超えたインタラクション制御

コールバックとセッションステートの活用

コールバックは、Streamlit がウィジェット変更を収集した後に実行されます。ロジックのカプセル化や st.session_state の更新に最適です。

import datetime as dt
import streamlit as st
 
if "last_clicked" not in st.session_state:
    st.session_state.last_clicked = None
 
 
def mark_timestamp() -> None:
    st.session_state.last_clicked = dt.datetime.now(dt.timezone.utc)
 
st.button("タイムスタンプを記録", on_click=mark_timestamp, type="primary")
 
st.write("直近のクリック:", st.session_state.last_clicked or "まだありません")

コールバックを使えばトップレベルのスクリプトを宣言的に保ち、if の深いネストを避けつつ再実行間で状態を維持できます。

トグルのような挙動を作る

ボタンは押下状態を保持しませんが、セッションステートと組み合わせればトグル的なインタラクションを表現できます。

import streamlit as st
 
st.session_state.setdefault("show_advanced", False)
 
if st.button("詳細オプションを切り替え"):
    st.session_state.show_advanced = not st.session_state.show_advanced
 
if st.session_state.show_advanced:
    st.info("ここに詳細設定を表示します。")

持続的なオン/オフ制御が必要なら、st.checkboxst.toggle のようなウィジェットの方が状態を明確に伝えられます。

ボタンのレイアウトテクニック

Streamlit は記述順に要素を配置しますが、コンテナを使えばレイアウトを柔軟に制御できます。

col1, col2 = st.columns(2)
with col1:
    st.button("前へ", key="prev", type="secondary")
with col2:
    st.button("次へ", key="next", type="primary", use_container_width=True)
 
with st.sidebar:
    st.button("フィルターをリセット", key="reset")

st.container()st.expander() で関連アクションをまとめ、st.columns() で行内にボタンを並べれば、生の HTML に頼らなくても整列できます。

スタイリングと CSS 上書き

Streamlit は一貫性のためにスタイルの直接変更を制限していますが、次のような選択肢があります。

  • 強調したい場合は組み込みプリセットの type="primary"、レスポンシブにしたい場合は use_container_width=True を活用する。
  • グローバルなテーマ設定(.streamlit/config.toml)でデフォルト色を調整する。
  • カスタムスタイルが必要なら st.markdown(..., unsafe_allow_html=True) でスコープを限定した CSS を注入する。
import streamlit as st
 
st.markdown(
    """
    <style>
    .custom-button button {
        background: linear-gradient(135deg, #005bbb, #00bcd4);
        color: white;
        border: 0;
        padding: 0.6rem 1.5rem;
        border-radius: 999px;
        transition: transform 0.1s ease-in-out;
    }
    .custom-button button:hover {
        transform: translateY(-1px);
    }
    </style>
    """,
    unsafe_allow_html=True,
)
 
with st.container():
    st.markdown('<div class="custom-button">', unsafe_allow_html=True)
    st.button("グラデーションボタン", key="custom")
    st.markdown("</div>", unsafe_allow_html=True)

CSS の上書きは最小限に留めましょう。大きなインラインブロックは保守が難しく、Streamlit が内部クラス名を変更すると壊れる可能性があります。

実践的なパターン

  • 段階的な開示: st.session_state と組み合わせ、必要なときだけ追加入力や説明テキストを表示する。
  • データ処理ステップ: ファイルアップロードや認証トークンなどの前提条件が満たされるまでボタンを無効化(disabled=True)する。
  • ダウンロードフロー: ファイル配布が目的なら st.download_button を使い、アプリ内ロジックには st.button を用いる。

まとめ

ボタンは Streamlit アプリの多くのユーザージャーニーの要です。戻り値のブール値、コールバック API、st.session_state を組み合わせれば、リアクティブな設計を保ったまま複雑な挙動を調整できます。レイアウトの調整にはプリミティブを活用し、CSS には必要な場合だけ頼り、持続的な状態表示が必要なら別のウィジェットも検討しましょう。丁寧に設計されたボタンは Streamlit アプリを高速で直感的かつ信頼できるものにします。

よくある質問

Streamlit でボタンを作るには?

st.button("ラベル") を使います。クリックでトリガーされた実行中に True が返るので、対応する if ブロックにロジックを記述するか、on_click でコールバックを渡します。

Streamlit でボタンを配置するには?

st.columnsst.containerst.sidebarst.expander などのレイアウトプリミティブでウィジェットを包みます。これらのコンテナを使えば、HTML を直接書かなくても配置を制御できます。

Streamlit でラジオボタンを作るには?

st.radio(label, options) を利用します。排他的な選択肢を提示でき、選択された値は即座に返されて st.session_state に保存して後続処理に使えます。

Streamlit のデメリットは?

Streamlit のスクリプト再実行モデルは開発をシンプルにしますが、レイアウトの細かな制御、長時間のバックグラウンド処理、深いスタイルカスタマイズが必要なときは制約に感じることがあります。ただしエコシステムは急速に進化しており、新しいウィジェットやテーマ設定、セッションステートの補助機能がこれらのギャップを徐々に埋めています。