Как сделать кнопку неактивной на 10 сек, после ее нажатия?
Есть бот на основе парсера, который собирает скидки из ситилинка. Работает все прекрасно. Но есть одно но, если пользователь нажмет много раз на кнопку «показать процессоры», то это будет много запросов, за которых можно получить флуд или ляжет бот. Можно конечно сделать так
if index % 20 == 0: tm.sleep(5)
но это просто ограничение по выводу карточек. Решение непрактичное
В итоге, как можно сделать кнопку ‘показать процессоры’ неактивной на 10 сек после нажатия на нее
Библиотека aiogram
- Вопрос задан 21 янв. 2023
- 356 просмотров
Комментировать
Решения вопроса 1
import time def callback_handler(update, context): query = update.callback_query # Disable the button context.bot.answer_callback_query(callback_query_id=query.id, text="Button disabled", show_alert=False, disable_notification=True) # Start the timer time.sleep(10) # Enable the button context.bot.answer_callback_query(callback_query_id=query.id, text="Button enabled", show_alert=False, enable_notification=True)
Ответ написан 29 янв. 2023
Константин @robocop45 Автор вопроса
Спасибо большое)
Ответы на вопрос 1
import telebot from telebot import types import threading import time bot = telebot.TeleBot("token") clicked = False timeout = 10 # Секунд def run_in_thread(func): def wrapper(*args, **kwargs): thread = threading.Thread(target=func, args=args, kwargs=kwargs) thread.start() return wrapper @run_in_thread def asynchronous(): global clicked while True: if clicked: time.sleep(timeout) clicked = False @bot.message_handler(commands=["start"]) def start(message): markup = types.InlineKeyboardMarkup() hello_button = types.InlineKeyboardButton(text="Показать процессоры", callback_data="cpu") markup.add(hello_button) bot.send_message(message.chat.id, "Здравствуйте, %s!" % (f"[](tg://user?id=)"), parse_mode="markdown", reply_markup=markup) @bot.callback_query_handler(func=lambda call: True) def callback_worker(call): global clicked if clicked: bot.answer_callback_query(call.id, "Попробуйте снова через 10 секунд!", show_alert=True) return if call.data == "cpu": clicked = True bot.send_message(call.from_user.id, "Процессоры..") if __name__ == "__main__": asynchronous() bot.polling(none_stop=True, interval=0)
в идеале конечно завести словарь формата ID: [True/False] и не использовать global
Ответ написан 21 янв. 2023
Нравится 1 2 комментария
а, простите, вам нужно сделать так, чтобы был лимит на нажатие? к примеру 1.5 сек
Константин @robocop45 Автор вопроса
HXNDY, нужно чтобы после нажатия кнопка была неактивна на сек 10-15. Ну это одно из решений. Возможно против спама можно бороться по-другому. Также я не указал что я пишу на aiogram, прошу прощения, но вы мне дали основу))
Ваш ответ на вопрос
Войдите, чтобы написать ответ

- Python
- +1 ещё
Telethon не отправляет кнопки в канал, почему?
- 1 подписчик
- 14 часов назад
- 30 просмотров
Tkinter как сделать кнопку неактивной
Одним из наиболее используемых компонентов в графических программах является кнопка. В tkinter кнопки представлены классом Button . Основные параметры виджета Button:
- command : функция, которая вызывается при нажатии на кнопку
- compund : устанавливает расположение картинки и текста относительно друг друга
- cursor : курсор указателя мыши при наведении на метку
- image : ссылка на изображение, которое отображается на метке
- pading : отступы от границ вилжета до его текста
- state : состояние кнопки
- text : устанавливает текст метки
- textvariable : устанавливает привязку к элементу StringVar
- underline : указывает на номер символа в тексте кнопки, который подчеркивается. По умолчанию значение -1, то есть никакой символ не подчеркивается
- width : ширина виджета
Добавим в окно обычную кнопку из пакета ttk:
from tkinter import * from tkinter import ttk root = Tk() root.title("METANIT.COM") root.geometry("250x200") # стандартная кнопка btn = ttk.Button(text="Button") btn.pack() root.mainloop()
Для создания кнопки используется конструктор Button() . В этом конструкторе с помощью параметра text можно установить текст кнопки.
Чтобы разместить виджет в контейнере (главном окне), у него вызывается метод pack() . На ОС Windows мы получим следующую кнопку:

