首页 文章

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

提问于
浏览
1

我正在尝试制作一个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是在一个离散的时间发生的 . 我正在寻找的可能是在某种线程或多处理模块中运行计数器函数和终止函数,并在一个函数中使用条件来终止其他运行函数 . 但我不确定如何使这项工作 .

好的,所以我在意志力的评论之后尝试了这个脚本:

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放入队列 . 计数器函数连续运行并读取Queue并使用if语句进入并退出此函数中的循环 . 这段代码根本不起作用,但我不明白为什么 .

2 回答

  • 0

    好的我有一个使用线程在按住鼠标按钮时执行某些操作的示例 . 如果用户非常快速地双击鼠标,此示例会中断/卡住 . 它使用锁和线程,该线程仅在释放锁时执行某些代码(由鼠标按下触发) .

    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

    根据您提供的示例,您似乎想要计算鼠标按钮停止的秒数?您可以在不使用多个线程的情况下执以下示例将打印按下鼠标按钮的时间:

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

相关问题