2016-11-20 11 views
1

마우스 버튼을 누르면 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 문을 사용하여이 함수에서 루프를 시작하고 종료합니다. 이 코드는 전혀 작동하지 않지만 이유를 이해할 수는 없습니다.

+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

답변을 해주셔서 대단히 감사합니다. 불행히도 나는 모호한 말로 나의 요청을 말했을 수도있다. 이 프로그램은 마우스 버튼을 누르고있는 동안 루프에서 연산을 수행하기로되어 있고 예제로 계산합니다. 다중 처리 또는 스레딩 없이는 생각할 수없는 이유는 함수에 들어가면 프로그램이 마우스 입력을 수신하는 것을 중단한다는 것입니다[email protected] – mathiasxx94