Mouse position using python - python

I have written the following two scripts to show the current mouse position in the console:
Using tkinter:
import tkinter
import time
print('Press Ctrl-C to quit.')
p=tkinter.Tk()
try:
while True:
x, y = p.winfo_pointerxy()
positionStr = 'X: ' + str(x).rjust(4) + ' Y: ' + str(y).rjust(4)
print(positionStr, end='')
print('\b' * len(positionStr), end='', flush=True)
time.sleep(1)
except KeyboardInterrupt:
print('\n')
1535, 863
Using pyautogui
import pyautogui, sys
import time
print('Press Ctrl-C to quit.')
try:
while True:
x, y = pyautogui.position()
positionStr = 'X: ' + str(x).rjust(4) + ' Y: ' + str(y).rjust(4)
print(positionStr, end='')
print('\b' * len(positionStr), end='', flush=True)
time.sleep(1)
except KeyboardInterrupt:
print('\n')
1919, 1079
Why these two are different? What is the difference between pyautogui.position() and tkinter.winfo_pointerxy()?
The referred question in comment doesn't answer my question because I want to know the difference between the two functions and how to get similar output.

As Stated In The Original Documentation Of Both Libraries
w.winfo_pointerxy(): Returns a tuple (x, y) containing the coordinates of the mouse pointer relative to w's root window.
Tkinter Documentation
While pyautogui.position() gives with respect to the left top corner of your screen.
PyAutoGUI Documentation
Use This x = p.winfo_pointerx() - p.winfo_rootx()
y = p.winfo_pointery() - p.winfo_rooty()
To Know More Getting the absolute position of cursor in tkinter

import pyautogui
import keyboard
while keyboard.is_pressed('q') == False:
get1 = input('\nGet Cords Press Enter! \n')
pos1 = pyautogui.position()
print(str(pos1[0]) + ',' + str(pos1[1]))
This will print your x, y cords every time you press enter to the console. When you're done, you can quit by pressing Q.
Not a lot of code needed and works pretty much flawlessly.

Related

In python, how can I display my output in a external window instead of python terminal?

I try to make a countdown timer in python
could anyone help me? this is my code and I need something like the image
this is my code and I need something like the image
import time
import datetime
title = input("title: ")
year = input("year: ")
month = input("month: ")
day = input("day: ")
hour = input("hour: ")
minute = input("minute: ")
targetTime = datetime.datetime(int(year), int(month), int(day), int(hour), int(minute))
def countdown(targetTime):
while True:
difference = targetTime - datetime.datetime.now()
countHours, remainder = divmod(difference.seconds, 3600)
countMinutes, countSeconds = divmod(remainder, 60)
if difference.days == 0 and countHours == 0 and countMinutes == 0 and countSeconds == 0:
print("BOOOM!")
break
print( str(difference.days) + "d "
+ str(countHours) + "h "
+ str(countMinutes) + "m "
+ str(countSeconds) + "s " + "until "
+ str(title)
)
time.sleep(1)
countdown(targetTime)
[1]: https://i.stack.imgur.com/EJONp.png
do you really need to use tkinter?. i recommend you pysimplegui, it is pretty sweet
this is an example of a clock, which is (nearly) what you want:
import PySimpleGUI as sg
import datetime
sg.set_options(border_width=0)
sg.theme('dark')
layout = [[sg.Text('Time: '), sg.Text('', key='_time_')], [sg.Quit()]]
window = sg.Window('Simple Clock', no_titlebar=True).Layout(layout)
def getTime():
return datetime.datetime.now().strftime('%H:%M:%S')
def main(gui_obj):
while True:
event, values = gui_obj.Read(timeout=10)
if event in (None, 'Quit'):
break
gui_obj['_time_'].Update(getTime())
if __name__ == '__main__':
main(window)
Below are some tkinter commands
Entry : for entering users input
.get() : to get the user entered inputs and assign to your var's
label : for labelling text
button : to start the function
message box : to display text finally
If you are not confident with Tkinter Classes approach and want to remain on your IDE Input principle - even so as suggested by Siva is the correct approach - use for displaying opencv or plt:
e.g. opencv
create empty image in desired size
create loop
write text with actual counter time on image
image show
use dynamic wait Key to ensure every sec the pic gets updated
At the end, whatever suits you best is the best solution.

Win 10 not detecting mouse movement from Python code

I've written a small program that will move the cursor every 5 seconds if it has not been moved.
I've provided the code below.
But it seems that no matter how much I move it, Windows 10 does not recognise it's movement.
To speed up the testing, I've set Turn Off display to 1 min in the Power plan settings. When this code it run through the CMD, I can see the mouse moving back and forward, but the screen still goes to sleep after 1 min.
Is there something I'm missing here?
Thank you
#! python3
import pyautogui as p
import time as t
# CTRL+C to stop it
p.FAILSAFE = False
try:
while True:
# get current mouse position
x1,y1 = p.position()
positionStr1 = 'X: ' + str(x1).rjust(4) + ' Y: ' + str(y1).rjust(4)
print("check1")
print(positionStr1, end='')
print("\n")
# wait 5 sec
t.sleep(5)
#check the position again
x2,y2 = p.position()
positionStr2 = 'X: ' + str(x2).rjust(4) + ' Y: ' + str(y2).rjust(4)
print("check2")
print(positionStr2, end='')
print("\n")
if positionStr1 == positionStr2:
p.moveRel(200,0, duration=.1)
p.moveRel(-200,0,duration=.1)
p.moveRel(200,0, duration=.1)
p.moveRel(-200,0,duration=.1)
else:
print('mouse moved')
except KeyboardInterrupt:
print('\nDone')

Is there anyway to add a Defusal Sequence whilst a countdown is happening