Конструктор Button определяет различные параметры, которые позволяют настроить поведение и внешний вид кнопки. Однако конкретный набор параметров зависит от того, используем ли мы кнопки из пакета tkinter или из пакета tkinter.ttk.
Обработка нажатия на кнопку
Для обработки нажатия на кнопку необходимо установить в конструкторе параметр command , присвоив ему ссылку на функцию, которая будет срабатывать при нажатии:
from tkinter import * from tkinter import ttk clicks = 0 def click_button(): global clicks clicks += 1 # изменяем текст на кнопке btn["text"] = f"Clicks " root = Tk() root.title("METANIT.COM") root.geometry("250x150") btn = ttk.Button(text="Click Me", command=click_button) btn.pack() root.mainloop()
Здесь в качестве обработчика нажатия устанавливается функция click_button. В этой функции изменяется глобальная переменная clicks, которая хранит число кликов. Кроме того, изменяем текст кнопки, чтобы визуально было видно сколько нажатий произведено. Таким образом, при каждом нажатии кнопки будет срабатывать функция click_button, и количество кликов будет увеличиваться:

Отключение кнопки
Для ttk-кнопки мы можем установить отключенное состояние с помощью метода state() , передав ему значение «disabled». С такой кнопкой пользователь не сможет взаимодействовать:
from tkinter import * from tkinter import ttk root = Tk() root.title("METANIT.COM") root.geometry("250x200") btn = ttk.Button(text="Click Me", state=["disabled"]) btn.pack() root.mainloop()
При этом в метод state мы можем передать набор состояний, поэтому значение «disabled» передается внутри списка.
Как сделать так, чтобы кнопка была неактивной, пока в поле ввода не будет достаточного количества символов?
Хочу написать программу, где будет поле ввода и пока там не будет минимум 6 символов кнопка не будет активной. Я пыталась писать условием в функции кнопки, но это не совсем то.
Кратко говоря, пока в поле ввода не будет 6 символов и больше — кнопка в состоянии DISABLED
- Вопрос задан более двух лет назад
- 477 просмотров
Комментировать
Решения вопроса 1
Александр @shabelski89
import tkinter as tk root = tk.Tk() def myfunction(*args): l = 6 check_entry = stringvar1.get() if len(check_entry) >= l: button.config(state='normal') else: button.config(state='disabled') stringvar1 = tk.StringVar(root) stringvar1.trace("w", myfunction) entry1 = tk.Entry(root, width=15, textvariable=stringvar1) entry1.grid(row=1,column=1) button = tk.Button(root,text="submit", state='disabled') button.grid(row=1, column=4) root.mainloop()
Ответ написан более двух лет назад
Нравится 1 1 комментарий
Tkinter как сделать кнопку неактивной
Tkinter позволяет обрабатывать события виджетов. Для обработки распространенных и наболее используемых событий Tkinter предоставляет интерфейс команд. Например, для обработки нажатия на кнопку ее параметру command надо передать функцию, которая будет вызываться при нажатии на кнопку
def click(): print("Hello") btn = ttk.Button(text="Click", command=click)
Ряд виджетов также позволяют с помощью параметра command задать обработчик для одного из событий данного виджета.
Однако что, если мы хотим обрабатывать другие события виджета. Например, для кнопки обработать получение фокуса, или обработать нажатие клавиши клавиатуры? Для подобных ситуаций Tkinter предоставляет ряд встроенных событий. Наиболее распространенные из них:
- Activate : окно становится активным.
- Deactivate : окно становится неактивным.
- MouseWheel : прокрутка колеса мыши.
- KeyPress : нажатие клавиши на клавиатуре.
- KeyRelease : освобождение нажатой клавиши
- ButtonPress : нажатие кнопки мыши.
- ButtonRelease : освобождение кнопки мыши.
- Motion : движение мыши.
- Configure : изменение размера и положения виджета
- Destroy : удаление виджета
- FocusIn : получение фокуса
- FocusOut : потеря фокуса.
- Enter : указатель мыши вошел в пределы виджета.
- Leave : указатель мыши покинул виджет.
Привязка событий
Для привязки события к виджету применяется метод bind() :
bind(событие, функция)
В качестве первого параметра указывается обрабатываемое событие, а в качестве второго — функция, которая обрабатывает событие.
Например, обработаем события получения и потери фокуса для кнопки:
from tkinter import * from tkinter import ttk root = Tk() root.title("METANIT.COM") root.geometry("250x200") def entered(event): btn["text"] ="Entered" def left(event): btn["text"] ="Left" btn = ttk.Button(text="Click") btn.pack(anchor=CENTER, expand=1) btn.bind("", entered) btn.bind("", left) root.mainloop()
Название событие передается в угловных скобках, например, «» или «». Для события Enter (получение фокуса) определен обработчик-функция entered, которая изменяет текст кнопки:
def entered(event): btn["text"] ="Entered"
Стоит обратить внимание, что функция обработки события должна принимать в качестве параметра объект события — в примере выше параметр event, даже если он в самой функции не используется.
Событие потери фокуса связывыется с функцией left:
btn.bind("", left)

