este problema se puede abordar de diversas maneras, por lo tanto te compartimos la resolución más completa en nuestra opinión.
Solución:
Deberías usar un argumento pattern
en CallbackQueryHandler
. También es bueno usar clases o funciones para teclados y mensajes.
Para volver al menú principal, agregue el botón de retorno al submenú con un patrón de devolución de llamada específico.
tenga en cuenta: tu usas edit_message_text
en el menú. Significa que no pasará nada si llamas start
funcionar con reply_text
método desde cualquier menú.
Ejemplo de trabajo completo con funciones:
#!/usr/bin/env python3.8
from telegram.ext import Updater
from telegram.ext import CommandHandler, CallbackQueryHandler
from telegram import InlineKeyboardButton, InlineKeyboardMarkup
############################### Bot ############################################
def start(bot, update):
bot.message.reply_text(main_menu_message(),
reply_markup=main_menu_keyboard())
def main_menu(bot, update):
bot.callback_query.message.edit_text(main_menu_message(),
reply_markup=main_menu_keyboard())
def first_menu(bot, update):
bot.callback_query.message.edit_text(first_menu_message(),
reply_markup=first_menu_keyboard())
def second_menu(bot, update):
bot.callback_query.message.edit_text(second_menu_message(),
reply_markup=second_menu_keyboard())
def first_submenu(bot, update):
pass
def second_submenu(bot, update):
pass
def error(update, context):
print(f'Update update caused error context.error')
############################ Keyboards #########################################
def main_menu_keyboard():
keyboard = [[InlineKeyboardButton('Menu 1', callback_data='m1')],
[InlineKeyboardButton('Menu 2', callback_data='m2')],
[InlineKeyboardButton('Menu 3', callback_data='m3')]]
return InlineKeyboardMarkup(keyboard)
def first_menu_keyboard():
keyboard = [[InlineKeyboardButton('Submenu 1-1', callback_data='m1_1')],
[InlineKeyboardButton('Submenu 1-2', callback_data='m1_2')],
[InlineKeyboardButton('Main menu', callback_data='main')]]
return InlineKeyboardMarkup(keyboard)
def second_menu_keyboard():
keyboard = [[InlineKeyboardButton('Submenu 2-1', callback_data='m2_1')],
[InlineKeyboardButton('Submenu 2-2', callback_data='m2_2')],
[InlineKeyboardButton('Main menu', callback_data='main')]]
return InlineKeyboardMarkup(keyboard)
############################# Messages #########################################
def main_menu_message():
return 'Choose the option in main menu:'
def first_menu_message():
return 'Choose the submenu in first menu:'
def second_menu_message():
return 'Choose the submenu in second menu:'
############################# Handlers #########################################
updater = Updater('XXXXXXXXX:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX', use_context=True)
updater.dispatcher.add_handler(CommandHandler('start', start))
updater.dispatcher.add_handler(CallbackQueryHandler(main_menu, pattern='main'))
updater.dispatcher.add_handler(CallbackQueryHandler(first_menu, pattern='m1'))
updater.dispatcher.add_handler(CallbackQueryHandler(second_menu, pattern='m2'))
updater.dispatcher.add_handler(CallbackQueryHandler(first_submenu, pattern='m1_1'))
updater.dispatcher.add_handler(CallbackQueryHandler(second_submenu, pattern='m2_1'))
updater.dispatcher.add_error_handler(error)
updater.start_polling()
################################################################################
Lo siento, tengo dos espacios en la pestaña. 🙂
UPD: Fijar objeto de submenú.
gran respuesta de @dzNET. Pero no funcionará en V12, así que cambié un poco.
from telegram.ext import CommandHandler, CallbackQueryHandler
from telegram import InlineKeyboardButton, InlineKeyboardMarkup
############################### Bot ############################################
def start(update, context):
update.message.reply_text(main_menu_message(),
reply_markup=main_menu_keyboard())
def main_menu(update,context):
query = update.callback_query
query.answer()
query.edit_message_text(
text=main_menu_message(),
reply_markup=main_menu_keyboard())
def first_menu(update,context):
query = update.callback_query
query.answer()
query.edit_message_text(
text=first_menu_message(),
reply_markup=first_menu_keyboard())
def second_menu(update,context):
query = update.callback_query
query.answer()
query.edit_message_text(
text=second_menu_message(),
reply_markup=second_menu_keyboard())
# and so on for every callback_data option
def first_submenu(bot, update):
pass
def second_submenu(bot, update):
pass
############################ Keyboards #########################################
def main_menu_keyboard():
keyboard = [[InlineKeyboardButton('Option 1', callback_data='m1')],
[InlineKeyboardButton('Option 2', callback_data='m2')],
[InlineKeyboardButton('Option 3', callback_data='m3')]]
return InlineKeyboardMarkup(keyboard)
def first_menu_keyboard():
keyboard = [[InlineKeyboardButton('Submenu 1-1', callback_data='m1_1')],
[InlineKeyboardButton('Submenu 1-2', callback_data='m1_2')],
[InlineKeyboardButton('Main menu', callback_data='main')]]
return InlineKeyboardMarkup(keyboard)
def second_menu_keyboard():
keyboard = [[InlineKeyboardButton('Submenu 2-1', callback_data='m2_1')],
[InlineKeyboardButton('Submenu 2-2', callback_data='m2_2')],
[InlineKeyboardButton('Main menu', callback_data='main')]]
return InlineKeyboardMarkup(keyboard)
############################# Messages #########################################
def main_menu_message():
return 'Choose the option in main menu:'
def first_menu_message():
return 'Choose the submenu in first menu:'
def second_menu_message():
return 'Choose the submenu in second menu:'
############################# Handlers #########################################
updater = Updater('YOUR_TOKEN_HERE', use_context=True)
updater.dispatcher.add_handler(CommandHandler('start', start))
updater.dispatcher.add_handler(CallbackQueryHandler(main_menu, pattern='main'))
updater.dispatcher.add_handler(CallbackQueryHandler(first_menu, pattern='m1'))
updater.dispatcher.add_handler(CallbackQueryHandler(second_menu, pattern='m2'))
updater.dispatcher.add_handler(CallbackQueryHandler(first_submenu,
pattern='m1_1'))
updater.dispatcher.add_handler(CallbackQueryHandler(second_submenu,
pattern='m2_1'))
updater.start_polling()
Nuevamente gracias a @dzNET
Comentarios y valoraciones del post
Si te gusta el tema, eres capaz de dejar un escrito acerca de qué te ha parecido este artículo.