@router.callback_query(StateFilter(FSMPag.forward))
async def collection_f(callback: CallbackQuery, state: FSMContext):
conn = sqlite3.connect('mega_db.db')
cur = conn.cursor()
user_id = callback.from_user.id
cur.execute("""SELECT array FROM users WHERE user_id = ?""", (user_id,))
result = cur.fetchall()[0][0]
numbers = [int(i) for i in result.strip('[]').replace(',', '').split()]
pag_num[user_id] += 1
pathCard = pathlib.Path(dir_p, "cards", f"{pag_card[user_id][int(pag_num[user_id])]}.jpg")
pathCard = FSInputFile(pathCard)
caption=lexicon['collection']
if callback.data == 'forward':
await state.set_state(FSMPag.forward)
if pag_num[user_id] + 1 == len(numbers):
reply_markup = create_pagination_keyboard('backward', f'{pag_num[user_id]+1}/{len(numbers)}')
else:
reply_markup = create_pagination_keyboard('backward', f'{pag_num[user_id]+1}/{len(numbers)}', 'forward')
elif callback.data == 'backward':
await state.set_state(FSMPag.backward)
if pag_num[user_id] == 0:
reply_markup = create_pagination_keyboard(f'{pag_num[user_id]+1}/{len(numbers)}')
else:q
reply_markup = create_pagination_keyboard('backward', f'{pag_num[user_id]+1}/{len(numbers)}', 'forward')
else:
pass
await callback.message.edit_media(InputMediaPhoto(media=pathCard, caption=caption), reply_markup=reply_markup)
由于某种原因,机器人识别出所需的回调,但不会立即切换到另一个状态
我尝试重置 if 块中的状态,但仍然没有任何帮助。通过测试,我发现回调被正确识别,并且整个块,如果它与此回调一起工作,只有状态切换不起作用
The reason why your state doesn't change immediately is because
await state.set_state()
is not blocking
. It schedules the state change for the next interaction with the FSM, not within the same handler execution.
Here's how the code execution flows:
-
Callback received:
The
collection_f
handler is triggered by the callback query. -
State check:
The
StateFilter(FSMPag.forward)
ensures the handler only executes if the current state matches. -
State set attempt:
await state.set_state(FSMPag.forward)
is called, BUT this only schedules the state change. -
Remaining handler execution:
The rest of the
collection_f
handler continues, including editing the message with the new pagination. -
Handler finishes:
The execution of
collection_f
completes WITHOUT the state being actually changed yet. -
Next interaction:
Only when another update (like a new callback or message) arrives, the FSM middleware will apply the pending state change set by
set_state
.
Therefore, although you are setting the state within the
if callback.data == 'forward'
: block, the actual state change only takes effect AFTER the current handler finishes.
Here are two possible solutions:
1. Move state change outside the conditional:
If you want the state to always change to
FSMPag.forward
regardless of the callback data, simply move
await state.set_state(FSMPag.forward)
outside the
if/elif/else
block. This ensures the state is changed before any other logic within the handler.
```python @router.callback_query(StateFilter(FSMPag.forward)) async def collection_f(callback: CallbackQuery, state: FSMContext): # ... your code ...
await state.set_state(FSMPag.forward) # Move this line here
if callback.data == 'forward':
# ... your logic ...
elif callback.data == 'backward':
# ... your logic ...
else:
pass
await callback.message.edit_media(...)
```
2. Force state change and re-route:
If you need the state change to happen immediately and influence the current handler's logic, you can force the state update and then re-route the update through the dispatcher:
```python @router.callback_query(StateFilter(FSMPag.forward)) async def collection_f(callback: CallbackQuery, state: FSMContext): # ... your code ...
if callback.data == 'forward':
await state.set_state(FSMPag.forward)
# Force state application
await state.update_data()
# Re-route the update for immediate handling
return await router.forward(callback)
elif callback.data == 'backward':
await state.set_state(FSMPag.backward)
# Force state application
await state.update_data()
# Re-route the update for immediate handling
return await router.forward(callback)
else:
pass
await callback.message.edit_media(...)
```
This approach ensures the state is applied immediately and the handler is called again with the new state, allowing you to perform different actions based on the updated state within the same interaction.
标签:python,aiogram From: 78791047