Profile picture

[Python] 디스코드(Discord) Select를 활용하여 콤보박스 구현하기

JaehyoJJAng2024년 09월 20일

개요

discord.py에서 discord.ui.Select를 활용하여 콤보박스(드롭다운 메뉴)를 구현하는 방법을 단계별로 기록해보려고 한다.


1. 기본 콤보박스 구현하기

다음 코드는 간단한 discord.ui.Select 예제이다.

사용자가 콤보박스에서 옵션을 선택하면 선택한 값이 표시된다.

import discord
import json
import os
from discord.ext import commands
from discord import app_commands, ButtonStyle
from discord.ui import Button, View, Select


class DropDownView(View):
    def __init__(self):
        super().__init__(timeout=None)

        # DropDown 추가
        self.add_item(DropDown())


class DropDown(Select):
    def __init__(self):
        options = [
            discord.SelectOption(label="첫 번째 옵션!!"),
            discord.SelectOption(label="두 번째 옵션!!"),
            discord.SelectOption(label="세 번째 옵션!!"),
        ]
        super().__init__(
            placeholder="옵션을 선택하세요!",
            max_values=1,
            min_values=1,
            options=options,
        )

    async def callback(self, interaction: discord.Interaction) -> None:
        await interaction.response.send_message(
            f"당신이 선택한 옵션은 {' '.join(self.values)} 입니다!"
        )


class DropDownCog(commands.Cog):
    def __init__(self, bot: commands.Bot):
        super().__init__()
        self.bot = bot

    @commands.Cog.listener()
    async def on_ready(self) -> None:
        print(f"{self.__class__.__name__} Cog is ready.")
        channel_id: int = 1319685000370716722
        channel = self.bot.get_channel(channel_id)
        if channel:
            await channel.send(
                "알림 등록을 시작하려면 아래 버튼을 클릭하세요.", view=DropDownView()
            )


# Cog 등록 함수
async def setup(bot: commands.Bot):
    await bot.add_cog(DropDownCog(bot=bot))

  • DropDownView: 드롭다운 메뉴를 메시지와 함께 렌더링하기 위해 사용된다.
  • DropDown.callback() : 사용자가 옵션을 선택했을 때 실행되는 함수이다.
  • super().__init__(placeholder="Choose an option...", max_values=1, min_values=1, options=options)
    • min_values: 최소 선택 가능한 옵션의 수를 나타낸다.
    • max_values: 최대 선택 가능한 옵션의 수를 나타낸다.

테스트

위 코드를 실행하여 디스코드에서 직접 테스트해보자.
dico-example1


2. 콤보박스와 버튼 연동

콤보박스와 버튼을 조합해서 더 확장성 있는 상호작용으로 구현해나갈 수 있다.

import discord
import json
import os
from discord.ext import commands
from discord import app_commands, ButtonStyle
from discord.ui import Button, View, Select


class DropDownView(View):
    def __init__(self):
        super().__init__(timeout=None)

        # DropDown 객체 생성
        self.dropdown = DropDown()

        # View에 Dropdown, Button 추가
        self.add_item(self.dropdown)

    @discord.ui.button(
        label="값 확인하기!",
        style=discord.ButtonStyle.green,
        custom_id="value_check_button",
    )
    async def value_check_button(
        self, interaction: discord.Interaction, button: discord.ui.Button
    ) -> None:
        if len(self.dropdown.values) > 0:
            print("OK")
            await interaction.response.send_message(
                f"당신이 선택한 옵션은 {' '.join(self.dropdown.values)} 입니다!"
            )


class DropDown(Select):
    def __init__(self):
        options = [
            discord.SelectOption(label="첫 번째 옵션!!"),
            discord.SelectOption(label="두 번째 옵션!!"),
            discord.SelectOption(label="세 번째 옵션!!"),
        ]
        super().__init__(
            placeholder="옵션을 선택하세요!",
            max_values=1,
            min_values=1,
            options=options,
        )

    async def callback(self, interaction: discord.Interaction):
        await interaction.response.defer()  # UI 업데이트만 수행


class DropDownCog(commands.Cog):
    def __init__(self, bot: commands.Bot):
        super().__init__()
        self.bot = bot

    @commands.Cog.listener()
    async def on_ready(self) -> None:
        print(f"{self.__class__.__name__} Cog is ready.")
        channel_id: int = 1319685000370716722
        channel = self.bot.get_channel(channel_id)
        if channel:
            await channel.send(
                "알림 등록을 시작하려면 아래 버튼을 클릭하세요.", view=DropDownView()
            )


# Cog 등록 함수
async def setup(bot: commands.Bot):
    await bot.add_cog(DropDownCog(bot=bot))

  • DropDown(): 옵션 선택 시 UI 업데이트만 수행하도록 callback() 메소드에서 Interaction.response.defer()를 작성해줬다.
  • DropDownView: 버튼을 추가하기 위해 discord.ui.button 이벤트로 해당 View에 버튼을 등록시켰다.
    • 또한 DropDown 객체를 멤버변수로 등록하고 버튼 클릭 시 선택된 옵션에 대한 값을 불러올 수 있도록 처리하였다.

테스트

위 코드를 실행하여 디스코드에서 직접 테스트해보자.
dico-example2


Loading script...