Python获取鼠标点击时的x、y位置

34

我来自IDL,发现在Python中获取鼠标单击时的x-y位置并不容易,除了tkinter这种用大材小用的方法。有人知道是否有一个Python包含一个简单地返回x-y坐标的方法吗(类似于IDL中的cursor方法)?


6
我已经投票支持重新开放这个问题。它被关闭,原因是“范围太广”,我不同意这个理由。该作者正在询问一种在单击鼠标时获取坐标的方法,而无需使用过度复杂的tkinter(例如:https://dev59.com/pm035IYBdhLWcg3wTuJu)。这方面有什么问题吗? - Gabriel
9个回答

24

有许多库可供使用,以下是两个第三方库:

使用 PyAutoGui

一种强大的 GUI 自动化库,可以获得屏幕大小、控制鼠标、键盘等。

要获取位置,只需要使用 position() 函数即可。下面是一个示例:

>>>import pyautogui
>>>pyautogui.position()
(1358, 146)
>>>

其中1358是X位置,146是Y位置。

相关的文档链接

使用Pynput

另一个(更精简的)库是Pynput:

>>> from pynput.mouse import Controller
>>> mouse = Controller()
>>> mouse.position
(1182, 153)
>>>

其中,1182是X位置,153是秒数。

文档

这个库学起来非常容易,不需要依赖项,非常适合像这样的小任务(PyAutoGui会过度杀伤)。但是,它提供的功能并不是很多。

Windows特定:

对于特定于平台的但默认的库选项(尽管您可能仍然考虑它们为过度杀伤),可以在此处找到:Python中获取光标位置


1
但是如何在鼠标点击时执行这个操作呢? - mkrieger1
PyAutoGui使用PyScreeze来持续捕获屏幕,我认为这是因为像鼠标跟踪这样简单的操作会导致CPU使用率极高。现在这才是我所认为的过度杀伤力。 - zamarov

13

使用 PyMouse

>>> import pymouse
>>> mouse = pymouse.PyMouse()
>>> mouse.position()
(231L, 479L)

2
请参阅库 PyUserInput,它集成了 PyMouse 的代码并似乎更加现代化。 其中一个依赖项 PyHook 只有官方的32位版本,但是可以在此处找到第三方的64位安装程序 http://www.lfd.uci.edu/~gohlke/pythonlibs/#pyhook。 - Kevin
жӮЁеҸҜд»ҘйҖҡиҝҮеӯҗзұ»еҢ–PyMouseEventзұ»жқҘзӣ‘еҗ¬йј ж ҮзӮ№еҮ»дәӢ件гҖӮиҜ·еҸӮйҳ…PyUserInputйЎөйқўдёҠзҡ„вҖңClickonacciвҖқзӨәдҫӢгҖӮ - Kevin
2
这并没有回答如何在鼠标点击时获取位置。 - mkrieger1

3

我前几天写了这个函数。它可以在鼠标右键或左键点击时获取颜色或位置:

#Add Any helpfull stuff in functions here for later use
def GetMouseInfos(WhatToGet="leaving emety will get you x and y", GetXOnly=False, GetYOnly=False, GetColor=False, Key='Right', OverrideKey=False):#gets color of whats under Key cursor on right click
    try:
        import win32api
    except ModuleNotFoundError:
        print("win32api not found, to install do pip install pywin32")
    try:
        import time
    except ModuleNotFoundError:
        print("time not found, to install do pip install time?")
    try:
        import pyautogui
    except ModuleNotFoundError:
        print("py auto gui not found, to install do pip install pyautogui")
    #--------------------------------------------------------------
    #above checks if needed modules are installed if not tells user
    #code below is to get all varibles needed
    #---------------------------------------------------------------
    print(WhatToGet)
    if OverrideKey:
        Key_To_click = Key
    if Key == 'Left':
        Key_To_click = 0x01
    if Key == 'Right':
        Key_To_click = 0x02
    if Key == 'Wheel':
        Key_To_click = 0x04
    state_left = win32api.GetKeyState(Key_To_click)  # Left button up = 0 or 1. Button down = -127 or -128
    IsTrue = True
    while IsTrue:
        a = win32api.GetKeyState(Key_To_click)
        if a != state_left:  # Button state changed
            state_left = a
            if a < 0:
                global Xpos, Ypos
                Xpos, Ypos = win32api.GetCursorPos()
                x, y = pyautogui.position()
                pixelColor = pyautogui.screenshot().getpixel((x, y))
            else:
                posnowX, posnowY = win32api.GetCursorPos()
                win32api.SetCursorPos((posnowX, posnowY))
                IsTrue = False#remove this for it to keep giving coords on click without it just quitting after 1 click
        time.sleep(0.001)
    #--------------------------------------------------------------------
    #The Code above is the code to get all varibles and code below is for the user to get what he wants
    #--------------------------------------------------------------------
    
    if GetXOnly: #Checks if we should get Only X (def options) the command to do this would be GetKeyInfos("Click To get X ONLY", True)
        if GetYOnly:
            return(Xpos , Ypos)
        if GetColor:
            return(Xpos, pixelColor)
        return(Xpos)
    if GetYOnly: #Checks if we should get Only Y (def options) the command to do this would be GetKeyInfos("Click To get X ONLY",False, True)
        if GetXOnly:
            return(Xpos , Ypos)
        if GetColor:
            return(Ypos, pixelColor) 
        return(Ypos)
    if GetColor:
        return(pixelColor) #Checks 
    return(Xpos, Ypos)
# getKeyinfos("Anything here without any other guidelines will give u x and y only on right click")

3
作为示例,对于绘图或图像,可以使用名为 matplotlib 的工具,称为 ginput 。 每次单击鼠标时,所选点的[x,y]坐标存储在变量中。
# show image
fig, ax=plt.subplots()
ax.imshow(img)

# select point
yroi = plt.ginput(0,0)

使用ginput(0,0)可以在图表或图片上选择任意点。

这里是ginput文档的链接

https://matplotlib.org/3.1.1/api/_as_gen/matplotlib.pyplot.ginput.html


2

如果我使用这个,我会得到“pygame.error: video system not initialized”的错误,而如果我使用“pygame.init()”,那么无论我的光标在哪里,我都会得到一个恒定的(0,0)位置。 - Hadi Farah
2
这并没有回答如何在鼠标点击时获取位置。 - mkrieger1
这将返回鼠标在Pygame窗口中的x和y位置,而不是整个屏幕中的位置。 - hotwheel2007

1
这是一个使用tkinter的canvas的例子:

def callback(event):  
    print("clicked at: ", event.x, event.y)  

canvas.bind("<Button-1>", callback)

1

如何在不使用 Tkinter 的情况下,捕获鼠标左键点击时的坐标 (x,y)?

很简单:

  1. 安装 pynput(使用 pip install pynput 命令(不要输入'i'))。
  2. 将以下代码复制粘贴到您的编辑器中:
from pynput.mouse import Listener

def on_click(x, y, button, pressed):
    x = x
    y = y
    print('X =', x, '\nY =', y)

with Listener(on_click=on_click) as listener:
    listener.join()

我希望这可以帮助你 =D

这很简短。但是,x=xy=y是什么?你需要它们吗?如果我获得了两组坐标并希望使用这些值继续执行程序,我该如何停止循环? - theozh

1
对于海龟:

def get_mouse_click_coor(x, y):
    print(x, y)

turtle.onscreenclick(get_mouse_click_coor)

在结尾处添加turtle.mainloop(),这样当你单击时屏幕将保持打开状态。 - quicksilver

-3

你们都把它想得太难了,其实它就像这样简单:

import pyautogui as pg

pos = pg.position()

# for x pos
print(pos[0])

# for y pos
print(pos[1])

这并没有回答问题。他明确要求在不使用tkinter的情况下,在鼠标按钮被点击时返回坐标。 - C0ppert0p

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接