Как показать имя меню после выбора в элементе disnake.ui.StringSelect?

Не могу найти функцию, которая возвращала бы меню к первоначальному виду после выбора. Либо я не вижу ее, либо не понимаю, как это должно работать. Где находится эта функция? Если ее нет, не могли бы вы подсказать, как я могу решить эту проблему? <br/> Вот мой код. Сначала появляется меню с выбором игры. После выбора пользователь получает сообщение с новым меню, в котором необходимо выбрать категорию игры, а затем выполняются другие функции. Однако после этого второе меню с сообщением исчезает. По идее, первое меню должно сбрасывать выбор пользователя, но я не могу придумать, как это сделать. Если я пытаюсь использовать edit_original_response, то возникает ошибка. <br/> <br/> <pre><code class="python">class DropdownMenu(disnake.ui.StringSelect):

    def __init__ (self):
        options = [
            disnake.SelectOption(label = "Starcraft 2"),
            disnake.SelectOption(label = "Overwatch 2"),
            disnake.SelectOption(label = "League of Legends"),
            disnake.SelectOption(label = "Counter-Strike"),
            disnake.SelectOption(label = "Dota 2"),
            disnake.SelectOption(label = "Другое")
        ]

        super().__init__(
            placeholder = "Игры",
            min_values = 0,
            max_values = 1,
            options = options
        )

    async def callback(self, inter: disnake.MessageInteraction):
        
        if self.values[0] == "Starcraft 2":
            await inter.response.send_message(f"Выберите категорию {self.values[0]}", view = DropdownView(1))
        elif self.values[0] == "Overwatch 2":
            await inter.response.send_message(f"Выберите категорию {self.values[0]}", view = DropdownView(2))
        elif self.values[0] == "League of Legends":
            await inter.res
  • 10 сентября 2024 г. 17:33
Ответы на вопрос 2
В вашем коде вы используете `disnake.ui.StringSelect` для отображения выпадающего меню, и после выбора значения вы отправляете новое сообщение с другим меню. Проблема, с которой вы столкнулись, заключается в том, что после выбора в первом меню оно не сбрасывается, и вам нужно вернуть его в первоначальное состояние.

Чтобы сбросить выбранное значение в элементах интерфейса, таких как `StringSelect`, вам необходимо обновить (или перерисовать) родительский интерфейс с обновленным состоянием. В вашей ситуации вы можете воспользоваться методом `edit_original_response`, чтобы обновить сообщение с первым меню, сбросив состояние `StringSelect`.

Вот пример того, как это можно реализовать:

```python
import disnake
from disnake.ext import commands

class DropdownMenu(disnake.ui.StringSelect):
    def __init__(self):
        options = [
            disnake.SelectOption(label="Starcraft 2", value="starcraft"),
            disnake.SelectOption(label="Overwatch 2", value="overwatch"),
            disnake.SelectOption(label="League of Legends", value="lol"),
            disnake.SelectOption(label="Counter-Strike", value="cs"),
            disnake.SelectOption(label="Dota 2", value="dota"),
            disnake.SelectOption(label="Другое", value="other")
        ]

        super().__init__(
            placeholder="Игры",
            min_values=1,  # измените на 1, если хотите, чтобы до 1 элемента выбирали
            max_values=1,
            options=options
        )

    async def callback(self, inter: disnake.MessageInteraction):
        selected_game = self.values[0]

        # Создаем новое меню для категорий в зависимости от выбранной игры
        await inter.response.send_message(f"Выберите категорию {selected_game}", view=DropdownView(selected_game))

        # Сбрасываем выбор в текущем DropdownMenu
        await inter.message.edit(view=self.make_reset_view())

    def make_reset_view(self):
        # Создаем новое меню с первоначальным состоянием
        return disnake.ui.View().add_item(DropdownMenu())

class DropdownView(disnake.ui.View):
    def __init__(self, game_type):
        super().__init__()
        self.game_type = game_type
        # Инициализируем новое DropdownMenu для категорий каждой игры здесь
        # Например:
        if self.game_type == 'starcraft':
            self.add_item(disnake.ui.StringSelect(options=[...]))  # добавьте соответствующие категории
        
# Основной бот
bot = commands.Bot(command_prefix='!')

@bot.command()
async def menu(ctx):
    dropdown = DropdownMenu()
    await ctx.send("Выберите игру:", view=dropdown)

bot.run('YOUR_TOKEN')
```

### Что было изменено и добавлено:

1. **Сброс выбора**: Вам нужно добавить логику сброса выбранного значения в `DropdownMenu`. Для этого я создал метод `make_reset_view`, который создает новое меню с первоначальным состоянием. При этом состояние `StringSelect` сбрасывается.
  
2. **Передача значений**: Я добавил `value` к опциям в `SelectOption`, чтобы вы могли использовать его для идентификации выбранной игры.

3. **Использование родительского метода `edit`**: После выбора игры сообщение обновляется с новым меню и предварительнее сбросив предыдущее состояние. Обратите внимание на необходимый вид кнопки для обновления.

Эта структура также предполагает, что у вас есть соответствующие категории для каждой игры в `DropdownView`. Обязательно создайте нужные опции для каждой игры, если они разные.
Нигде не могу найти функцию, чтобы возвращала в первоначальный вид меню после выбора.
Потому что нет такой функции. Из первого меню создаете второе, из второго пересоздаете первое.

Если использую edit_original_response то выводит ошибку.
Если я правильно вас понял, вы после операций во втором сообщении хотите поправить первое. Второе о первом вообще ничего не знает. До вызова inter.response.send_message можно получить сообщение из inter.message , сохранить id и затем его отредактировать.
Похожие вопросы