Кроме обычных событий некоторые виджеты Tkinter могут использовать виртуальные события или высокоуровневые события (выше были описаны низкоуровневые события), которые помещаются в двойные угловные скобки, например, событие выделения списка «>». Наиболее используемые виртуальные события будут рассмотрены в соответствующих темах про виджеты.
Шаблон события
В примере выше при привязке события указывалось только имя события например, «» или «». Но в реальности в угловых скобках указывается не просто имя события, а его шаблон. Шаблон события имеет следующую форму:
Модификаторы события
Часто используемые модификаторы:
- Alt : нажата клавиша Alt
- Control : нажата клавиша Ctrl
- Shift : нажата клавиша Shift
- Any : нажата любая клавиша
Клавиши
Также в шаблоне можно указать конкретные клавиши или комбинации. Некоторые из них:
- Alt_L : левая клавиша alt
- Alt_R : правая клавиша alt
- BackSpace : клавиша backspace
- Cancel : клавиша break
- Caps_Lock клавиша CapsLock
- Control_L : левая клавиша control
- Control_R : правая клавиша control
- Delete : клавиша Delete
- Down : клавиша ↓
- End : клавиша end
- Escape : клавиша esc
- Execute : клавиша SysReq
- F1 : клавиша F1
- F2 : клавиша F2
- Fi : функциональная клавиша Fi
- F12 : клавиша F12
- Home : клавиша home
- Insert : клавиша insert
- Left : клавиша ←
- Linefeed : клавиша Linefeed (control-J)
- KP_0 : клавиша 0
- KP_1 : клавиша 1
- KP_2 : клавиша 2
- KP_3 : клавиша 3
- KP_4 : клавиша 4
- KP_5 : клавиша 5
- KP_6 : клавиша 6
- KP_7 : клавиша 7
- KP_8 : клавиша 8
- KP_9 : клавиша 9
- KP_Add : клавиша +
- KP_Begin : центральная клавиша (5)
- KP_Decimal : клавиша точка ( . )
- KP_Delete : клавиша delete
- KP_Divide : клавиша /
- KP_Down : клавиша ↓
- KP_End : клавиша end
- KP_Enter : клавиша enter
- KP_Home : клавиша home
- KP_Insert : клавиша insert
- KP_Left : клавиша ←
- KP_Multiply : клавиша ×
- KP_Next : клавиша PageDown
- KP_Prior : клавиша PageUp
- KP_Right : клавиша →
- KP_Subtract : клавиша —
- KP_Up : клавиша ↑
- Next : клавиша PageDown
- Num_Lock : клавиша NumLock
- Pause : клавиша pause
- Print : клавиша PrintScrn
- Prior : клавиша PageUp
- Return : клавиша Enter
- Right : клавиша →
- Scroll_Lock : клавиша ScrollLock
- Shift_L : левая клавиша shift
- Shift_R : правая клавиша shift
- Tab : клавиша tab
from tkinter import * from tkinter import ttk root = Tk() root.title("METANIT.COM") root.geometry("250x200") def single_click(event): btn["text"] ="Single Click" def double_click(event): btn["text"] ="Double Click" btn = ttk.Button(text="Click") btn.pack(anchor=CENTER, expand=1) btn.bind("", single_click) btn.bind("", double_click) root.mainloop()
Здесь в шаблоне «» ButtonPress — название события — нажатие кнопки мыши, а «1» указывает на конкретную кнопку — левую кнопку мыши (например, 3 — представляет правую кнопку)
А в шаблоне «» добавляется модификатор Doubles , который указывает на двойное нажатие.
Глобальная регистрация события
В примерах выше обработка события устанавливалась для одного конкретного объекта — для одной кнопки. Но что, если у нас много кнопок и мы хотим, чтобы для всех была установлена привязка одного и тоже события с одной и той же функцией_обработчиком? В этом случае мы можем установить привязку события глобально ко всем объектам класса с помощью метода bind_class класса Tk:
from tkinter import * from tkinter import ttk clicks = 0 root = Tk() root.title("METANIT.COM") root.geometry("250x200") def clicked(event): global clicks clicks = clicks + 1 btn["text"] =f" Clicks" btn = ttk.Button(text="Click") btn.pack(anchor=CENTER, expand=1) # привязка события к кнопкам ttk.Button root.bind_class("TButton", "", clicked) root.mainloop()
В данном случае для кнопок для обработки двойного нажатия установаливается обработчик — функция clicked. Причем события привязывается к кнопкам из пакета tkinter.ttk, поэтому в качестве типа виджетов используется «TButton» (а не просто Button).
Удаление события
Для открепления события от виджета вызывается метод unbind() , в который передается шаблон события:
widget.unbind(event)