python keyboard wont stop once key is pressed - python

I have an endless loop in MAIN and ive looked at it so many times.
def click(x,y):
win32api.SetCursorPos((x,y))
win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN,0,0)
time.sleep(0.05)
win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP,0,0)
def click_x_box(Box_x_axis, X_axis, Y_Axis_top, Y_Axis_bottom):
#[Check if pixel is RED from top]
while pyautogui.pixel(X_axis, Y_Axis_top)[0] == 255 and pyautogui.pixel(X_axis, Y_Axis_top)[1] != 255:
# click function has no loops
click(Box_x_axis, Y_Axis_top)
Y_Axis_top += 19
print("finished top-down loop")
#[Check if pixel is RED from bottom]
while pyautogui.pixel(X_axis, Y_Axis_bottom)[0] == 255 and pyautogui.pixel(X_axis, Y_Axis_bottom)[1] != 255:
click(Box_x_axis, Y_Axis_bottom)
Y_Axis_bottom -= 19
print("finished bottom-up loop")
After I press 'q' once the "keyboard.is_pressed" line will keep re-going through, I dont know why it keeps getting through if 'q' is not being held down?
def main():
# Continue unticking boxes while 'q' is held
print("Hold 'q' to start clearing out the page of red")
while True:
if keyboard.is_pressed("q") == True:
print("q is pressed")
click_x_box(Box_x_axis, X_axis, Y_Axis_top, Y_Axis_bottom)
if __name__ == "__main__":
main()
EDIT
Ive figured out that when for whatever reason the click function is still engaging despite there being no 255,0,0 (red) on screen...

Related

Simultaneous mouse press events in Python using Pynput

I am using scrcpy to mirror an Android phone to my computer in order to play a game. The issue is that scrcpy does not support keyboard mapping natively, so I'm writing a Python script to map the keyboard to execute the key presses I need to play the game (using WASD to move around, space to jump, etc.).
I'm fairly new to programing in general and to Python in particular, but so far it's been going pretty well using Pynput. Basically, I am mapping different keys on my keyboard to correspond to mouse clicks on different areas of the screen. My issue is that, as written, my script can only push one left mouse press event at a time.
For example, pressing "w" (to move forward) and space (jump) at the same time will move the cursor to different areas on the screen, and will therefore not result in the desired outcome. The game itself supports simultaneous touch input when played on an Android screen (I can press different areas on the screen at the same time to execute certain actions), so ideally I would need my script to be able to recreate this behavior.
I was wondering if there was a way to do this in Python?
from pynput.mouse import Button, Controller
from pynput.keyboard import Key, KeyCode, Listener
global MOUSE
MOUSE = Controller()
global CENTER
global HEIGHT
CENTER = 315
HEIGHT = 800
global LISTEN
def cust_click(x,y):
MOUSE.position = (x,y)
MOUSE.press(Button.left)
def cust_mvmt_click(x, y):
MOUSE.position = (CENTER, HEIGHT)
MOUSE.press(Button.left)
MOUSE.move(x, y)
#WASD movement
def w():
cust_mvmt_click(0, -100)
def s():
cust_mvmt_click(0, 100)
def a():
cust_mvmt_click(-100, 0)
def d():
cust_mvmt_click(100, 0)
#Miscellaneous
def space():
cust_click(CENTER*5.75,HEIGHT*0.95)
def c():
cust_click(CENTER*5.15, HEIGHT*1.2)
#Weapon controls
def r():
cust_click(CENTER*4.75, HEIGHT*1.15)
def f():
cust_click(CENTER*0.5, HEIGHT*0.7)
def ctrl():
cust_click(CENTER*5.15, HEIGHT)
def q():
cust_click(CENTER*5.3, HEIGHT*0.77)
def switch1():
cust_click(CENTER*2.75, HEIGHT*1.15)
def switch2():
cust_click(CENTER*3.3, HEIGHT*1.15)
def switch3():
cust_click(CENTER*3, HEIGHT*1.05)
def on_press(key):
if key == KeyCode(char='w'):
w()
elif key == KeyCode(char='f'):
f()
elif key == Key.shift_l:
ctrl()
elif key == KeyCode(char='q'):
q()
elif key == KeyCode(char='s'):
s()
elif key == KeyCode(char='a'):
a()
elif key == KeyCode(char='d'):
d()
elif key == KeyCode(char='c'):
c()
elif key == KeyCode(char='r'):
r()
elif key == Key.space:
space()
elif key == KeyCode(char='1'):
switch1()
elif key == KeyCode(char='2'):
switch2()
elif key == KeyCode(char='3'):
switch3()
elif key == Key.tab:
LISTEN.stop()
def on_release(key):
if key == Key.shift_l or key == KeyCode(char='1') or key == KeyCode(char='f') or key == KeyCode(char='2') or key == KeyCode(char='3') or key == KeyCode(char='r') or key == KeyCode(char='c') or key == KeyCode(char='s') or key == KeyCode(char='a') or key == KeyCode(char='d') or key == Key.space or key == KeyCode(char='q') or key == KeyCode(char='w'):
MOUSE.release(Button.left)
MOUSE.position = (CENTER*390/100,HEIGHT*70/100) #1235, 565
# Collect events until released
with Listener(
on_press=on_press,
on_release=on_release) as LISTEN:
LISTEN.join()
You can use pydirectinput or pydirectinput-rgx for clicking. Check
https://www.google.com/url?sa=t&source=web&rct=j&url=https://pypi.org/project/PyDirectInput/&ved=2ahUKEwi9sbb7w6b6AhXE23MBHV85ChgQFnoECBEQAQ&usg=AOvVaw2EChi0UGXZlMafbw1aHhod
for its documentation.

