在Python中获取当前鼠标指针位置是微不足道的,通过使用Windows API
此外,程序员社区经常混淆鼠标指针位置和文本光标位置,这使情况变得更糟。历史上从来没有鼠标“光标”,所以当人们说“光标”时,他们应该指的是文本光标,而不是反过来。由于这个错误,Stackoverflow上充满了与“光标”相关的问题和答案,但似乎没有一个与获取终端shell的当前字符位置有关。[可怕的光标!]
要获取相对的鼠标指针位置:
我怎样才能在终端中获取 (行,列) 中的
(并且不做任何假设或编写自己的窗口管理器?) 最终我希望能够在任何终端窗口中找到最后一个光标位置,(可能被任何程序使用?)
所以考虑到这一点,我认为以下方案可行。
ctypes
库即可。然而,从鼠标指针的屏幕位置(x,y)到获取当前终端窗口的文本光标位置似乎是一个巨大的难题。此外,程序员社区经常混淆鼠标指针位置和文本光标位置,这使情况变得更糟。历史上从来没有鼠标“光标”,所以当人们说“光标”时,他们应该指的是文本光标,而不是反过来。由于这个错误,Stackoverflow上充满了与“光标”相关的问题和答案,但似乎没有一个与获取终端shell的当前字符位置有关。[可怕的光标!]
要获取相对的鼠标指针位置:
from ctypes import windll, wintypes, byref
def get_cursor_pos():
cursor = wintypes.POINT()
windll.user32.GetCursorPos(byref(cursor))
return (cursor.x, cursor.y)
while(1): print('{}\t\t\r'.format(get_cursor_pos()), end='')
我希望有一个函数,可以给我最后一个字符的位置,以及它所在的行数和列数。也许可以像这样:
def cpos():
xy = here_be_magic()
return xy
# Clear screen and start from top:
print('\x1b[H', end='');
print('12345', end='', flush=True); xy=cpos(); print('( {},{})'.format(xy[0],xy[1]),end='', flush=True)
# 12345 (1,5) # written on top of blank screen
我怎样才能在终端中获取 (行,列) 中的
text
光标位置?(并且不做任何假设或编写自己的窗口管理器?) 最终我希望能够在任何终端窗口中找到最后一个光标位置,(可能被任何程序使用?)
可能相关(但无用)的SO问题:
- 获取当前键光标位置文本 [C#]
- 如何在Windows中获取文本光标位置? [鼠标?]
- 如何在Python readline中获取当前光标位置? [鼠标?]
- 如何更改powershell控制台中的光标位置
- python ctypes,通过引用传递双指针
- Python和ctypes:如何正确地将“指向指针”的内容传递到DLL中?
更新(2022年1月17日)
查看微软文档后,我现在相信可以从(较旧的、非VT基础的)API调用GetConsoleScreenBufferInfo
中获取这个信息,如下所示。
BOOL WINAPI GetConsoleScreenBufferInfo(
_In_ HANDLE hConsoleOutput, # A handle to the console screen buffer. The handle must have the GENERIC_READ access right.
_Out_ PCONSOLE_SCREEN_BUFFER_INFO lpConsoleScreenBufferInfo # A pointer to a CONSOLE_SCREEN_BUFFER_INFO structure that receives the console screen buffer information.
);
typedef struct _CONSOLE_SCREEN_BUFFER_INFO {
COORD dwSize; # contains the size of the console screen buffer, in character columns and rows.
COORD dwCursorPosition; # contains the column and row coordinates of the cursor in the console screen buffer.
WORD wAttributes; # Character attributes (divided into two classes: color and DBCS)
SMALL_RECT srWindow; # A SMALL_RECT structure that contains the console screen buffer coordinates of the upper-left and lower-right corners of the display window.
COORD dwMaximumWindowSize; # A COORD structure that contains the maximum size of the console window, in character columns and rows, given the current screen buffer size and font and the screen size.
} CONSOLE_SCREEN_BUFFER_INFO; #
# Defines the coordinates of a character cell in a console screen buffer.
# The origin of the coordinate system (0,0) is at the top, left cell of the buffer.
typedef struct _COORD {
SHORT X; # The horizontal coordinate or column value. The units depend on the function call.
SHORT Y; # The vertical coordinate or row value. The units depend on the function call.
} COORD, *PCOORD;
typedef struct _SMALL_RECT {
SHORT Left;
SHORT Top;
SHORT Right;
SHORT Bottom;
} SMALL_RECT;
所以考虑到这一点,我认为以下方案可行。
cls='\x1b[H'
from ctypes import windll, wintypes, byref
def cpos():
cursor = wintypes._COORD(ctypes.c_short)
windll.kernel32.GetConsoleScreenBufferInfo(byref(cursor))
return (cursor.X, cursor.Y)
cpos()
# TypeError: '_ctypes.PyCSimpleType' object cannot be interpreted as an integer
dwCursorPosition
是文本光标位置(不是鼠标光标)。 - ssbssa