Friends,我正在学习创建简单的机器人.我自己也在为互联网上的问题寻找解决方案.但是现在我离不开你们的经验,我希望能得到你们的帮助!

Expected Result:

  1. 通过启动命令,我们启动机器人.
  2. 此时会出现一条消息:"来自机器人的Hello!"在它下面有一个按钮:" Select 一个城市"
  3. 当你按下按钮:" Select 一个城市"时,题词就会出现:"你的城市:"和一些带有城市名称的按钮.
  4. 用户点击其中一个带有城市名称的按钮.

5.之后,带有城市的按钮消失,发送给聊天的文本显示按下的城市名称按钮.

6.Total:在code变量中,我们获得城市的名称.

Problem:个 在第3步之后,除了单击带有城市的任何按钮外,用户还可以在文本字段中输入内容.然后折叠按钮,如果输入了按钮上指示的城市名称以外的其他内容,则该过程将停止,因为城市名称是稍后发送请求所需的参数.

Solution:个 需要在第三步之后捕获除指定按钮名称之外的任何文本输入,如果文本!=其中一个按钮的名称=>,则需要:

  1. 显示您需要 Select 城市的消息!
  2. 再次显示带有城市名称的按钮.
  3. 捕获正确的名称并将其写入变量,该名称可以通过单击按钮或用户在文本字段中输入与城市名称完全匹配的名称来获得.

Regarding the expected result,一切对我来说都解决了,但我无法处理这个问题--输入错误或用户在文本字段中意外点击……我try 将其包装在While Loop中,但无法获得正确的响应. 如何才能解决这个问题?

from aiogram import Bot, Dispatcher, executor, types
from aiogram.dispatcher.filters.state import StatesGroup, State
from aiogram.contrib.fsm_storage.memory import MemoryStorage
from aiogram.types import InlineKeyboardMarkup, InlineKeyboardButton
import asyncio
import os as OSis
 
bot = Bot(token=OSis.getenv("TOKEN"), parse_mode=types.ParseMode.HTML)
dp = Dispatcher(bot, storage=MemoryStorage())
 
 
# State class:
class UserAnswer(StatesGroup):
    City = State()
 
 
@dp.message_handler(commands="start")
async def start(message: types.Message):
    # add button:
    markup = InlineKeyboardMarkup()
    start_button = InlineKeyboardButton(text='Select a city', callback_data="town_id")
    markup.add(start_button)
    await bot.send_message(message.chat.id, "Hello from the bot!", reply_markup=markup)
 
 
# Handler for displaying the result of a button click: start_button
@dp.callback_query_handler(lambda c: c.data == "town_id")
async def button_press(call: types.callback_query):
    """Displaying a list of cities in the form of buttons"""
    list_cities = ['Washington', 'Montgomery', 'Phoenix', 'Atlanta', 'Boise', 'Frankfort', 'Boston', 'Springfield', 'Helena', 'Nashville']
    while True:
        keyboard = types.ReplyKeyboardMarkup(resize_keyboard=True, one_time_keyboard=True)
        for name in list_cities:
            keyboard.row(types.KeyboardButton(name))
        await bot.answer_callback_query(call.id)
        await bot.send_message(call.message.chat.id, "Your city:", reply_markup=keyboard)
        # Set the status for the 1st response:
        await UserAnswer.City.set()
 
        # I tried to write the code below to handle the exception...
        enter_city = await get_answer_correct(call.message)
        if any(enter_city in item for item in list_cities):
            break
        else:
            await bot.send_message(call.message.chat.id, "CHOOSE YOUR CITY:", reply_markup=keyboard)
            await asyncio.sleep(5)  # I tried to slow down the loop but it didn't work
 
@dp.message_handler(state=UserAnswer.City)
async def get_answer_correct(message: types.Message):
    # Recording the user's response after clicking the city button or entering text in the field
    answer_correct_city = message.text
    print('answer_correct_city =', answer_correct_city)
    return answer_correct_city

def main():
    executor.start_polling(dp)

if __name__ == '__main__':
    main()

推荐答案

try 使用InlineKeyboardButton,而不是像在" Select 一个城市"中那样使用简单的键盘按钮.它将如下所示:

keyboard = InlineKeyboardMarkup(one_time_keyboard=True)

for city in cities:
    new_city = InlineKeyboardButton(f"{city}", callback_data=f"{city}")
    keyboard.row(new_city)

@dp.message_handler(commands=["start"])
async def bot_message(message: types.Message):
    await bot.send_message(message.from_user.id, "Text", reply_markup=keyboard)

@dp.callback_query_handler(text="insert the name of city 1 here")
async def send_the_city(call: types.CallbackQuery):
    await bot.send_message(call.from_user.id, "Your city: Insert the name of city 1 here")
    
@dp.callback_query_handler(text="insert the name of city N here")
async def send_the_city(call: types.CallbackQuery):
    await bot.send_message(call.from_user.id, "Your city: Insert the name of city N here")

行内按钮不依赖于输入文本,因此键盘不会折叠.

Python-3.x相关问答推荐

如何验证具有内部json字符串的json字符串?

使用数据库将文件从Sharepoint下载到文件系统

向前/向后移动导致移动行的数据不可见

如何强调您正在寻求以 pandas 数据帧的另一列为条件的差异?

找到在指定列的另一个分组中存在重复的行.

在新数据帧上自动提取两个字符串 python 之间的相等性

平移数组

如何将数据框中的每一行转换为具有属性的 node ?

有没有更好的方法来判断一个数字是否是两个数字的范围

如何从 Python 3.5 降级到 Python 3.4

Visual Studio Code 中的 Python 3.x 类型提示

如何使我的课程在 Python 中非常可打印?

如何从另一个目录导入 python 包?

Python3四舍五入到最接近的偶数

Pandas 的 EMA 与股票的 EMA 不匹配?

Python中调用者函数的访问变量

Tensorflow:ImportError:libcudnn.so.7:无法打开共享对象文件:没有这样的文件或目录

将 args、kwargs 传递给 run_in_executor

无论如何我可以在 Google colaboratory 中下载文件吗?

如何在 Python 3.2 中退出?