IndentationError: expected an indented block in waitkey

File "<ipython-input-6-b985bbbd8c62>", line 21
cv2.rectangle(img,(ix,iy),(x,y),(255,0,0),-1)
^
IndentationError: expected an indented block
my code
import cv2
import numpy as np
#variables
#True while mouse button down, False while mouse button up
drawing = False
ix,iy = -1
#Function
def draw_rectangle(event,x,y,param,flags):
global ix,iy,drawing
if event == cv2.EVENT_LBUTTONDOWN:
drawing = True
ix,iy = x,y
elif event == cv2.EVENT_MOUSEMOVE:
if drawing == True:
cv2.rectangle(img,(ix,iy),(x,y),(255,0,0),-1)
elif event == cv2.EVENT_LBUTTONUP:
drawing = False
cv2.rectangle(img,(ix,iy),(x,y),(255,0,0),-1)
#Showing images with opencv
#black
img = np.zeros((612,612,3))
cv2.namedwindow(winname='draw_painting')
cv2.setMouseCallback('draw_painting',draw_rectangle)
while True:
cv2.imshow('draw_painting',img)
cv2.waitkey(20) & 0xFF = 27:
break
cv2.destryAllWindows()
You need to give indentation for the line after the if statement
if drawing == True:
cv2.rectangle(img,(ix,iy),(x,y),(255,0,0),-1)
This is your current code:
elif event == cv2.EVENT_MOUSEMOVE:
if drawing == True:
cv2.rectangle(img,(ix,iy),(x,y),(255,0,0),-1)
Note that, after the if statement, you need to indent your code:
elif event == cv2.EVENT_MOUSEMOVE:
if drawing == True:
cv2.rectangle(img,(ix,iy),(x,y),(255,0,0),-1)
Other errors:
Also, it seems that you intend your final if statement to be inside an if block and remember to use == rather than = to check for equality.

python curses - .getch() in newwin not working

I am attempting to make menu system using the curses module. I have the following code:
import sys, os, traceback, curses
def main(scrn):
screen = scrn
screen.border(0)
curses.start_color()
curses.init_pair(2,curses.COLOR_WHITE,curses.COLOR_BLUE)
while True:
event = screen.getch()
if event == ord("q"):
break
elif event == curses.KEY_RIGHT:
#enter function containing while loop, passing job
job_sub()
#loop to hand the subscreen for a job element
def job_sub():
screen = curses.newwin(5, 10, 3, 3)
screen.box()
objects =["RUN", "MAINTAIN", "EDIT"]
for i in range( len(objects) ):
if i == 0:
screen.addstr(i+1,1, objects[i], curses.color_pair(2))
else:
screen.addstr(i+1,1, objects[i])
screen.refresh()
while True:
event = screen.getch()
if event == curses.KEY_LEFT:
break
screen.erase()
return
if __name__=='__main__':
try:
# Initialize curses
screen=curses.initscr()
curses.noecho()
curses.cbreak()
screen.keypad(1)
main(screen)
screen.keypad(0)
curses.echo()
curses.nocbreak()
curses.endwin()
except:
# In event of error, restore terminal to sane state.
screen.keypad(0)
curses.echo()
curses.nocbreak()
curses.endwin()
traceback.print_exc()
The program runs until I hit the right arrow key. After that, it freezes, like it's stuck in a loop. It won't respond to any more input. Any help is appreciated.
In your job_sub() function you create a new window but you don't enable the keypad for it. As a result the arrow key is not sending a curses.KEY_LEFT value.

