'How to return the keyboard to its original state after the completion of the script?
This script is part of a telegram bot. The task of this script is to provide the user with a multiple choice of options.
from telegram import InlineKeyboardButton, InlineKeyboardMarkup
from telegram.ext import (
Updater,
CommandHandler,
CallbackQueryHandler,
ConversationHandler)
import logging
green_check = '\u2705'
grey_check = '\u2714'
FIRST, ANSWER = range(2)
TEXT_1 = 'Click'
CHECK = grey_check
CLICK = False
KEYS = {'1': (0, 0), '2': (0, 1), '3': (1, 0), '4': (1, 1)}
keyboard = [
[
InlineKeyboardButton(f'1 {grey_check}', callback_data='1'),
InlineKeyboardButton(f'2 {grey_check}', callback_data='2'),
],
[
InlineKeyboardButton(f'3 {grey_check}', callback_data='3'),
InlineKeyboardButton(f'4 {grey_check}', callback_data='4'),
],
[
InlineKeyboardButton('Next \u27A1', callback_data='next'),
],
]
def start(update, context):
CHECK = grey_check
reply_markup = InlineKeyboardMarkup(keyboard)
update.message.reply_text(TEXT_1, reply_markup=reply_markup)
for i in range(1,5):
context.user_data[f'BUTTON_{i}'] = False
return FIRST
def clicked(click=None, data=None):
global keyboard
global CHECK
if click == True:
CHECK = green_check
else:
CHECK = grey_check
keyboard[KEYS[data][0]][KEYS[data][1]] = InlineKeyboardButton(
f'{data} {CHECK}', callback_data=f'{data}')
reply_markup = InlineKeyboardMarkup(keyboard)
return reply_markup
def press(update, context):
data = update.callback_query.data
global CLICK
if context.user_data[f'BUTTON_{data}'] == False:
context.user_data[f'BUTTON_{data}'] = True
else:
context.user_data[f'BUTTON_{data}'] = False
reply_keyboard = clicked(context.user_data[f'BUTTON_{data}'], data)
update.callback_query.edit_message_text(text=TEXT_1, reply_markup=reply_keyboard)
return FIRST
def send(update, context):
text = ''
for i in range(1, 5):
text += f'{i} - ' + str(context.user_data[f'BUTTON_{i}']) + '\n'
context.user_data[ANSWER] = text
update.callback_query.edit_message_text(text=context.user_data[ANSWER])
return ConversationHandler.END
def main():
updater = Updater(
'TOKEN', use_context=True)
dp = updater.dispatcher
conv_handler = ConversationHandler(
entry_points=[CommandHandler('start', start)],
states={
FIRST: [
CallbackQueryHandler(press, pattern='^'+str(1)+'$'),
CallbackQueryHandler(press, pattern='^'+str(2)+'$'),
CallbackQueryHandler(press, pattern='^'+str(3)+'$'),
CallbackQueryHandler(press, pattern='^'+str(4)+'$'),
CallbackQueryHandler(send, pattern='^'+'next'+'$'),
],
},
fallbacks=[CommandHandler('start', start)]
)
dp.add_handler(conv_handler)
updater.start_polling()
updater.idle()
if __name__ == "__main__":
main()
After selecting the option, the color of the button changes to green, after sending the data and the next run of the /start script, the keyboard does not return to its original form. The buttons pressed by the user remain green, while the data change, when the buttons are pressed, occurs as expected.
Solution 1:[1]
After several attempts, I found this solution:
from telegram import InlineKeyboardButton, InlineKeyboardMarkup
from telegram.ext import (
Updater,
CommandHandler,
CallbackQueryHandler,
ConversationHandler)
import logging
green_check = '\u2705'
grey_check = '\u2714'
FIRST, ANSWER = range(2)
TEXT_1 = 'Click'
CHECK = grey_check
CLICK = False
BUTTONS = []
KEYS = {'1': (0, 0), '2': (0, 1), '3': (1, 0), '4': (1, 1)}
keyboard = [
[
InlineKeyboardButton(f'1 {CHECK}', callback_data='1'),
InlineKeyboardButton(f'2 {CHECK}', callback_data='2'),
],
[
InlineKeyboardButton(f'3 {CHECK}', callback_data='3'),
InlineKeyboardButton(f'4 {CHECK}', callback_data='4'),
],
[
InlineKeyboardButton('Next \u27A1', callback_data='next'),
],
]
def start(update, context):
global CHECK
global keyboard
global BUTTONS
CHECK = grey_check
for data in BUTTONS:
keyboard[KEYS[data][0]][KEYS[data][1]] = InlineKeyboardButton(
f'{data} {CHECK}', callback_data=f'{data}')
reply_markup = InlineKeyboardMarkup(keyboard)
update.message.reply_text(TEXT_1, reply_markup=reply_markup)
for i in range(1,5):
context.user_data[f'BUTTON_{i}'] = False
BUTTONS = []
return FIRST
def clicked(click=None, data=None):
global keyboard
global CHECK
global BUTTONS
if click == True:
CHECK = green_check
else:
CHECK = grey_check
BUTTONS.append(data)
keyboard[KEYS[data][0]][KEYS[data][1]] = InlineKeyboardButton(
f'{data} {CHECK}', callback_data=f'{data}')
reply_markup = InlineKeyboardMarkup(keyboard)
return reply_markup
def press(update, context):
data = update.callback_query.data
global CLICK
if context.user_data[f'BUTTON_{data}'] == False:
context.user_data[f'BUTTON_{data}'] = True
else:
context.user_data[f'BUTTON_{data}'] = False
reply_keyboard = clicked(context.user_data[f'BUTTON_{data}'], data)
update.callback_query.edit_message_text(text=TEXT_1, reply_markup=reply_keyboard)
return FIRST
def send(update, context):
text = ''
for i in range(1, 5):
text += f'{i} - ' + str(context.user_data[f'BUTTON_{i}']) + '\n'
context.user_data[ANSWER] = text
update.callback_query.edit_message_text(text=context.user_data[ANSWER])
return ConversationHandler.END
def main():
updater = Updater(
'TOKEN', use_context=True)
dp = updater.dispatcher
conv_handler = ConversationHandler(
entry_points=[CommandHandler('start', start)],
states={
FIRST: [
CallbackQueryHandler(press, pattern='^'+str(1)+'$'),
CallbackQueryHandler(press, pattern='^'+str(2)+'$'),
CallbackQueryHandler(press, pattern='^'+str(3)+'$'),
CallbackQueryHandler(press, pattern='^'+str(4)+'$'),
CallbackQueryHandler(send, pattern='^'+'next'+'$'),
],
},
fallbacks=[CommandHandler('start', start)]
)
dp.add_handler(conv_handler)
updater.start_polling()
updater.idle()
if __name__ == "__main__":
main()
Perhaps this is not the best solution. Do you have any ideas how to improve this code?
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
