使用Pynput获取鼠标点按坐标无法同步到外部全局变量如何解决
问题原因
你启动的mouse.Listener是独立运行的后台子线程,主线程不会等待监听器的回调事件执行完成。你在调用listener.start()之后立刻执行外部打印语句,此时用户还没有触发鼠标点击事件,on_click回调函数还没运行,变量自然还是初始的0值。你后续看到的函数内部打印是点击鼠标后才触发的,二者执行顺序和你预期的不一致。
解决方法
方法1:等待单次点击完成后读取变量(适合单次拾取坐标的场景)
使用listener.join()阻塞主线程,直到监听器运行结束(即on_click返回False)后再读取变量,修改后的代码如下:
from pynput import mouse px = 0 py = 0 rx = 0 ry = 0 pressed_location = 0, 0 released_location = 0, 0 def on_click(x, y, button, pressed): global pressed_location global released_location global px,py,rx,ry if pressed: pressed_location = x, y px = x py = y else: released_location = x, y rx = x ry = y print('Inside function pressed at {0}x{1}'.format(*pressed_location)) print('Inside function released at {0}x{1}'.format(*released_location)) # 触发一次点击释放后停止监听 return False listener = mouse.Listener(on_click=on_click) listener.start() # 阻塞主线程,直到监听器线程结束 listener.join() # 现在再打印,变量已经被回调函数修改完成了 print ("Outside function pressed: ", px , "x" ,py) print ("Outside function released: ", rx , "x" , ry)
方法2:按需触发读取(适合持续监听的场景)
如果需要持续监听鼠标事件不需要停止监听器,可以把读取外部变量的逻辑放到其他触发条件中,比如定时轮询、业务操作触发等,只要保证读取时机晚于鼠标点击事件的触发时机,就能拿到正确的坐标值。
注意:你原来的代码中全局变量声明、赋值逻辑本身没有问题,不需要修改。另外原代码里的内部打印语句存在format参数冗余的问题,上述示例代码中已经做了修正。
内容的提问来源于stack exchange,提问作者Alan Koh W.T
相关产品推荐
相关产品推荐