(python) How to create static text in curses

I am creating a text adventure. How could I to add static text to this.
What i mean is some text that always stays on the left side of the window. Even if all the other text is scrolling down. Also how could i make this text red.
Here is an example that shows some static text in red(that always stays on top):
import sys
import curses
curses.initscr()
if not curses.has_colors():
curses.endwin()
print "no colors"
sys.exit()
else:
curses.start_color()
curses.noecho() # don't echo the keys on the screen
curses.cbreak() # don't wait enter for input
curses.curs_set(0) # don't show cursor.
RED_TEXT = 1
curses.init_pair(RED_TEXT, curses.COLOR_RED, curses.COLOR_BLACK)
window = curses.newwin(20, 20, 0, 0)
window.box()
staticwin = curses.newwin(5, 10, 1, 1)
staticwin.box()
staticwin.addstr(1, 1, "test", curses.color_pair(RED_TEXT))
cur_x = 10
cur_y = 10
while True:
window.addch(cur_y, cur_x, '#')
window.refresh()
staticwin.box()
staticwin.refresh()
inchar = window.getch()
window.addch(cur_y, cur_x, ' ')
# W,A,S,D used to move around the #
if inchar == ord('w'):
cur_y -= 1
elif inchar == ord('a'):
cur_x -= 1
elif inchar == ord('d'):
cur_x += 1
elif inchar == ord('s'):
cur_y += 1
elif inchar == ord('q'):
break
curses.endwin()
A screenshot of the result:
Remember that windows on top must be refresh()ed last otherwise the windows that should go below are drawn over them.
If you want to change the static text do:
staticwin.clear() #clean the window
staticwin.addstr(1, 1, "insert-text-here", curses.color_pair(RED_TEXT))
staticwin.box() #re-draw the box
staticwin.refresh()
Where the 1, 1 means to start writing from the second character of the second line(remember: coordinates start at 0). This is needed since the window's box is drawn on the first line and first column.
You create static text by putting it in a separate window. Create a window large enough for all the text, and then create a smaller window for the dynamic text. Text is colored by passing the various COLOR_* constants as the text attribute.

Pygame text input not on screen

I need to kb input onto a pygame screen
at the moment it appears on the idle shell
any advice would be appreciated.
This code is extracted from a larger program
mostly screen based but i need to input some
data (numeric) from the kb at times
import sys
import pygame
from pygame.locals import *
pygame.init()
N= ''
screen = pygame.display.set_mode((600,600))
font= pygame.font.Font(None,40)
screen.fill((255,255,255))
pygame.display.flip
pygame.display.update()
def score(C,y):
SetWnd = font.render( C,True,(0,0,255))
screen.blit(SetWnd, (15, 100+y))
pygame.display.update()
def start():
while True:
name=''
for evt in pygame.event.get():
if evt.type == KEYDOWN:
if evt.unicode.isalnum(): # unicode
name+=evt.unicode
print name,
elif evt.key == K_BACKSPACE:
name = name[:-1]
print name,
elif evt.key == K_RETURN:
return N
elif evt.type == QUIT:
pygame.quit()
sys.exit()
def Pchange(c,y):
block = font.render(N, True, (0,0,0))
rect = block.get_rect()
rect.move_ip(75,100 + y)
screen.blit(block,rect)
pygame.display.flip()
score('wind', 0)
score('elev',20)
N = start()
Pchange(N,0)
Pchange(N,20)
Firstly you draw the score twice, which i assume works well.
The problem lies in you start function.
You are not calling any draw or update function in your while loop.
In your event foreach, you add a digit to name, and exit the while loop when enter is pressed. Then you draw twice with Pchange, but you are the function does not use the right parameters. You have:
def Pchange(c,y):
block = font.render(N, True, (0,0,0))
you are using the global N which is ''. So to fix that, you need to change N to c.
The next problem is that the game quits right after pressing enter. Since you pasted only a part of the program, this might not be the case. If it is, make another while loop, and just wait for the ESC key to call pygame.quit() and sys.exit()

Categories

Resources