I am attempting to program a defusable bomb for a csgo prop and was trying to make it as close as i can to the original thing. I have got everything working smoothly. An entry code and a Timer. The only thing I need to do is add a defusable section to it. Whilst the Bombs timer is running I would need to be able to cancel that action with an Input Code. Where, and what would I put?
I have tried doing a
defuse = input("Defusal Code")
if defuse == "7355608":
break
import time
while True:
uin = input("")
try:
when_to_stop = abs(int(uin))
except KeyboardInterrupt:
break
except:
print("NAN!")
while when_to_stop > 0:
s, ms = divmod(when_to_stop, 100)
m, s = divmod(s, 60)
time_left = str(m).zfill(2) + ":" + str(s).zfill(2) + ":" + str(ms).zfill(2)
print(time_left, end="\r")
time.sleep(0.01)
when_to_stop -=1
print()
print("BOMB DETONATED")

How to delete the previous print() using '\b'

Im using Pyautogui to print mouse's current position.
After i print the first coordinates, i want to delete it instantly and print the next coordinates.
import pyautogui as p
print('Press Ctrl-C to quit.')
try:
while True:
x, y = p.position()
positionStr = 'X: ' + str(x).rjust(4) + ' Y: ' + str(y).rjust(4)
print(positionStr, end='') #printing current position
print('\b' * len(positionStr), end='', flush=True) #deleting previous print
except KeyboardInterrupt:
print('\nDone')
Instead of deleting the previous print, it prints the next coordinates with some weird squares.

How to get rid of frame 'blinking' effect with standard libs?

I am currently playing with some cmd/prompt animations/graphics:
import os
import time
def printFrame(timeout, count):
os.system('cls')
l=0
while True:
for k in range(0,9):
for i in range(0,9):
for j in range(0,9):
if j == k and i != 4:
print("|", end="", flush=True)
elif j !=k and i == 4:
print("-", end="", flush=True)
elif j ==k and i == 4:
print("+", end="", flush=True)
else:
print("O", end="", flush=True)
print("")
time.sleep(timeout)
os.system('cls')
l += 1
if l > count:
break
if __name__ == "__main__":
printFrame(0.08, 2)
and i want to get rid of frame blinking - especialy visible in first line, my idea was to use second printing thread:
def printFrame(timeout, count):
#print from example1
def printFrameTwo(timeout, count):
#print from example1 without os.system('cls')
if __name__ == "__main__":
p1 = threading.Thread(target = printFrame, args = (0.08, 2))
p2 = threading.Thread(target = printFrameTwo, args = (0.08, 2))
p1.start()
p2.start()
but the effect was rather disappointing - problems with synchronization and first line still very blinky, second idea was to use 'predefined frames' - but its not very educating - the bonus here is that I can print whole line at once, but still effect is not as expected, third (most promising) idea is to only change necessary 'pixels'/chars in frame - but here I need to move in frame between lines! and curses is not working on windows (at least not in standard). Do you maybe have some ideas how to bite it? (windows, standard libraries) maybe how to speed up 'os.system('cls')'?
I figured it out... You can use ANSI codes to move the cursor then clear the lines without any BLINK!
print('\033[4A\033[2K', end='')
\033[4A Moves the cursor 4 lines up (\033[{lines}A you can replace lines with however many you need) \033[2K Clears all those lines without the screen blinking. You can use it in a simple typewrite function that needs a constant message or a box around it like this:
from time import sleep
def typewrite(text: str):
lines = text.split('\n')
for line in lines:
display = ''
for char in line:
display += char
print(f'╭─ SOME MESSAGE OR SOMEONES NAME ────────────────────────────────────────────╮')
print(f'│ {display:74} │') # :74 is the same as ' ' * 74
print(f'╰────────────────────────────────────────────────────────────────────────────╯')
sleep(0.05)
print('\033[3A\033[2K', end='')
The only problem with this is that the top line is blinking. To fix this all we need to do is to add a empty line that is blinking so the user cant see it. We also move the cursor up from 3 to 4 lines.
def typewrite(text: str):
lines = text.split('\n')
for line in lines:
display = ''
for char in line:
display += char
print('')
print(f'╭─ SOME MESSAGE OR SOMEONES NAME ────────────────────────────────────────────╮')
print(f'│ {display:74} │') # :74 is the same as ' ' * 74
print(f'╰────────────────────────────────────────────────────────────────────────────╯')
sleep(0.05)
print('\033[4A\033[2K', end='')
To make this into your code just print your text and add a print('') at the start. Then use this print('\033[4A\033[2K', end='') but change the 4 to however many lines that you printed including the print(''). Then it should work without blinking. You can put print('\033[4B', end='') at the end which just moves the cursor back up.
If you want to hide the cursor you can use this gibberish or make the cursor the same color as the background:
import ctypes
if os.name == 'nt':
class _CursorInfo(ctypes.Structure):
_fields_ = [("size", ctypes.c_int),
("visible", ctypes.c_byte)]
def hide_cursor() -> None:
if os.name == 'nt':
ci = _CursorInfo()
handle = ctypes.windll.kernel32.GetStdHandle(-11)
ctypes.windll.kernel32.GetConsoleCursorInfo(handle, ctypes.byref(ci))
ci.visible = False
ctypes.windll.kernel32.SetConsoleCursorInfo(handle, ctypes.byref(ci))
def show_cursor() -> None:
if os.name == 'nt':
ci = _CursorInfo()
handle = ctypes.windll.kernel32.GetStdHandle(-11)
ctypes.windll.kernel32.GetConsoleCursorInfo(handle, ctypes.byref(ci))
ci.visible = True
ctypes.windll.kernel32.SetConsoleCursorInfo(handle, ctypes.byref(ci))
Note: All of this is still new to me so I am still testing this out to fully understand it.

Categories