Python:鼠标向下计数,当鼠标向上时停止

问题描述:

我试图做一个python脚本,当按下鼠标按钮时,它从0开始计数。我的想法是在按下鼠标左键时使用pyHook进入函数,释放鼠标左键时退出函数。我对python非常陌生,所以对于不好的解释感到抱歉。 一些伪代码: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发生在离散时间。我在寻找的可能是在某种线程或多处理模块中运行计数器函数和终止函数,并使用一个函数中的条件来终止其他运行函数。但我不确定如何使这项工作。

好了,所以我想这个脚本意志力的评论后:

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功能应该运行为单独的进程。在mousesignal过程中,我根据鼠标输入将0或1放入队列中。计数器函数连续运行并读取队列并使用if语句在此函数中输入和退出循环。此代码根本不起作用,但我无法理解为什么。

+0

只是一个建议,你可能会尝试得到一个pyhook程序的工作示例,然后尝试和调整以满足您的需求。一旦你有一个工作的例子,它会更容易帮助你。我建议这个例子作为一个可能的开始:https://gordoncluster.wordpress.com/2013/09/12/logging-all-keyboard-input-with-python-pyhook/ – willpower2727

+0

增加了工作计数器代码。 – mathiasxx94

+0

您是否有兴趣计算鼠标按钮关闭的累计时间?或者其他一些计数措施? – willpower2727

好吧,我有使用线程当鼠标按键被按下做一些事情的一个例子。如果用户非常快速地双击鼠标,该示例就会中断/被卡住。它使用一个锁和一个只有在释放锁时才执行某些代码的线程(由鼠标触发)。

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()每次用鼠标按下,它只会工作的第一次启动。通过允许线程保持活动状态,但不做任何事情(除非经常检查它是否应该),这样可以在鼠标关闭时仅执行一些代码。有一些更复杂的方法可以改善计算机上的处理负载(可能使用线程条件而不是常规锁定),但这是我的一般想法。

+0

这看起来非常有希望,我非常感谢你的帮助,于是有时间完全理解了线程模块。我已经通过使用多处理更新了主帖,但是它不起作用。如果你想看看它,你非常欢迎。 – mathiasxx94

根据您提供的示例,它看起来像要计算鼠标按钮关闭的秒数?你可以做到这一点,而不使用多个线程。下面的例子将打印时的鼠标按钮被按下的金额:

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() 
+0

非常感谢您的答案意志力。不幸的是,我可能用一些含糊不清的措辞来表达我的要求。只要鼠标按钮被按下,程序就会在循环中执行一个操作,我只是以计数为例。我不能想到没有多处理或线程的方式的原因是,据我所知,程序在进入函数时会停止监听鼠标输入。@willpower – mathiasxx94