Как сделать остановку цикла while нажатием кнопки InlineKeyboardButton?
def crash(message): stop_signal = True markup = types.InlineKeyboardMarkup() btn1 = types.InlineKeyboardButton('СТОП', callback_data='crash_stop') markup.row(btn1) x = 1.00 crashat = round(random.uniform(1.01, 19.99), 1) bot.send_message(callback.message.chat.id, 'Нажми, чтобы остановить', reply_markup=markup) if callback.data == 'crash_stop': stop_signal = False while round(x, 1) < round(crashat, 1) or stop_signal != False: x += 0.1 bot.edit_message_text(f'{round(x, 1)}', timer_message.chat.id, timer_message.message_id) time.sleep(0.1) |
def crash(message): stop_signal = True markup = types.InlineKeyboardMarkup() btn1 = types.InlineKeyboardButton('СТОП', callback_data='crash_stop') markup.row(btn1) x = 1.00 crashat = round(random.uniform(1.01, 19.99), 1) bot.send_message(callback.message.chat.id, 'Нажми, чтобы остановить', reply_markup=markup) if callback.data == 'crash_stop': stop_signal = False while round(x, 1) < round(crashat, 1) or stop_signal != False: x += 0.1 bot.edit_message_text(f'{round(x, 1)}', timer_message.chat.id, timer_message.message_id) time.sleep(0.1)
У меня в боте есть цикл и есть кнопка, не понимаю, как сделать так, чтобы по нажатию этой кнопки цикл останавливался. Когда нажимаю кнопку, она просто зависает и реакция на нажатие происходит уже после окончания цикла, видимо кнопки с циклами не могут работать одновременно. Я понимаю, что можно сделать это с помощью команды, но хотелось бы именно кнопкой, если это возможно.
Дополнительно:
Ответы:
В while поменяйте OR на AND.
- Да, Вы правы, тут я ошибся, но на кнопку он всё равно не реагирует, точнее реагирует, но только после окончания цикла, а мне нужно, чтоб он завершился :(
- внутри while надо сделать дополнительную проверку флага stop_signal, если он False, то прерывать цикл.
Начинайте думать асинхронно и в терминах потоков, которые выполняются паралельно.
Как подобное реализовать.
бот получил команду начать цикл.
быстро ответил сообщением и запомнил номер для последующего его редактирования.
апи телеграма получило свой ответ в установленное время.
Теперь запускается новый поток, который проверяет из главного флаг (надоПрерваться)
если прошло время ожидания и нет команды остановиться - послать апи команду редактирования сообщения
заснуть до следующего раза
Если пришла команда остановиться, то поставить флаг в Труе. Ответить апи формальным ответом, что команда принята.
Все это делать с учетом, что разные пользователи могут использовать бот одновременно. То есть все еще привязовать к тиду пользователя. У каждого свой тред и флаг.
В дальнейшем подумать как не плодить треды на каждого.
Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.
Пока нет других ответов. Будьте первым, кто поможет автору.
Ответить на вопрос
Для остановки цикла while при нажатии кнопки InlineKeyboardButton вам нужно добавить условие для выхода из цикла в обработчике кнопки. Вот пример кода на языке PHP, который демонстрирует, как это можно сделать:
$stopLoop = false; while (!$stopLoop) { // ваш код, который выполняется в цикле // обработка нажатия кнопки $update = $telegram->getWebhookUpdate(); $callbackQuery = $update->getCallbackQuery(); if ($callbackQuery) { $data = $callbackQuery->getData(); if ($data == 'stop') { $stopLoop = true; } } }
В данном примере, переменная $stopLoop используется в качестве флага для контроля выполнения цикла. При каждой итерации цикла проверяется, была ли нажата кнопка InlineKeyboardButton с определенным значением ('stop' в данном случае). Если кнопка была нажата, то переменная $stopLoop устанавливается в true, что приводит к выходу из цикла.
Таким образом, вы можете остановить выполнение цикла while при нажатии кнопки InlineKeyboardButton, добавив соответствующую логику обработки нажатия в ваш код.