2016-11-20 84 views
1

我試圖做一個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

回答

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

這看起來非常有希望,我非常感謝你的幫助,於是有時間完全理解了線程模塊。我已經通過使用多處理更新了主帖,但是它不起作用。如果你想看看它,你非常歡迎。 – mathiasxx94

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

非常感謝您的答案意志力。不幸的是,我可能用一些含糊不清的措辭來表達我的要求。只要鼠標按鈕被按下,程序就會在循環中執行一個操作,我只是以計數爲例。我不能想到沒有多處理或線程的方式的原因是,據我所知,程序在進入函數時會停止監聽鼠標輸入。@willpower – mathiasxx94