1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

今更ながらdiscordpyのuiを解説したい!(buttonとかtextinputとか)

Last updated at Posted at 2024-08-24

はじめに

こんにちはnehatuです。
今回はあんまり解説してるサイトがないドキュメント読ってこと
discord pyのuiについて自分なりに解説していきます。ちょっとした応用例も最後にあるのでご参考になれば幸いです。

そもそもdiscord uiってに?

discord.uiは、Discord bot開発フレームワークであるdiscord.pyの拡張機能で、DiscordのインタラクティブなUI要素(ボタン、セレクトメニュー、モーダルなど)を簡単に作成するためのツールセットです。

従来のDiscord botは、テキストコマンドに反応して動作することが一般的でしたが、discord.uiを使用することで、より直感的なインターフェースをbotに実装できます。

軽く説明したということで主な要素を説明していきます。

botton

image.png

こんな感じに押すと特定のアクションを実行するボタン

image.png

では具体的にコードを使って解説していきます。


class TimedButtonView(discord.ui.View):
    def __init__(self):
        super().__init__(timeout=60)  # 60秒後にボタンを無効にする

    async def on_timeout(self):
        for child in self.children:
            child.disabled = True
        await self.message.edit(view=self)
        
    @discord.ui.button(label='Primary', style=discord.ButtonStyle.primary, custom_id='primary')
    async def primary_button(self, button, interaction):
        await interaction.response.send_message('青のボタン')

    @discord.ui.button(label='Secondary', style=discord.ButtonStyle.secondary, custom_id='secondary')
    async def secondary_button(self, button, interaction):
        await interaction.response.send_message('グレーのボタン')

    @discord.ui.button(label='Success', style=discord.ButtonStyle.success, custom_id='success')
    async def success_button(self, button, interaction):
        await interaction.response.send_message('緑のボタン')

    @discord.ui.button(label='Danger', style=discord.ButtonStyle.danger, custom_id='danger')
    async def danger_button(self, button, interaction):
        await interaction.response.send_message('赤のボタン')

    @discord.ui.button(label='Link', style=discord.ButtonStyle.link, url='https://qiita.com')
    async def link_button(self, button, interaction):
        pass  

@bot.command()
async def buttons(ctx):
    view = ButtonView()
    await ctx.send('5種類のボタンを試してみてください!', view=view)


上記のコードでは、5つの種類のボタンを表示します。それぞれのボタンには、custom_idという識別子が割り当てられており、ボタンが押されたときにどのボタンが押されたかを判別できます。

ボタンの種類

buttonは全部で6種類あります
それぞれ下のような指定をすれば色やスタイルをカスタマイズ可能。

種類
discord.ButtonStyle.primary (デフォルト): ぼやけた青色のボタン
discord.ButtonStyle.secondary: グレーのボタン
discord.ButtonStyle.success: 緑色のボタン
discord.ButtonStyle.danger: 赤色のボタン
discord.ButtonStyle.link: リンクのように表示されるボタン (URLが必要です)

ポイント

ボタンは最大5つまで、同じ行に並べることができます。
discord.ui.Viewクラスのtimeout引数を指定することで、ボタンが有効な時間を制限できます。

time
super().__init__(timeout=60)  # 60秒後にボタンを無効にする

textinput(mordal)

image.png
textinputユーザーからのテキスト入力をモーダルウィンドウで受け取るための UI コンポーネントです。
要はポップアップ形式で表示されるウィンドウ複雑な入力フォームや詳細な情報表示に便利と覚えておきましょう!

textinput
class MyModal(Modal):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.add_item(TextInput(label="名前", placeholder="例:太郎"))
        self.add_item(TextInput(label="年齢", placeholder="例:20", min_length=1, max_length=2, required=True))

    async def callback(self, interaction: discord.Interaction):
        name = self.children[0].value
        age = self.children[1].value
        await interaction.response.send_message(f"こんにちは、{name}さん! あなたは{age}歳ですね。")

@bot.tree.command(name="textinput", description="テスト")
async def textinput_command(interaction: discord.Interaction):
    await interaction.response.send_modal(MyModal(title="情報を入力してください"))

軽い特徴

各 TextInput には、こんな感じにラベル、プレースホルダー、最小/最大文字数、必須入力などのオプションを設定できます。
プレースホルダー、最小/最大文字数、必須入力などの設定により、入力内容を制御できます。
複数の TextInput を組み合わせることで、氏名、年齢、住所などの構造化された情報を一度に収集できます。(記入型のアンケートとかもこれでいいかも)

selectmenu

スクリーンショット 2024-08-24 203125.png

複数の選択肢から1つを選ばせるメニュー
選択肢に応じて異なるアクションを実行可能

select
class MyView(discord.ui.View):
    @discord.ui.select(
        placeholder="好きな果物を選んでください",
        min_values=1,
        max_values=3,
        options=[
            discord.SelectOption(label="りんご", description="赤くて美味しい"),
            discord.SelectOption(label="バナナ", description="黄色くて甘い"),
            discord.SelectOption(label="ぶどう", description="紫でジューシー"),
        ]
    )
    async def select_callback(self, interaction: discord.Interaction, select: discord.ui.Select):
        selected_fruits = [
            option.label for option in select.options if option.value in select.values
        ]
        await interaction.response.send_message(
            f"あなたが選んだ果物: {', '.join(selected_fruits)}"
        )

@bot.tree.command(name="select", description="テスト")
async def selectmenu_command(interaction: discord.Interaction):
    view = MyView()
    await interaction.response.send_message("果物を選んでください", view=view)

軽い特徴

最大25個の選択肢をリスト形式で表示できます。
max_values を設定することで、ユーザーが複数選択できるようにできます。

おまけappchoice

image.png
実装が簡単なので軽く説明して終わります。

appchooice
from discord import app_commands

@bot.tree.command(name="appchoice", description="テスト")
@app_commands.describe(fruit="好きな果物を選んでください")
@app_commands.choices(fruit=[
    app_commands.Choice(name="りんご", value="apple"),
    app_commands.Choice(name="バナナ", value="banana"),
    app_commands.Choice(name="ぶどう", value="grape"),
])
async def fruit_command(interaction: discord.Interaction, fruit: str):
    await interaction.response.send_message(f"あなたは {fruit} を選びました!")

軽い特徴

app_commands.Choice はスラッシュコマンドでのみ使用できます。
各選択肢には、表示名 (name) と値 (value) を設定します。
value は、コマンド処理時に使用される実際の値です。
選択肢は、コマンド登録時に Discordに送信され、変更するにはコマンドを再登録する必要があります。

最後に

ここまで見てくれてありがとうございます。わかりにくいところが多いでしょうがそういう時は有識者とかgithubにある公式のサンプルコードを真似るか私に聞いてください!それではよいpyライフを。

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?