Как создать опросник в Telebot на Python с помощью кнопок, которые будут появляться поэтапно, одна за другой?

Как лучше реализовать последовательное появление вопросов с учетом использования InlineKeyboardButton и callback_data? Есть ли другой способ решения этой задачи? Кроме того, каким образом можно запретить повторное нажатие кнопок? <br/> Вот мой текущий работающий код, но он нуждается в улучшении: <br/> <pre><code class="python">@bot.message_handler(commands=['start'])
def get_text_messages(message):
    bot.send_message(message.from_user.id,
                     hi_text['first'])
    keyboard = types.InlineKeyboardMarkup()
    key_next = types.InlineKeyboardButton(text='Продолжить',
                                          callback_data='next')
    keyboard.add(key_next)
    bot.send_message(
        message.from_user.id, text=hi_text['second'],
        reply_markup=keyboard)


@bot.callback_query_handler(func=lambda call: True)
def query_handler(call):
    global first_pas_count
    global second_pas_count
    bot.answer_callback_query(callback_query_id=call.id)
    if call.data == 'next':
        bot.send_message(call.from_user.id,
                         first_pas['name_1'])
        keyboard = types.InlineKeyboardMarkup()
        key_q_1_1 = types.InlineKeyboardButton(text=first_pas['answer_1_1'],
                                               callback_data='answer_1_1')
        keyboard.add(key_q_1_1)
        key_q_1_2 = types.InlineKeyboardButton(text=first_pas['answer_1_2'],
                                               callback_data='answer_1_2')
        keyboard.add(key_q_1_2)

        key_q_1_3 = types.InlineKeyboardButton(text=first_pas['answer_1...
  • 25 сентября 2024 г. 18:53
Ответы на вопрос 1
Для реализации опросника в Telebot, где вопросы появляются поэтапно с использованием InlineKeyboardButton и callback_data, необходимо учитывать состояние опроса, чтобы отслеживать этапы и предотвращать повторные нажатия кнопок. Для этого можно воспользоваться временной памятью (например, словарем), чтобы сохранять состояние каждого пользователя.

Вот улучшенная версия вашего кода, которая включает последовательное появление вопросов и запрет на повторное нажатие кнопок:

```python
import telebot
from telebot import types

bot = telebot.TeleBot('YOUR_BOT_TOKEN')

# Переменные для хранения вопросов и ответов
hi_text = {
    'first': 'Привет! Начнем опрос.',
    'second': 'Первый вопрос:'
}

first_pas = {
    'name_1': 'Какой ваш любимый цвет?',
    'answer_1_1': 'Красный',
    'answer_1_2': 'Синий',
    'answer_1_3': 'Зеленый',
}

# Состояние пользователей
user_states = {}

@bot.message_handler(commands=['start'])
def get_text_messages(message):
    bot.send_message(message.from_user.id, hi_text['first'])
    keyboard = types.InlineKeyboardMarkup()
    key_next = types.InlineKeyboardButton(text='Продолжить', callback_data='next')
    keyboard.add(key_next)
    bot.send_message(message.from_user.id, text=hi_text['second'], reply_markup=keyboard)

@bot.callback_query_handler(func=lambda call: True)
def query_handler(call):
    user_id = call.from_user.id
    
    # Инициализируем состояние пользователя, если оно еще не установлено
    if user_id not in user_states:
        user_states[user_id] = {'stage': 0}

    current_stage = user_states[user_id]['stage']
    
    if current_stage == 0 and call.data == 'next':
        bot.answer_callback_query(call.id)
        bot.send_message(call.from_user.id, first_pas['name_1'])
        
        # Создаем кнопки для ответов
        keyboard = types.InlineKeyboardMarkup()
        key_q_1_1 = types.InlineKeyboardButton(text=first_pas['answer_1_1'], callback_data='answer_1_1')
        key_q_1_2 = types.InlineKeyboardButton(text=first_pas['answer_1_2'], callback_data='answer_1_2')
        key_q_1_3 = types.InlineKeyboardButton(text=first_pas['answer_1_3'], callback_data='answer_1_3')
        keyboard.add(key_q_1_1, key_q_1_2, key_q_1_3)

        bot.send_message(call.from_user.id, 'Пожалуйста, выберите вариант:', reply_markup=keyboard)
        user_states[user_id]['stage'] += 1  # Переход на следующий этап
    
    elif current_stage == 1 and call.data in ['answer_1_1', 'answer_1_2', 'answer_1_3']:
        bot.answer_callback_query(call.id)
        # Обработка ответа
        answer = call.data
        bot.send_message(call.from_user.id, f'Вы выбрали: {answer}')
        
        # Здесь можно добавить больше вопросов и логики
        # Для примера, завершение опроса
        bot.send_message(call.from_user.id, 'Спасибо за участие! Опрос завершен.')
        del user_states[user_id]  # Удаляем состояние после завершения опроса

# Запускаем бот
bot.polling(none_stop=True)
```

### Объяснение кода:

1. **Хранение состояния пользователя**: Используем словарь `user_states`, чтобы отслеживать, на каком этапе находится каждый пользователь.

2. **Обработка кнопок**: Используем `callback_data` для перехода между этапами. Если пользователь нажимает кнопку "Продолжить", бот отправляет вопрос и кнопки с ответами. На следующем этапе пользователь может ответить, и его выбор обработается.

3. **Запрет на повторное нажатие**: Состояние для каждого пользователя отслеживается, и кнопки доступны только для тех этапов, где это предусмотрено.

4. **Удаление состояния**: После завершения опроса состояние пользователя удаляется, чтобы при следующем запуске `/start` он мог пройти опрос заново.

Такой подход позволит вам создать интерактивный опрос с последовательным выводом вопросов и ответов. Вы можете дополнительно улучшить функционал, добавляя больше вопросов и этапов в опрос.
Похожие вопросы