【问题标题】:Detecting Mouse clicks in windows using python使用python检测Windows中的鼠标点击
【发布时间】:2010-09-14 23:53:52
【问题描述】:

无论鼠标在哪个窗口中,如何检测鼠标点击?

最好在 python 中,但如果有人可以用任何语言解释它,我可能会弄明白。

我在微软的网站上找到了这个: http://msdn.microsoft.com/en-us/library/ms645533(VS.85).aspx

但我不知道如何检测或获取列出的通知。

尝试使用pygame的pygame.mouse.get_pos()函数如下:

import pygame
pygame.init()
while True:
    print pygame.mouse.get_pos()

这只是返回 0,0。 我对pygame不熟悉,是不是缺少了什么?

无论如何,我更喜欢不需要安装第 3 方模块的方法。 (除了 pywin32 http://sourceforge.net/projects/pywin32/

【问题讨论】:

  • 您使用的是哪个 UI 工具包/库?
  • 我认为这应该可以使用 win32ui 和 ctypes 来实现。发现可以用windll.user32.GetCursorPos(pointer(pt_struct))获取鼠标位置(详情:monkut.webfactional.com/blog/archive/2008/10/2/…

标签: python windows mouse


【解决方案1】:

自从提出这个问题以来,这已经是一个热门的时刻,但我想我会分享我的解决方案:我刚刚使用了内置模块 ctypes。 (我正在使用 Python 3.3 顺便说一句)

import ctypes
import time

def DetectClick(button, watchtime = 5):
    '''Waits watchtime seconds. Returns True on click, False otherwise'''
    if button in (1, '1', 'l', 'L', 'left', 'Left', 'LEFT'):
        bnum = 0x01
    elif button in (2, '2', 'r', 'R', 'right', 'Right', 'RIGHT'):
        bnum = 0x02

    start = time.time()
    while 1:
        if ctypes.windll.user32.GetKeyState(bnum) not in [0, 1]:
            # ^ this returns either 0 or 1 when button is not being held down
            return True
        elif time.time() - start >= watchtime:
            break
        time.sleep(0.001)
    return False

【讨论】:

  • 使用内置库赢得了这个(加上使用“热分钟”)
【解决方案2】:

我使用 win32api。单击任何窗口时都可以使用。

# Code to check if left or right mouse buttons were pressed
import win32api
import time

state_left = win32api.GetKeyState(0x01)  # Left button down = 0 or 1. Button up = -127 or -128
state_right = win32api.GetKeyState(0x02)  # Right button down = 0 or 1. Button up = -127 or -128

while True:
    a = win32api.GetKeyState(0x01)
    b = win32api.GetKeyState(0x02)

    if a != state_left:  # Button state changed
        state_left = a
        print(a)
        if a < 0:
            print('Left Button Pressed')
        else:
            print('Left Button Released')

    if b != state_right:  # Button state changed
        state_right = b
        print(b)
        if b < 0:
            print('Right Button Pressed')
        else:
            print('Right Button Released')
    time.sleep(0.001)

【讨论】:

    【解决方案3】:

    在程序外检测鼠标事件的唯一方法是使用SetWindowsHookEx 安装 Windows 挂钩。 pyHook 模块封装了细节。这是一个打印每次鼠标点击位置的示例:

    import pyHook
    import pythoncom
    
    def onclick(event):
        print event.Position
        return True
    
    hm = pyHook.HookManager()
    hm.SubscribeMouseAllButtonsDown(onclick)
    hm.HookMouse()
    pythoncom.PumpMessages()
    hm.UnhookMouse()
    

    您可以查看随模块安装的 example.py 脚本,了解有关 event 参数的更多信息。

    pyHook 在纯 Python 脚本中使用可能会很棘手,因为它需要一个主动的消息泵。来自tutorial

    任何希望收到的申请 全局输入事件的通知 必须有一个 Windows 消息泵。这 获得其中之一的最简单方法是 使用 PumpMessages 方法 Python 的 Win32 扩展包。 [...] 运行时,这个程序就在 空闲并等待 Windows 事件。如果 您正在使用 GUI 工具包(例如 wxPython),这个循环是不必要的 因为工具包提供了自己的。

    【讨论】:

    • 请注意,PyHook 同时移动到sourceforge.net/projects/pyhook
    • 如果你想退出导入ctypes库然后在当前线程的任何地方执行:ctypes.windll.user32.PostQuitMessage(0) 这将结束pythoncom.PumpMessages()
    • 最近,就像 Python 3.8+ 一样,pyHook 的这个分支可能会有所帮助:pypi.org/project/pyWinhook 它在 PyPI 上也很好,所以你不必直接处理 .whl 文件.普通的pip install pyWinhook 应该可以解决问题。
    【解决方案4】:

    Windows MFC(包括 GUI 编程)可通过 Python 使用 Mark Hammond 的 Python for Windows extensions 访问。 An O'Reilly Book Excerpt 来自 Hammond 和 Robinson 的 book 展示了如何挂钩鼠标消息,例如:

    self.HookMessage(self.OnMouseMove,win32con.WM_MOUSEMOVE)
    

    原始 MFC 并不容易或显而易见,但在网络上搜索 python 示例可能会产生一些可用的示例。

    【讨论】:

      【解决方案5】:

      windows 的做法是处理WM_LBUTTONDBLCLK 消息。

      要发送此信息,您的窗口类需要使用CS_DBLCLKS 类样式创建。

      恐怕我不知道如何在 Python 中应用它,但希望它能给你一些提示。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-04-18
        • 2021-09-06
        • 2015-08-03
        相关资源
        最近更新 更多