I am making a very simple spambot for Discord just for pranking my friends. But the while True: command is very slow. Is there a faster alternative?
import PIL
import pyautogui, time
time.sleep(5)
pyautogui.FAILSAFE = True
while True:
pyautogui.hotkey("command", "v")
pyautogui.press("enter")
if (pyautogui.locateOnScreen("av.png")):
(pyautogui.click(pyautogui.locateCenterOnScreen("av.png")))
From the documentation:
Like the enchanted brooms from the Sorcerer’s Apprentice programmed to keep filling (and then overfilling) the bath with water, a bug in your program could make it go out of control. It’s hard to use the mouse to close a program if the mouse cursor is moving around on its own.
As a safety feature, a fail-safe feature is enabled by default. When a PyAutoGUI function is called, if the mouse is in any of the four corners of the primary monitor, they will raise a pyautogui.FailSafeException. There is a one-tenth second delay after calling every PyAutoGUI functions to give the user time to slam the mouse into a corner to trigger the fail safe.
You can disable this failsafe by setting pyautogui.FAILSAFE = False. I HIGHLY RECOMMEND YOU DO NOT DISABLE THE FAILSAFE.
The tenth-second delay is set by the pyautogui.PAUSE setting, which is 0.1 by default. You can change this value. There is also a pyautogui.DARWIN_CATCH_UP_TIME setting which adds an additional delay on macOS after keyboard and mouse events, since the operating system appears to need a delay after PyAutoGUI issues these events. It is set to 0.01 by default, adding an additional hundredth-second delay.
Therefore, if you want to "speed up" your loop, you can reduce the pyautogui.PAUSE value. However, keep in mind, this will prevent you from having time to activate the failsafe if you need it.
Related
I am currently trying to stop mouse clicks while my Script is running and still work with them.
If you are confused about the use case I will elaborate at the end of the question.
Currently I can get clicks like this:
import mouse
import time
def mouseHook(event):
if type(event) == mouse.ButtonEvent:
print(event)
mouse.hook(mouseHook)
while 1:
time.sleep(0.25)
But this still lets the clicks go through, how would I intercept them?
use case: simulate a monitor and while mouse is on that monitor send all movements, clicks and keypresses to MacBook (similar to Synergy, Mouse without Borders or Share Mouse)
The hook used by the application only 'hooks' into the process, which means it gets information from it, but can't insert or modify it's code.
For reference on windows that would use (https://learn.microsoft.com/en-us/previous-versions/windows/desktop/legacy/ms644988(v=vs.85))
The easiest way would be to have your application ignore the mouseclicks.
For example, with pyautogui, you can allow it to go as fast as you want with pyautogui.PAUSE = 0
Is there something similar for pynput? (Allow it to run as fast as my computer lets it?)
well I think not but u could theoretically try messing with while cycle so it would just press and release the mouse button (if it wont register the clicks u could try to import time and experiment which is the minimal delay of seconds to register those clicks)
it would look like something this:
while True:
mouse.press(Button.right)
time.sleep(0.001) #experiment with this number and see which works best
mouse.release(Button.right)
I'm learning OpenCV and I decided to make a snake game using it. It's almost done but there is a slight problem that seems simple but I couldn't find a solution.
while True:
move()
cv2.imshow('Snake Game', frame)
cv2.waitKey(250)
It's supposed to wait 250 miliseconds before the next frame but key presses break the waiting so game speeds up when I hold down a key. How can I make it ignore the keyboard events and only use time?
I would be very surprised if waitKey didn't stop the waiting after key presses. In fact the name itself suggest that. So basically it's like calling a function called max and then expect the minimum.
From your code and what you've described, you're using waitKey for two reasons:
waiting for some fixed time. That means you're using it to synchronize your game loop.
using it (maybe) to handle key presses for user interaction with the game.
In my opinion, first thing to do is to stop waiting and just keep showing frames continuously as soon as it is ready. And for synchronization you just need to save time for each frame printing. And using that time you update after user interaction or deciding how to process frame or ... One place to help you in that is to look at how game loops are implemented.Take a look here : https://gamedev.stackexchange.com/questions/651/how-should-i-write-a-main-game-loop
I have 2 different codes for the same input. The most basic one(knoptest.py(translate to buttontest.py)) works as intented. When i press the button the terminal writes "aan"(translate to "on") until i let go. However, in my more difficult code(discodouch.py(translate to discoshower)) the terminal writes "uit"(off) for a couple of times, somewhere between 1 and 20 times aprox. After then it "aan"(on) once and stays there, even without me pressing the button.
I've tried fixing it on the hardware side without any result. I've also tried copying the lines from the test file to the real file to check for spelling/other writing errors
knoptest.py:
import time
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BOARD)
GPIO.setwarnings(False)
GPIO.setup(38, GPIO.IN)
while True:
if GPIO.input(38) == 1:
print('aan')
discodouch.py:
import time
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BOARD)
GPIO.setwarnings(False)
GPIO.setup(38, GPIO.IN)
GPIO.setup(16, GPIO.OUT)
tijd = 0
GPIO.output(16, 0)
while True:
GPIO.output(16, 0)
tijd = 0
print('uit')
if GPIO.input(38) == 1:
GPIO.output(16, 1)
print('aan')
while tijd <= 2:
time.sleep(60)
tijd = tijd + 1
print('1 minuuten voorbij')
No error messages when compiling or running. However the code is supposed to jump to the "on state" when i press the button. Not after somewhere between 1 and 20 cycles at random.
TL;DR
I can't run your code on my laptop (requires a RasPi), but it sounds like you are experiencing a phenomenon called button-bouncing. Currently, your code does not handle this problem.
End TL;DR
Essentially, the button you are expecting is an ideal button. An ideal button only presses once when you push down on the button. A realistic button (the one you have) "bounces" up and down before tapering off in the depressed position. There are more discussions about this topic on the Arduino stack exchange that elaborate on this subject in much more detail.
Basically, you need to de-bounce the button so that it reads like an ideal button. You need to either use an IC (Integrated Circuit) that specifically solves this problem, some software logic, or a simple (tiny) capacitor** in series of the signal input to properly read the value of the button.
There are many different ways of solving this problem, and I haven't paid too much attention to your code, but I know, with %100 certainty, that you need to take care of button debouncing before you can reliably write programs that use buttons, and I don't see that in your code. I should mention that debouncing only matters if you care about sensitivity and timing, but I don't know the application requirements to recommend you otherwise.
Basically, without knowing the hardware configuration, that is the best I (or anybody) can give you.
** A capacitor would automatically add a delay, but it would prevent a bunch of readings of both high and low before choosing a polarity. I suggest you hook up an oscilloscope and see for yourself how the output of the button reacts.
I have a program that captures all key presses using pyHook, then runs a few functions.
I notice that after a while (of random duration), the program was stop receiving key triggers, even though I am pressing keys?
Is pyHook unstable?
I'm not changing what keys are pressed or pressing them prematurely or anything like that.
Here's my code:
import time
import win32api
import win32con
import pythoncom
import pyHook
import os
import ctypes
def Click(x,y):
win32api.SetCursorPos((x,y))
win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN,x,y,0,0)
win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP,x,y,0,0)
def DeleteRun(event):
if event.Ascii == 96:
BreakHook()
return False
Click(1250, 741)
time.sleep(0.2)
Click(649,261)
time.sleep(0.2)
Click(651, 348)
time.sleep(0.2)
Click(800, 442)
time.sleep(0.2)
Click(865, 612)
time.sleep(0.2)
Click(25, 744)
time.sleep(3)
Click(25, 744)
time.sleep(1.5)
Click(1112,297)
Click(145,392)
return True
def BreakHook():
ctypes.windll.user32.PostQuitMessage(0)
KeyGrabber = pyHook.HookManager()
KeyGrabber.KeyDown = DeleteRun
KeyGrabber.HookKeyboard()
pythoncom.PumpMessages()
Why does is suddenly stop working?
It's very frustrating as the process remains active on my computer, even if I stop the program through the IDE.
Specs:
python 2.7.2
Windows 7 (32)
Similar (dare I say identical?) problems were discussed and resolved here: pyHook + pythoncom stop working after too much keys pressed [Python]
and here: Pyhook stops capturing key events after 6 presses
You may be trying to do to much from withing the event callback.
Any event function callback as configured via HookManager and PumpMessages should return as quickly as possible.
When you press a key, Windows is kind enough to inform you of the event, but there may be other programs who also need the event. You are doing sleep calls within your event, but while you sleep, Windows is waiting for your response on THIS callback.
My guess is that after a certain number of opportunities to return in a timely manner, your event registration is being voided and ignored by Windows.
Move your sleep commands outside of the event, and instead trigger your actually click-sleep sequence outside of the hookmanager callback.
Edit: Links/Reference:
The PyHook API Documentation is one of the best (unfortunately), http://pyhook.sourceforge.net/doc_1.5.0/ If you notice the many things you can do from within the event, it becomes clear why time is of the essence. Windows wants to know how to handle the keypress (for example), and keypresses happen very fast, so it wants to know ASAP.
Its important to understand that PyHook is a very thin layer, and most of the functionality is provided by Windows, so the best documents are from MSDN http://msdn.microsoft.com/en-us/library/ms632589(v=vs.85).aspx. Also might want to take a look up a level at some of the information on 'Messages' (thats where our PumpMessages ultimately derives) The written text is very descriptive, and many of the constants and values are reflected properly through PyHook, although the good code segments are not written in Python.
Here is a pretty direct reference to proper handling of Messages (which is what hookmanager knows how to get, and by which PumpMessages delivers), http://msdn.microsoft.com/en-us/library/ms644927(v=vs.85).aspx
If a top-level window stops responding to messages for more than several seconds, the system considers the window to be not responding.
and
Message Handling
An application must remove and process messages posted to the message queues of its threads
When you call your sleeps, you are hanging in your current message, and neglecting the others that might be stacking up. Even if you grab the message and immediately return, Windows doesn't care what you do with it, as long as you are consuming.