我正在尝试找到一种方法来量化我分心的频率。然而,以下技术有缺陷,但至少比没有好。我决定尝试计算计算机中的击键和鼠标点击次数。当我运行以下 python 代码时,我可以听到我的 Mac 键盘的声音,前提是我从 Mac Terminal
执行此操作并使用 sudo
:
import keyboard
def count_key_strokes():
while True:
b = keyboard.read_key()
print (b)
但是,keyboard
模块不是为 Mac 上的鼠标点击而编写的,因此我必须使用不同的模块,如下所示:
from pynput import mouse
def on_click(x, y, button, pressed):
if not pressed:
return False
def count_mouse():
d = 0
while True:
with mouse.Listener(
on_click=on_click,
) as listener:
listener.join()
d += 1
print (d)
为了同时运行这两个程序,我必须将它们连接在一起,如下所示:
import threading
''code here
threading.Thread(target=count_mouse).start()
threading.Thread(target=count_key_strokes).start()
但是,当我从 Terminal
运行该代码时,使用:
sudo python3 count_keystrokes.py
我收到以下错误消息,但不明白原因:
Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/threading.py", line 916, in _bootstrap_inner
self.run()
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/threading.py", line 864, in run
self._target(*self._args, **self._kwargs)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/keyboard/__init__.py", line 292, in listen
_os_keyboard.listen(self.direct_callback)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/keyboard/_darwinkeyboard.py", line 431, in listen
KeyEventListener(callback).run()
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/keyboard/_darwinkeyboard.py", line 366, in run
loopsource = Quartz.CFMachPortCreateRunLoopSource(None, self.tap, 0)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/objc/_lazyimport.py", line 163, in __getattr__
raise AttributeError(name)
AttributeError: CFMachPortCreateRunLoopSource
更新
真正的程序只是稍微复杂一些。真正的程序会跟踪时间,并且仅在某个应用程序位于最前面时才计算击键和鼠标点击。无论如何,20 分钟后我的电脑 (MacBookPro 2015) 总是会变慢得难以忍受。可以肯定的是,这个程序是罪魁祸首,因为当我终止它时,一切都会立即恢复正常。我的第一个解决方法是每 2 分钟重置一次程序,但这不起作用。 20 分钟后,计算机的速度仍然慢得令人难以忍受。
import keyboard, threading
from pynput import mouse
import time
from AppKit import NSWorkspace
#
totals = []
clicks = 0
def count_keystrokes():
global clicks
keystrokes = 0
elapsed = 0
minutes = 0
total_elapsed = 0
all_time = lambda x, y, z: y + (z - x) if x != 0 else 0
while True:
active_app = NSWorkspace.sharedWorkspace().activeApplication()
front_app = active_app["NSApplicationName"]
if front_app == 'PyCharm':
if elapsed == 0:
elapsed = time.time()
b = keyboard.read_key()
keystrokes += 1
else:
if elapsed > 0:
total_elapsed += (time.time() - elapsed)
elapsed = 0
if all_time(elapsed, total_elapsed, time.time()) > 30:
minutes += 1
print (f"{minutes} {keystrokes + clicks}")
# print (keystrokes + clicks)
total_elapsed = 0
elapsed = 0
keystrokes = 0
clicks = 0
def on_click(x, y, button, pressed):
if not pressed:
return False
def main():
global clicks
time1 = time.time()
thread = threading.Thread(target=count_keystrokes)
thread.daemon = True
thread.start()
while True:
clicks = 0
with mouse.Listener(on_click=on_click) as listener:
listener.join()
frontmost = NSWorkspace.sharedWorkspace().activeApplication()
if frontmost["NSApplicationName"] == 'PyCharm':
clicks += 1
if time.time() - time1 > 120:
return
thread.join()
while True:
main()
print ('main program exited')
time.sleep(1)
更新
问题肯定是线程。仅使用键盘监听运行的程序运行良好,并且不会降低计算机速度。
最佳答案
pynput.keyboard.Listener
和 pynput.mouse.Listener
都是 threading.Thread
的子类,因此不需要显式地声明完全使用线程。
with
语句,如 the documentation 中所述,只是简写:
listener.start()
try:
with_statements()
finally:
listener.stop()
而且没有必要。
脚本的简化版本可能会这样编写:
from pynput import keyboard, mouse
def on_press(key):
# A key has been pressed
pass
def on_click(x, y, button, pressed):
if pressed:
# A mouse button has been clicked
pass
with keyboard.Listener(on_press=on_press) as kl, \
mouse.Listener(on_click=on_click) as ml:
kl.join()
ml.join()
关于python - 在Mac上使用Python监听键盘并遇到AttributeError : CFMachPortCreateRunLoopSource,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52136168/