从按钮调用另一个函数时会出现此问题。当触发机器人重现菜单的某个状态时,如果用户按下播放键盘上的任何其他按钮,该状态就会结束,但不会发出用户请求的新操作。为了使此操作起作用,用户必须再次单击他想要激活的按钮。我希望问题已经清楚了。 (在运行状态下,为了让用户打开另一个菜单,必须调用它两次。第一次 - 完成状态,第二次 - 启动一个新功能。需要一个想法如何解决这个问题问题)
poster = ['any url', 'any url', 'any url']
name = ['test1', 'test2', 'test3']
storage = MemoryStorage()
bot = Bot(TOKEN)
dp = Dispatcher(bot=bot,
storage=storage)
class Test(StatesGroup):
Q1 = State()
next_button = InlineKeyboardButton(text='next', callback_data='next')
back_button = InlineKeyboardButton(text='back', callback_data='back')
nbtn_callback = [next_button.callback_data, back_button.callback_data]
nbtn = InlineKeyboardMarkup(row_width=True)
nbtn_next = InlineKeyboardMarkup(row_width=True)
nbtn_next.add(next_button)
nbtn.row(back_button, next_button)
a = KeyboardButton('cancel')
b = KeyboardButton('Photo')
menu = ReplyKeyboardMarkup(resize_keyboard=True)
menu.row(a, b)
@dp.message_handler(commands=['start'])
async def start_bot(message: types.Message):
txt = "Hello!\n"
await message.answer(txt, reply_markup=menu)
await message.delete()
@dp.message_handler(text='Photo', state=None)
async def photo(message: types.Message):
reply_markup = nbtn_next
await Test.Q1.set()
await bot.send_photo(
message.chat.id,
photo=poster[0],
reply_markup=reply_markup,
caption=name[0],
)
@dp.message_handler(text='cancel', state=None)
async def cancel(message: types.Message):
ph = "any url photo"
await bot.send_photo(chat_id=message.chat.id,
photo=ph)
@dp.callback_query_handler(state=Test.Q1)
async def photo_update(callback: types.CallbackQuery, state: FSMContext):
if callback.data == "next":
i = await state.get_data()
i = i.get("answer")
if i is None:
i = 1
else:
i += 1
file_path = poster[i]
await state.update_data(
{"answer": poster.index(file_path)}
)
file = InputMedia(media=file_path, caption=name[i])
await callback.message.edit_media(file, reply_markup=nbtn)
@dp.message_handler(content_types=types.ContentType.TEXT, state=Test.Q1)
async def stop_state(message: types.Message, state: FSMContext):
await state.finish()
正如你所看到的,这部分代码是为了完成状态,但是由于这种设计,需要一个新的动作才能工作
@dp.message_handler(content_types=types.ContentType.TEXT, state=Test.Q1)
async def stop_state(message: types.Message, state: FSMContext):
await state.finish()
尝试将你的函数(stop_state)放在带有处理程序的文件顶部。
我的函数(cancel_operation)看起来像这样并且可以工作。
@dp.message_handler(commands=['cancel'], state="*")
async def cancel_operation(message: types.Message, state: FSMContext):
"""Cancel current operation"""
try:
await state.finish()
await message.answer(
text=message_cancel_action,
reply_markup=ReplyKeyboardRemove()
)
except Exception as error:
logger.error(f"[ERROR] {error}")