Python-telegram-bot:无需修改键盘,识别用户多选的骰子下注按钮
Python-telegram-bot 实现多选项下注且不刷新键盘的方案
核心思路:不用每次点击都重新生成并编辑键盘,而是利用 python-telegram-bot 内置的context.user_data存储用户选中的选项,键盘保持静态仅提供交互入口,最终通过读取存储的选项判定输赢。
1. 初始化用户选中状态
在触发下注功能的命令(比如/bet)处理函数中,初始化用户的选中列表,确保每个用户的下注数据独立:
def start_bet(update, context): # 初始化用户选中列表,最多存2个选项 context.user_data['selected_bets'] = [] # 发送带静态键盘的消息 update.message.reply_text( "请选择最多2个下注选项:", reply_markup=get_bet_keyboard() )
2. 构建静态InlineKeyboard
直接创建包含所有功能按钮的键盘,通过callback_data区分按钮类型:
from telegram import InlineKeyboardButton, InlineKeyboardMarkup def get_bet_keyboard(): keyboard = [ [InlineKeyboardButton("1", callback_data="bet:1"), InlineKeyboardButton("2", callback_data="bet:2"), InlineKeyboardButton("3", callback_data="bet:3")], [InlineKeyboardButton("4", callback_data="bet:4"), InlineKeyboardButton("5", callback_data="bet:5"), InlineKeyboardButton("6", callback_data="bet:6")], [InlineKeyboardButton("奇数", callback_data="bet:odd"), InlineKeyboardButton("偶数", callback_data="bet:even")], [InlineKeyboardButton("返回", callback_data="action:back"), InlineKeyboardButton("掷骰子", callback_data="action:roll")] ] return InlineKeyboardMarkup(keyboard)
3. 处理按钮回调逻辑
通过CallbackQueryHandler解析按钮指令,仅更新后端存储的选中状态,不修改键盘:
import random from telegram.ext import CallbackQueryHandler def handle_bet_callback(update, context): query = update.callback_query query.answer() # 必须调用,消除用户端的加载状态 data = query.data selected = context.user_data.get('selected_bets', []) # 处理下注选项点击 if data.startswith('bet:'): bet_option = data.split(':')[1] # 切换选中/取消选中,限制最多2个选项 if bet_option in selected: selected.remove(bet_option) else: if len(selected) < 2: selected.append(bet_option) else: query.answer("最多只能选2个选项哦", show_alert=True) return context.user_data['selected_bets'] = selected # 可选:更新消息文本,让用户直观看到当前选中项 current_text = f"当前选中:{'、'.join(selected) if selected else '未选择'}\n请选择最多2个选项" query.edit_message_text(text=current_text, reply_markup=get_bet_keyboard()) # 处理掷骰子逻辑 elif data == 'action:roll': if not selected: query.answer("请先选择至少一个下注选项", show_alert=True) return dice_result = random.randint(1,6) result_text = f"骰子结果:{dice_result}\n" win_count = 0 # 逐一判定每个选中项的输赢 for bet in selected: if bet.isdigit(): if int(bet) == dice_result: result_text += f"选中的{bet}:赢了!\n" win_count +=1 else: result_text += f"选中的{bet}:输了\n" elif bet == 'odd': if dice_result %2 ==1: result_text += "选中的奇数:赢了!\n" win_count +=1 else: result_text += "选中的奇数:输了\n" elif bet == 'even': if dice_result %2 ==0: result_text += "选中的偶数:赢了!\n" win_count +=1 else: result_text += "选中的偶数:输了\n" result_text += f"\n总共赢了{win_count}项" query.edit_message_text(text=result_text, reply_markup=get_bet_keyboard()) # 重置选中列表,准备下一轮下注 context.user_data['selected_bets'] = [] # 处理返回逻辑 elif data == 'action:back': query.edit_message_text(text="已返回主菜单", reply_markup=None) context.user_data['selected_bets'] = []
4. 注册处理器
把上述函数注册到Application中:
def main(): application = Application.builder().token("YOUR_BOT_TOKEN").build() application.add_handler(CommandHandler("bet", start_bet)) application.add_handler(CallbackQueryHandler(handle_bet_callback)) application.run_polling() if __name__ == "__main__": main()
内容的提问来源于stack exchange,提问作者Raysuoo
相关产品推荐
相关产品推荐

