I need help with my script below. In the simulation part of the W and S keys, it is very slow, although I have set the speed to 1ms it is being pressed very slowly. I set it to 1 millisecond, it seems like the keys are being pressed every 1 second, I wanted to make it faster, can anyone help me? I just want him to press the keys at the exact speed I set. import pyautogui import cv2 import numpy as np import tkinter as tk from tkinter import filedialog import threading import os import time import pygame from pynput.keyboard import Key, Controller, Listener import atexit import random # Inicializa o pygame para tocar os sons pygame.mixer.init() # Sons som_macro = pygame.mixer.Sound('start.wav') # Som para iniciar/parar o macro som_imagem_y = pygame.mixer.Sound('stop.wav') # Som para quando a imagem Y for detectada # Variáveis globais macro_rodando = False diretorio_imagem_y = None diretorio_imagem_x = os.path.join(os.getcwd(), "imagemX.png") # Caminho da imagem X no diretório do script teclas_alternancia = ['w', 's'] # Teclas para alternar botao_imagem_x = '4' # Botão para pressionar quando a imagem X for detectada tempo_alternancia = 0.001 # Tempo de alternância em segundos (inicialmente 1 ms) # Inicializa o controlador de teclado controlador = Controller() listener = None # Função para pressionar e soltar uma tecla def pressionar_tecla(tecla): controlador.press(tecla) controlador.release(tecla) # Função para detectar a imagem na tela def detectar_imagem(diretorio): try: if not os.path.exists(diretorio): raise ValueError(f"Arquivo de imagem não encontrado: {diretorio}") diretorio = os.path.normpath(diretorio) imagem_modelo = cv2.imdecode(np.fromfile(diretorio, dtype=np.uint8), cv2.IMREAD_COLOR) if imagem_modelo is None: raise ValueError(f"Não foi possível carregar a imagem: {diretorio}") tela = pyautogui.screenshot() tela = cv2.cvtColor(np.array(tela), cv2.COLOR_RGB2BGR) resultado = cv2.matchTemplate(tela, imagem_modelo, cv2.TM_CCOEFF_NORMED) _, max_valor, _, _ = cv2.minMaxLoc(resultado) return max_valor > 0.8 except Exception as e: print(f"Erro ao detectar a imagem: {e}") return False # Função da macro def executar_macro(): global macro_rodando, tempo_alternancia ultimo_tecla = None tempo_alternancia *= 0.1 # Reduz o tempo de alternância para acelerar o processo ultimo_tempo = time.perf_counter() while macro_rodando: if diretorio_imagem_y and detectar_imagem(diretorio_imagem_y): print("Imagem Y detectada. Parando a macro.") pygame.mixer.Sound.play(som_imagem_y) macro_rodando = False break if detectar_imagem(diretorio_imagem_x): print(f"Imagem X detectada. Clicando {botao_imagem_x}.") pressionar_tecla(botao_imagem_x) tempo_atual = time.perf_counter() if tempo_atual - ultimo_tempo >= tempo_alternancia: # Escolhe uma tecla aleatória, diferente da última tecla pressionada teclas_disponiveis = [tecla for tecla in teclas_alternancia if tecla != ultimo_tecla] if teclas_disponiveis: tecla_atual = random.choice(teclas_disponiveis) pressionar_tecla(tecla_atual) ultimo_tecla = tecla_atual ultimo_tempo = tempo_atual # Função para iniciar/parar a macro def toggle_macro(): global macro_rodando pygame.mixer.Sound.play(som_macro) if macro_rodando: print("Parando macro.") macro_rodando = False else: print("Iniciando macro.") macro_rodando = True threading.Thread(target=executar_macro).start() # Função para selecionar o diretório da imagem Y def selecionar_imagem_y(): global diretorio_imagem_y diretorio_imagem_y = filedialog.askopenfilename(title="Selecione a imagem Y") if diretorio_imagem_y: diretorio_imagem_y = os.path.abspath(diretorio_imagem_y) print(f"Imagem Y selecionada: {diretorio_imagem_y}") # Função para selecionar o diretório da imagem X def selecionar_imagem_x(): global diretorio_imagem_x diretorio_imagem_x = filedialog.askopenfilename(title="Selecione a imagem X") if diretorio_imagem_x: diretorio_imagem_x = os.path.abspath(diretorio_imagem_x) print(f"Imagem X selecionada: {diretorio_imagem_x}") # Função para selecionar o diretório da imagem X def selecionar_imagem_x(): global diretorio_imagem_x diretorio_imagem_x = filedialog.askopenfilename(title="Selecione a imagem X") if diretorio_imagem_x: diretorio_imagem_x = os.path.abspath(diretorio_imagem_x) print(f"Imagem X selecionada: {diretorio_imagem_x}") # Função para configurar as teclas e o botão def configurar(): def salvar_configuracoes(): global teclas_alternancia, botao_imagem_x, tempo_alternancia teclas_alternancia = [tecla.strip() for tecla in entrada_teclas_alternancia.get().split(',')] botao_imagem_x = entrada_botao.get().strip() try: tempo_alternancia = float(entrada_tempo.get().strip()) except ValueError: print("Valor inválido para tempo de alternância. Usando o valor padrão.") tempo_alternancia = 0.001 print(f"Configurações atualizadas: Teclas Alternância: {teclas_alternancia}, Botão Imagem X: {botao_imagem_x}, Tempo de Alternância: {tempo_alternancia} segundos") configuracoes_window.destroy() configuracoes_window = tk.Toplevel(root) configuracoes_window.title("Configurações") configuracoes_window.configure(bg='#6A0D91') configuracoes_window.attributes('-topmost', True) configuracoes_window.resizable(False, False) # Remove o tamanho fixo para permitir ajuste automático configuracoes_window.grid_columnconfigure(0, weight=1) configuracoes_window.grid_columnconfigure(1, weight=3) configuracoes_window.grid_rowconfigure(0, weight=1) configuracoes_window.grid_rowconfigure(1, weight=1) configuracoes_window.grid_rowconfigure(2, weight=1) configuracoes_window.grid_rowconfigure(3, weight=1) label_teclas_alternancia = tk.Label(configuracoes_window, text="Teclas Alternância (separadas por vírgula e espaço):", bg='#6A0D91', fg='white') label_teclas_alternancia.grid(row=0, column=0, padx=10, pady=5, sticky="w") entrada_teclas_alternancia = tk.Entry(configuracoes_window) entrada_teclas_alternancia.insert(0, ', '.join(teclas_alternancia)) entrada_teclas_alternancia.grid(row=0, column=1, padx=10, pady=5, sticky="ew") label_botao = tk.Label(configuracoes_window, text="Botão Imagem X:", bg='#6A0D91', fg='white') label_botao.grid(row=1, column=0, padx=10, pady=5, sticky="w") entrada_botao = tk.Entry(configuracoes_window) entrada_botao.insert(0, botao_imagem_x) entrada_botao.grid(row=1, column=1, padx=10, pady=5, sticky="ew") label_tempo = tk.Label(configuracoes_window, text="Tempo de Alternância (em segundos):", bg='#6A0D91', fg='white') label_tempo.grid(row=3, column=0, padx=10, pady=5, sticky="w") entrada_tempo = tk.Entry(configuracoes_window) entrada_tempo.insert(0, str(tempo_alternancia)) entrada_tempo.grid(row=3, column=1, padx=10, pady=5, sticky="ew") botao_salvar = tk.Button(configuracoes_window, text="Salvar Configurações", command=salvar_configuracoes, bg='#4B0082', fg='white') botao_salvar.grid(row=4, column=0, columnspan=2, pady=10) # Função para escutar teclas def on_press(key): if key == Key.f8: toggle_macro() # Função para encerrar o programa limpo def cleanup(): global listener if listener: listener.stop() pygame.mixer.quit() cv2.destroyAllWindows() print("Programa encerrado corretamente.") # GUI principal def criar_gui(): global root root = tk.Tk() root.title("Macro de Imagens") # Configura a cor de fundo e outras propriedades root.configure(bg='#6A0D91') # Cor de fundo roxa # Força a janela a ficar sempre no topo root.attributes('-topmost', True) # Impede o redimensionamento da janela root.resizable(False, False) # Configura o estilo dos widgets label = tk.Label(root, text="Selecione a Imagem Y para parar a macro:", bg='#6A0D91', fg='white', font=('Arial', 12)) label.pack(pady=10) botao_selecionar_x = tk.Button(root, text="Selecionar Imagem X", command=selecionar_imagem_x, bg='#4B0082', fg='white', font=('Arial', 12)) botao_selecionar_x.pack(pady=10) botao_selecionar_y = tk.Button(root, text="Selecionar Imagem Y", command=selecionar_imagem_y, bg='#4B0082', fg='white', font=('Arial', 12)) botao_selecionar_y.pack(pady=10) botao_configurar = tk.Button(root, text="Configurar Teclas e Botão", command=configurar, bg='#4B0082', fg='white', font=('Arial', 12)) botao_configurar.pack(pady=10) root.mainloop() # Inicia o listener de teclas listener = Listener(on_press=on_press) listener.start() # Inicia a interface gráfica criar_gui() # Registra a função de limpeza para ser chamada ao sair atexit.register(cleanup) The keys feel like they are being pressed in 1 second, even though I set it to 1 millisecond Continue reading...