1
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【Python】クリックカウンターを作る

Last updated at Posted at 2019-03-15

概要

click.gif

・ウェブブラウジングやPC作業等で生じるクリックの回数を自動でカウントしてくれるツール
・スタートしてから終了するまでの時間とクリック回数をリアルタイムで表示
デモ(GIF)
・何かの被験者実験等に使えると思います.
・ネットになかったので作って公開してみました.

環境

・MacOS Mojave
・Python3

コード

click_count.py
from pynput import mouse
import wx
import time
import threading

class Singleton:
    _unique_instance = None
    elapsed_time = 0
    click_count = -1
    active_state = False
    
    @classmethod
    def get_instance(cls):
        if not cls._unique_instance:
            cls._unique_instance = cls()
            
        return cls._unique_instance
    def set_time(self,time):
        self.elapsed_time = time
        #print("set_time = {}".format(self.elapsed_time))

    def count_increment(self):
        self.click_count += 1
        print(self.click_count)

class AppFrame(wx.Frame):
    start_time = time.time()
    current_count = 0
    thread = None
    def __init__(self):
        wx.Frame.__init__( self, None, title="click count",size=(250, 100))
        frame = wx.Frame(None, -1, "click count")
        self.SetTransparent(255)
        self.start_time = time.time()
        main_panel = wx.Panel(self)
        date_time = wx.DateTime.Now()
        self.label_1 = wx.StaticText(main_panel, label="elapsed", pos=(20, 10))
        self.label_2 = wx.StaticText(main_panel, label="time:{0}".format(0) + "[sec]", pos=(20,10))
        self.label_3 = wx.StaticText(main_panel, label="click_count", pos=(20, 10))
        self.label_4 = wx.StaticText(main_panel, label="count:{0}".format(0), pos=(20,10))
        

        button_1 = wx.Button(main_panel, wx.ID_ANY, 'Start')
        button_2 = wx.Button(main_panel, wx.ID_ANY, 'Stop')
        
        button_1.Bind(wx.EVT_BUTTON, self.start)
        button_2.Bind(wx.EVT_BUTTON, self.stop)

        layout = wx.GridSizer(rows=3, cols=2, gap=(2, 2))
        layout.Add(self.label_1, 0, wx.GROW)
        layout.Add(self.label_2, 0, wx.GROW)
        layout.Add(self.label_3, 0, wx.GROW)
        layout.Add(self.label_4, 0, wx.GROW)
        layout.Add(button_1, 0, wx.GROW)
        layout.Add(button_2, 0, wx.GROW)
        
        main_panel.SetSizer(layout)

    
    def initialize(self):
        self.start_time = time.time()
        object = Singleton.get_instance()
        object.click_count = -1
        object.elapsed_time = 0
        object.active_state = False
        self.label_2.SetLabel("time:{0}".format(0) + "[sec]")
        
        
    def start(self,event):
        self.initialize()
        self.timer = wx.Timer(self)
        self.Bind(wx.EVT_TIMER, self.update)
        self.timer.Start(1000)
        object = Singleton.get_instance()
        object.active_state = True
        if self.thread == None:
            self.thread = threading.Thread(target=click_liten)
            self.thread.start()
        
    def stop(self,event):
        self.timer.Stop()
        
    def update(self, event):
        current_label = self.label_2.GetLabel()
        new_time = time.time()
        delta = new_time - self.start_time
        delta = int(delta)
        object = Singleton.get_instance()
        object.set_time(delta)
        self.label_2.SetLabel("time:{0}".format(delta) + "[sec]")
        
        new_count = object.click_count
        if self.current_count != new_count:
            self.current_count = new_count
            self.label_4.SetLabel("count:{0}".format(new_count))
            
def on_click(x, y, button, pressed):
    print('{0} at {1}'.format('Pressed' if pressed else 'Released',(int(x), int(y))))
    if not pressed:
        object = Singleton.get_instance()
        object.count_increment()

def click_liten():
    object = Singleton.get_instance()
    while(True):
        if(object.active_state == False):
            break
        with mouse.Listener(on_click=on_click) as listener:
            listener.join()
        

def make_view():
    app = wx.App(False)
    frame = AppFrame().Show(True)
    app.MainLoop()

make_view()

うまく動かないとき

最新のOSにアップデートするとセキュリティの関係で「環境設定」→「セキュリティとプライバシー」の「アクセアクセシビリティ」における「ターミナル」のチェックが抜けているので,チェックをつけて,ターミナル(つまりプログラム)からの操作アクセスの許可を与えてください.

そうすると正常に動きます.
security.png

1
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?