はじめに
Discordでは様々なuiが準備されています。今回はドロップダウンメニューやボタンの使い方や制御について、この記事では紹介します。
基本的には下記で紹介したテンプレートをベースに、拡張して作成します。
ファイル構成は下記の通り。
.
┣━ main.py
┣━ .env
┗━ cogs
┣━ commands.py
┗━ listenner.py
今回はcommands.pyを修正して作成します。
1.ボタンとドロップダウンメニューを出力するコマンドを作成する
こんな感じのボタンやドロップダウンメニューを出力するコマンドを作成してみます。
import os,discord
from discord.ext import commands
from discord import app_commands
# DiscordサーバのIDを取得
GUILD_ID = os.getenv('GUILD_ID')
# ボタンの挙動を定義するクラス
class Button(discord.ui.Button):
def __init__(self, label,style):
super().__init__(label=label,style=style)
async def callback(self, interaction: discord.Interaction):
await interaction.response.send_message(content=self.label+'ボタンが押されました。')
# ボタンのビューを定義するクラス
class ButtonView(discord.ui.View):
def __init__(self, timeout=180):
super().__init__(timeout=timeout)
self.add_item(Button(label='OK', style=discord.ButtonStyle.success))
self.add_item(Button(label='Cancel', style=discord.ButtonStyle.gray))
# ドロップダウンメニューの挙動を定義するクラス
class Dropdown(discord.ui.Select):
def __init__(self,options):
super().__init__(placeholder='好きな動物は何ですか?', min_values=1, max_values=1, options=options)
async def callback(self, interaction: discord.Interaction):
# 2回以上実行されないように非活性にする。
self.disabled = True
# edit_messageを使って変更したビューを反映する。
await interaction.response.edit_message(view=self.view)
# responseは1回のみのため、followupを使ってesonseに対して返信を行う。
await interaction.followup.send(self.values[0]+'が選択されました。')
# ドロップダウンメニューのビューを定義するクラス
class DropdownView(discord.ui.View):
def __init__(self):
super().__init__()
# ドロップダウンメニューのリスト
options = [
discord.SelectOption(label='dog', description='犬が好きです。'),
discord.SelectOption(label='cat', description='猫が好きです。'),
discord.SelectOption(label='bird', description='鳥が好きです。'),
]
# viewにセレクトを追加
self.add_item(Dropdown(options=options))
class MyCommands(commands.Cog):
def __init__(self, bot):
self.bot = bot
# ボタンを出力するスラッシュコマンドを追加
@app_commands.command(name='button', description='ボタンを表示します。')
async def button(self,interaction: discord.Interaction):
await interaction.response.send_message(view=ButtonView())
# ドロップダウンメニューを出力するスラッシュコマンドを追加
@app_commands.command(name='select', description='ドロップダウンメニューを表示します。')
async def select(self,interaction: discord.Interaction):
await interaction.response.send_message(view=DropdownView())
# BOTにcogを登録 ギルドコマンドとして登録
async def setup(bot: commands.Bot):
await bot.add_cog(MyCommands(bot), guild=discord.Object(id=GUILD_ID))
イメージとしてはビューにボタンやドロップダウンメニューを配置して、それぞれのオブジェクトのcallback関数
で挙動を定義する感じです。なので一つのビューの中で複数のボタンやドロップダウンメニューなどを配置できます。
また、今回は1度だけ実行させたいのでDropdown
のcallback関数
でself.disabled = True
を指定して、ドロップダウンメニューを非活性化しています。何回でも実行しても問題なければ下記でOKです。
async def callback(self, interaction: discord.Interaction):
await interaction.response.send_message(self.values[0]+'が選択されました。')
2.対話的にuiを利用するやり方
例えば、ドロップダウンメニューを選択したのち、それで良いかどうかを確認したい場合があったとします。その場合、以下のようにドロップダウンメニューの後にOK,Cancelボタンを表示して選ばせるといった方法があります。
以下それを実現させたコードです。
import os,discord
from discord.ext import commands
from discord import app_commands
# DiscordサーバのIDを取得
GUILD_ID = os.getenv('GUILD_ID')
# ボタンの挙動を定義するクラス
class Button(discord.ui.Button):
def __init__(self, label,style):
super().__init__(label=label,style=style)
async def callback(self, interaction: discord.Interaction):
await interaction.response.send_message(content=self.label+'ボタンが押されました。')
# ボタンのビューを定義するクラス
class ButtonView(discord.ui.View):
def __init__(self, timeout=180):
super().__init__(timeout=timeout)
self.add_item(Button(label='OK', style=discord.ButtonStyle.success))
self.add_item(Button(label='Cancel', style=discord.ButtonStyle.gray))
# ドロップダウンメニューの挙動を定義するクラス
class Dropdown(discord.ui.Select):
def __init__(self,options):
super().__init__(placeholder='好きな動物は何ですか?', min_values=1, max_values=1, options=options)
async def callback(self, interaction: discord.Interaction):
# edit_messageを使って表示をButtonViewへ変更する。
await interaction.response.edit_message(content=self.values[0]+'が選択されました。よろしいですか?',view=ButtonView())
# ドロップダウンメニューのビューを定義するクラス
class DropdownView(discord.ui.View):
def __init__(self):
super().__init__()
# ドロップダウンメニューのリスト
options = [
discord.SelectOption(label='dog', description='犬が好きです。'),
discord.SelectOption(label='cat', description='猫が好きです。'),
discord.SelectOption(label='bird', description='鳥が好きです。'),
]
# viewにセレクトを追加
self.add_item(Dropdown(options=options))
class MyCommands(commands.Cog):
def __init__(self, bot):
self.bot = bot
# ドロップダウンメニューを出力するスラッシュコマンドを追加
@app_commands.command(name='select', description='ドロップダウンメニューを表示します。')
async def select(self,interaction: discord.Interaction):
await interaction.response.send_message(view=DropdownView())
# BOTにcogを登録 ギルドコマンドとして登録
async def setup(bot: commands.Bot):
await bot.add_cog(MyCommands(bot), guild=discord.Object(id=GUILD_ID))
Dropdown
のcallback関数
で使用するビューをドロップダウンメニュー(DropdownView
)からボタン(ButtonView
)へ変更しています。
content
を設定することで、メッセージとともにボタンを表示することができます。
ちなみにビューを表示させたくない場合はview=None
としてください。
まとめ
uiを表示させるには、viewに表示するuiを設定してsend_messageでviewを表示させるだけです。その他のuiは使ったことがないですが、おそらく同じような使い方だと思っています。(調べていません)
今回はここまで。