Делюсь своим. Разобраться можно. Только кнопки Inline, но смысл функции одинаковый: вывести любое нужное количество кнопок.
from telebot import types
def message_dialog(*args):
btns_in_row = 3
buttons = []
buttons.extend([*args])
if len(buttons) < 3:
raise AttributeError('Ошибка! Диалог должен иметь не менее 3 аргументов: заголовок, user_id и названия кнопок')
caption = buttons[0]
del buttons[0]
user_id = buttons[0]
if type(user_id) != int:
raise AttributeError('Второй аргумент (user_id) должен быть числом')
del buttons[0]
keyboard = types.InlineKeyboardMarkup()
keyboard.row_width = btns_in_row
btn_count = len(buttons)
row_count = btn_count//btns_in_row
surplus = btn_count - row_count * btns_in_row
btn_no = -1
def fill_kb_row(btn_names:list, count):
btn_list = []
for N in range(count):
nonlocal btn_no
btn_no = btn_no + 1
if len(str(btn_names[btn_no])) > 20:
raise AttributeError('Текст на кнопке не должен быть длиннее 20 символов, включая пробелы и знаки препинания')
btn = types.InlineKeyboardButton(btn_names[btn_no], callback_data = 'dlg_' + btn_names[btn_no] + '_' + str(user_id))
btn_list.append(btn)
return btn_list
for i in range(row_count):
keyboard.row(*fill_kb_row(buttons, btns_in_row))
keyboard.row(*fill_kb_row(buttons, surplus))
return caption, keyboard
Использование:
caption, keyboard = message_dialog('⚠️ Выберите вариант:', message.from_user.id, 'Да', 'Нет', 'Может быть', 'Отмена')
bot.send_message(message.chat.id, caption, reply_markup = keyboard)