🕌
discord.pyでのui系のあれこれ
こんにちは、最近とあるところでの質問でなんか多いなって思った質問がいくつかあるので、ここでまとめて書いときます。
基本
basic.py
import discord
class BasicView(discord.ui.View):
@discord.ui.button(label="Click!")
async def click(self, interaction: discord.Interaction, button: discord.Button) -> None:
await interaction.response.send_message("Clicked")
@tree.command()
async def button(interaction: discord.Interaction) -> None:
await interaction.response.send_message(view=BasicView())
botが落ちて起動した後でも、クリックして反応するようにする
down-click.py
class NotTimeoutView(discord.ui.View):
@discord.ui.button(label="Click!", custom_id="sample")
async def click(self, interaction: discord.Interaction, button: discord.Button) -> None:
await interaction.response.send_message("Clicked")
# タイムアウトを設定しないように`None`を渡す。そして事前にインスタンスを作っとく
view = NotTimeoutView(timeout=None)
# 生成したインスタンスをbotに登録する。
# そうすることで落ちる前に作られたボタン入りのメッセージが実行できる
bot.add_view(view)
@tree.command()
async def click_two(interaction: discord.Interaction) -> None:
# 生成されたviewを繰り返し使うことで、同じボタンであることを認識するようにできる。
await interaction.response.send_message(view=view)
custom_id
を指定しないと動きません。
ボタンに着色する
デコレーターであるdiscord.ui.button
のstyle
引数にスタイルを指定すれば、着色できます。以下はそのサンプルコードです。
button-color.py
class ColorView(discord.ui.View):
# 緑色のボタン
@discord.ui.button(label="green", style=discord.ButtonStyle.green)
async def green(self, interaction: discord.Interaction, button: discord.Button) -> None:
await interaction.response.send_message("あなたは緑色のボタンを押しました")
# 赤色のボタン
@discord.ui.button(label="red", style=discord.ButtonStyle.red)
async def red(self, interaction: discord.Interaction, button: discord.Button) -> None:
await interaction.response.send_message("赤色のボタンを押しました。")
ボタンをリンクにする
ボタンをクリックするとどこかのページを飛ばすようにすることができます。この場合デコレーターを使って作ることはできませんので書き方が違います。見ればおそらくわかるので以下がサンプルコードです。
link.py
@tree.command()
async def search(interaction: discord.Interaction) -> None:
view = discord.ui.View()
# Googleのボタンを追加
view.add_item(discord.ui.Button(label="Google", url="https://google.com"))
# Bingのボタンを追加
view.add_item(discord.ui.Button(label="Bing", url="https://www.bing.com"))
# Yahoo japanのボタンを追加
view.add_item(discord.ui.Button(label="Yahoo japan!", url="https://www.yahoo.co.jp/"))
await interaction.response.send_message(view=view)
Selectの基本
選択できます。
basic.py
import discord
class Dropdown(discord.ui.Select):
def __init__(self):
# オプション、ここでは赤、緑、青を選べるようになっている。
options = [
discord.SelectOption(label='赤', description='赤色です。'),
discord.SelectOption(label='青', description='青色です。'),
discord.SelectOption(label='緑', description='緑色'),
]
# placeholderはタイトルみたいなもの、min_valuesは最低限選択しないといけない数、max_valuesは最大で何個選択できる数
super().__init__(placeholder='あなたの好きな色はなんですか?', min_values=1, max_values=1, options=options)
async def callback(self, interaction: discord.Interaction):
# ここで返答を返す。
await interaction.response.send_message(f'あなたが好きな色は{self.values[0]}なんですね!"')
class BasicView(discord.ui.View):
def __init__(self):
super().__init__()
# viewにセレクトを追加
self.add_item(BasicSelect())
@tree.command()
async def favorite_color(interaction: discord.Interaction) -> None:
await interaction.response.send_message(view=BasicView())
Modalの基本
Modalはフォームみたいなものだと思ってくださればいいです。以下が基本のコードです。
basic.py
import discord
# タイトルで自己紹介と書かれたモーダルを作成
class Modal(discord.ui.Modal, title="自己紹介"):
# 名前を入力するための欄を作る
name = discord.ui.TextInput(label="お名前")
# フォームのデータを受け取る
async def on_submit(self, interaction: discord.Interaction) -> None:
# 入力された名前を送信
await interaction.response.send_message(self.name.value)
動的なモーダル
ラベルとかを実行時に変更するコードです。以下がサンプルコードです。
dynamic_modal.py
class Modal(discord.ui.Modal, title="自己紹介"):
def __init__(self, default_name: str):
super().__init__()
self.name = discord.ui.TextInput(label="お名前", default=default_name)
self.add_item(self.name)
# 以下基本と同じ
async def on_submit(self, interaction: discord.Interaction) -> None:
...
@tree.command()
async def introduce(interaction: discord.Interaction, default_name: str = "名無し") -> None:
await interaction.response.send_modal(Modal(default_name))
最後に
よく質問されるところを中心にサンプルを書いてみましたが、いかがでしょうか?
たまにこれどうやるんだろうと疑問に持った時も何回もあったので一部僕がわからなかったところも載せてます。
では、さよなら。👋
Discussion