Python mouse.Listener and keyboard.Listener events trigger twice

425 Views Asked by At

I want to gather data when playing a game so I can learn an algorith to play it later. For this I need a key and mouse logger, this logger needs to:

  • log mouse clicks and scrolls
  • log any key presses.

The problem I am having is that one mouse click/scroll and keypress gets registered twice. With Javascript I thought you could stop this by using preventDefault() but I don't know the python solution to this issue.

The following output lines represent one click:

time/button/x/y/pressed
(17:52:08.509538): click:Button.left:587:1266:True:
(17:52:08.510471): click:Button.left:587:1266:True:

I would rather not check on time difference between current and last trigger except if I don't have any other option, but I can't imagine this being the case.

I have defined my listeners as follows:

with keyboard.Listener(on_press=self.on_press) as k_listener, mouse.Listener(on_click=self.on_click, on_scroll=self.on_scroll) as m_listener:
        k_listener.join()
        m_listener.join()

The on_press, on_click and on_scroll methods look as follows:

def on_press(self, key):
    print(str(key))
    self.log_input(str(key))

def on_click(self, x, y, button, pressed):
    if pressed:
        print('click:' + str(button) + ':' + str(x) + ':' + str(y) + ':' + str(pressed) + ':')
        self.log_input('click:' + str(button) + ':' + str(x) + ':' + str(y) + ':' + str(pressed) + ':')
    else:
        pass

def on_scroll(self, x, y, dx, dy):
    print('scroll:' + str(x) + ':' + str(y) + ':' + str(dx) + ':' + str(dy) + ':')
    self.log_input('scroll:' + str(x) + ':' + str(y) + ':' + str(dx) + ':' + str(dy) + ':')  

I would like to only get these methods triggered once instead of twice.

1

There are 1 best solutions below

0
On

I can't seem to reproduce your issue, but it may be caused by your log_input. I would suggest logging your inputs through a separately defined function that would be able to append to a list or text file. Here is a simplified version using only the key press event.

def log_input(input):
    global Log
    Log.append(input)

def on_press(key):
    print(str(key))
    log_input(str(key))

The use of a separate method works in my own programs.