3

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.

jottbe
  • 4,228
  • 1
  • 15
  • 31
aaron
  • 31
  • 2
  • Some ui consider `on_click` as a joined version of `on_click_down` + `on_click_up` in the same position, seems like it is triggering twice click insted of `on_drag` (the x/y might be the same but it can hold a double value and not show the decimals) – SrPanda Jan 28 '21 at 16:10

1 Answers1

0

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.

Dharman
  • 30,962
  • 25
  • 85
  • 135