Python: 鼠标按下时计数,鼠标向上时停止
Python: Counting while mouse Down, stop when mouse Up
我正在尝试制作一个 python 脚本,它在按下鼠标按钮时从 0 开始计数。我的想法是使用 pyHook 在按下鼠标左键时进入一个函数,并在释放鼠标左键时退出该函数。我是 python 的新手,很抱歉解释不当。
一些伪代码:
import pyHook
import pythoncom
def termin():
return None
def counter(tell):
a=0
while True:
print a
a+=1
hm = pyHook.HookManager()
hm.SubscribeMouseLeftUp(termin)
hm = pyHook.HookManager()
hm.SubscribeMouseLeftDown(counter)
hm.HookMouse()
pythoncom.PumpMessages()
hm.UnhookMouse()
此代码是我的一般想法,但我认为它不会起作用,因为 SubscribeMouseLeftUp 发生在离散时间。我正在寻找的可能是 运行 在某种线程或多处理模块中使用计数器函数和终止函数,并在一个函数中使用条件来终止另一个 运行ning 函数。但我不确定如何进行这项工作。
好的,所以我在 willpower 的评论后尝试了这个脚本:
import pyHook,time,pythoncom
def counter(go):
for a in range(5):
time.sleep(1)
print a
return True
hm=pyHook.HookManager()
hm.SubscribeMouseLeftDown(counter)
hm.HookMouse()
pythoncom.PumpMessages()
hm.UnhookMouse()
willpower2727 接受的答案是迄今为止我见过的最好的解决方案。在他使用线程发布他的解决方案之前,我编写了以下代码:
from multiprocessing import Process,Queue
import pyHook
import time
import pythoncom
import ctypes
def counter(tellerstate,q):
while True:
a=0
tellerstate=q.get()
if tellerstate==1:
while True:
a+=1
print a
tellerstate=q.get()
if tellerstate==0:
break
time.sleep(0.1)
def mousesignal(q):
def OnDown(go):
tellstate=1
q.put(tellstate)
return None
def OnUp(go):
tellstate=0
q.put(tellstate)
return None
def terminate(go):
if chr(go.Ascii)=='q' or chr(go.Ascii)=='Q':
ctypes.windll.user32.PostQuitMessage(0)
hm.UnhookKeyboard()
hm.UnhookMouse()
q.close()
q.join_thread()
process_counter.join()
process_mousesignal.join()
return None
hm=pyHook.HookManager()
hm.KeyDown = terminate
hm.MouseLeftDown = OnDown
hm.MouseLeftUp = OnUp
hm.HookMouse()
hm.HookKeyboard()
pythoncom.PumpMessages()
if __name__ == '__main__':
tellerstate=0
q=Queue()
process_counter = Process(target=counter,args=(tellerstate,q))
process_mousesignal = Process(target=mousesignal,args=(q,))
process_mousesignal.start()
process_counter.start()
我对这段代码的预期行为是计数器和鼠标信号函数应该 运行 作为单独的进程。在 mousesignal 过程中,我根据鼠标输入将 0 或 1 放入队列。计数器函数 运行 连续读取队列并使用 if 语句进入和退出此函数中的循环。这段代码根本不起作用,但我不明白为什么。
根据您提供的示例,您似乎想要计算按下鼠标按钮的秒数?您可以在不使用多线程的情况下执行此操作。以下示例将打印按下鼠标按钮的时间量:
import pyHook
import time
import pythoncom
global starttime
starttime = time.time()
global endtime
endtime = time.time()
def OnDown(go):
global starttime
starttime = time.time()
return True
def OnUp(go):
global starttime
global endtime
endtime = time.time()
etime = endtime-starttime
print(etime)
return True
hm = pyHook.HookManager()
hm.MouseLeftDown = OnDown
hm.MouseLeftUp = OnUp
hm.HookMouse()
pythoncom.PumpMessages()
好的,我有一个在按住鼠标按钮时使用线程执行某些操作的示例。如果用户快速双击鼠标,此示例 breaks/gets 会卡住。它使用一个锁和一个线程,该线程仅在释放锁(由鼠标按下触发)时执行某些代码。
import time
import threading
import pyHook
import pythoncom
def DoThis(Cond):
while True:
with Cond: #calling "with" automatically calls acquire() on the lock
print(time.time())
print('stopping...')
global Cond
Cond = threading.Lock()#create a threading lock
Cond.acquire() #give the lock to the main thread
global t1
t1 = threading.Thread(target=DoThis,args=(Cond, )) #initialize the thread that does stuff while mouse button is down
t1.start() #start the thread, it won't do anything until mouse button is down
def OnDown(go):
global Cond
Cond.release() #allow the thread to acquire the lock
print('Lock released')
return True
def OnUp(go):
global Cond
Cond.acquire() #take the lock away from the thread
print('Lock acquired')
return True
hm = pyHook.HookManager()
hm.MouseLeftDown = OnDown
hm.MouseLeftUp = OnUp
hm.HookMouse()
pythoncom.PumpMessages()
使用线程的挑战在于它们只能启动一次,因此您不能在每次按下鼠标时调用 thread.start(),它只会在第一次运行。通过允许线程保持活动状态但不做任何事情(除了不断检查它是否应该),可以只在鼠标按下时执行一些代码。有一些更复杂的方法可以提高计算机的处理负载(可能使用线程条件而不是常规锁),但这是我的一般想法。
我正在尝试制作一个 python 脚本,它在按下鼠标按钮时从 0 开始计数。我的想法是使用 pyHook 在按下鼠标左键时进入一个函数,并在释放鼠标左键时退出该函数。我是 python 的新手,很抱歉解释不当。 一些伪代码:
import pyHook
import pythoncom
def termin():
return None
def counter(tell):
a=0
while True:
print a
a+=1
hm = pyHook.HookManager()
hm.SubscribeMouseLeftUp(termin)
hm = pyHook.HookManager()
hm.SubscribeMouseLeftDown(counter)
hm.HookMouse()
pythoncom.PumpMessages()
hm.UnhookMouse()
此代码是我的一般想法,但我认为它不会起作用,因为 SubscribeMouseLeftUp 发生在离散时间。我正在寻找的可能是 运行 在某种线程或多处理模块中使用计数器函数和终止函数,并在一个函数中使用条件来终止另一个 运行ning 函数。但我不确定如何进行这项工作。
好的,所以我在 willpower 的评论后尝试了这个脚本:
import pyHook,time,pythoncom
def counter(go):
for a in range(5):
time.sleep(1)
print a
return True
hm=pyHook.HookManager()
hm.SubscribeMouseLeftDown(counter)
hm.HookMouse()
pythoncom.PumpMessages()
hm.UnhookMouse()
willpower2727 接受的答案是迄今为止我见过的最好的解决方案。在他使用线程发布他的解决方案之前,我编写了以下代码:
from multiprocessing import Process,Queue
import pyHook
import time
import pythoncom
import ctypes
def counter(tellerstate,q):
while True:
a=0
tellerstate=q.get()
if tellerstate==1:
while True:
a+=1
print a
tellerstate=q.get()
if tellerstate==0:
break
time.sleep(0.1)
def mousesignal(q):
def OnDown(go):
tellstate=1
q.put(tellstate)
return None
def OnUp(go):
tellstate=0
q.put(tellstate)
return None
def terminate(go):
if chr(go.Ascii)=='q' or chr(go.Ascii)=='Q':
ctypes.windll.user32.PostQuitMessage(0)
hm.UnhookKeyboard()
hm.UnhookMouse()
q.close()
q.join_thread()
process_counter.join()
process_mousesignal.join()
return None
hm=pyHook.HookManager()
hm.KeyDown = terminate
hm.MouseLeftDown = OnDown
hm.MouseLeftUp = OnUp
hm.HookMouse()
hm.HookKeyboard()
pythoncom.PumpMessages()
if __name__ == '__main__':
tellerstate=0
q=Queue()
process_counter = Process(target=counter,args=(tellerstate,q))
process_mousesignal = Process(target=mousesignal,args=(q,))
process_mousesignal.start()
process_counter.start()
我对这段代码的预期行为是计数器和鼠标信号函数应该 运行 作为单独的进程。在 mousesignal 过程中,我根据鼠标输入将 0 或 1 放入队列。计数器函数 运行 连续读取队列并使用 if 语句进入和退出此函数中的循环。这段代码根本不起作用,但我不明白为什么。
根据您提供的示例,您似乎想要计算按下鼠标按钮的秒数?您可以在不使用多线程的情况下执行此操作。以下示例将打印按下鼠标按钮的时间量:
import pyHook
import time
import pythoncom
global starttime
starttime = time.time()
global endtime
endtime = time.time()
def OnDown(go):
global starttime
starttime = time.time()
return True
def OnUp(go):
global starttime
global endtime
endtime = time.time()
etime = endtime-starttime
print(etime)
return True
hm = pyHook.HookManager()
hm.MouseLeftDown = OnDown
hm.MouseLeftUp = OnUp
hm.HookMouse()
pythoncom.PumpMessages()
好的,我有一个在按住鼠标按钮时使用线程执行某些操作的示例。如果用户快速双击鼠标,此示例 breaks/gets 会卡住。它使用一个锁和一个线程,该线程仅在释放锁(由鼠标按下触发)时执行某些代码。
import time
import threading
import pyHook
import pythoncom
def DoThis(Cond):
while True:
with Cond: #calling "with" automatically calls acquire() on the lock
print(time.time())
print('stopping...')
global Cond
Cond = threading.Lock()#create a threading lock
Cond.acquire() #give the lock to the main thread
global t1
t1 = threading.Thread(target=DoThis,args=(Cond, )) #initialize the thread that does stuff while mouse button is down
t1.start() #start the thread, it won't do anything until mouse button is down
def OnDown(go):
global Cond
Cond.release() #allow the thread to acquire the lock
print('Lock released')
return True
def OnUp(go):
global Cond
Cond.acquire() #take the lock away from the thread
print('Lock acquired')
return True
hm = pyHook.HookManager()
hm.MouseLeftDown = OnDown
hm.MouseLeftUp = OnUp
hm.HookMouse()
pythoncom.PumpMessages()
使用线程的挑战在于它们只能启动一次,因此您不能在每次按下鼠标时调用 thread.start(),它只会在第一次运行。通过允许线程保持活动状态但不做任何事情(除了不断检查它是否应该),可以只在鼠标按下时执行一些代码。有一些更复杂的方法可以提高计算机的处理负载(可能使用线程条件而不是常规锁),但这是我的一般想法。