スポンサーリンク

【Streamlit】「クリップボードにコピー」ボタンを作成

記事内に広告が含まれています。

Streamlitでクリップボードにコピーボタンを実装するコードをメモしておきます。

コード

streamlit.components.v1.htmlを利用したHTMLとJavaScriptの組み合わせで実装します。

この方法では、ボタンをクリックすると特定のテキストをクリップボードにコピーするHTMLフォームをStreamlitアプリに埋め込みます。


import streamlit as st
from streamlit.components.v1 import html

# コピーするテキスト
text_to_copy = "Hello, World!"

# HTMLとJavaScriptを使用してクリップボードにコピーする機能を実装
copy_button_html = f"""
<button onclick='navigator.clipboard.writeText("{text_to_copy}")'>Copy to clipboard</button>
"""

# カラム作成
col1, col2 = st.columns(2)

with col1:
    # 最初のカラムにテキストを表示
    st.write("ここに表示するテキスト: Hello, World!")

with col2:
    # StreamlitにHTMLコンポーネントを追加
    html(copy_button_html, height=50)

HTMLの<button>要素を使用してボタンを作成し、onclickイベントでJavaScriptのnavigator.clipboard.writeText()メソッドを呼び出しています。

html(copy_button_html, height=50)のheightのデフォルト値が150のため、heightを指定しないと広めの空白が入っているように見えました。

このメソッドにコピーしたいテキストを渡すことで、ユーザーのクリップボードにそのテキストをコピーします。

JavaScriptエラー対応

サーバーで上記アプリを実行したたときに、クリップボードにコピーできない事象が発生しました。

調べると以下のJavaScriptのエラーが発生していました。

Uncaught TypeError: Cannot read properties of undefined (reading 'writeText')
    at HTMLButtonElement.<anonymous> (about:srcdoc:46:33)

エラーの原因は、https接続ではなくhttp接続していることでした。

navigator.clipboard.writeText が使用できないようです。

http接続で機能させたい場合は、以下のコードで実現できました。

copy_button_html = f"""
<textarea id="hiddenTextArea" style="opacity: 0; position: absolute; z-index: -1;">{text_to_copy}</textarea>
<button onclick="copyText()">Copy to clipboard</button>
<script>
function copyText() {{
  // テキストエリアを選択
  var copyTextArea = document.getElementById("hiddenTextArea");
  copyTextArea.focus();
  copyTextArea.select();
  try {{
    // テキストをクリップボードにコピー
    var successful = document.execCommand('copy');
    var msg = successful ? 'successful' : 'unsuccessful';
    console.log('Copying text command was ' + msg);
  }} catch (err) {{
    console.log('Oops, unable to copy', err);
  }}
}}
</script>
"""
スポンサーリンク
Python
著者SNS
タイトルとURLをコピーしました