2016-11-20 3 views
1

マウスボタンを押したときに0からカウントを開始するpythonスクリプトを作成しようとしています。私の考えはpyHookを使用してマウスの左ボタンを押したときに関数に入り、左マウスが離されたときに関数を終了することです。私はPythonにはかなり新しいので、悪い説明をして申し訳ありません。 いくつかの擬似コード:Python:マウスダウン中にカウントダウン、マウスで停止するUp

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が離散時間で起こるので、それが動作するとは思わない、私の一般的な考え方です。私が探しているのは、ある種のスレッドまたはマルチプロセッシングモジュールでcounter関数とtermin関数を実行し、ある関数で条件を使用して他の実行関数を終了させることです。しかし、私はどのようにこの仕事をするか分からない。

わかりましたので、私は意志の力さんのコメントの後に、このスクリプトを試してみました:

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プロセスでは、マウス入力に基づいてQueueに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

[OK]をクリックします。この例では、ユーザーがマウスを非常に素早くダブルクリックすると、ブレーク/スティックが発生します。これは、ロックと、ロックが解除されたときに特定のコードのみを実行するスレッドを使用します(マウスが押されたときにトリガーされます)。

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

関連する問題