gpt4 book ai didi

python - 如何在 Windows 终端中从 Python 获取当前文本光标位置?

转载 作者:行者123 更新时间:2023-12-05 04:37:14 25 4
gpt4 key购买 nike

通过使用 Windows API ctypes 库,在 Python 中获取当前鼠标指针位置很简单。然而,似乎从鼠标指针的屏幕位置 (x,y) 开始,获取当前终端窗口的当前 text cursor 位置,似乎是难度很大。

此外,更糟糕的是,程序员社区不断混淆鼠标 指针 位置和文本 光标 位置。 Historically从来没有鼠标“光标”,所以当人们说“光标”时,他们应该指的是文本光标,而不是相反。由于这个错误,Stackoverflow 充满了与“光标”相关的问题和答案,但似乎与获取终端外壳的当前字符位置无关。 [被诅咒的光标!]

获取相对鼠标指针位置:

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

如何在我的终端中获取文本光标位置(行,列)?
(无需做任何假设并且不必编写我自己的窗口管理器?)

最终我希望用它来找到任何终端窗口中的最后一个光标位置,(并且可能被任何程序使用?)


可能相关(但没有用)SO 问题:


更新 (2022-01-17)

查看 MS 文档后,我现在确信应该可以从(较旧的、非基于 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

最佳答案

问题是定位各种结构定义。经过大量实验后,我得到了以下可行的解决方案。

#!/usr/bin/env python -u
# -*- coding: UTF-8 -*-
#------------------------------------------------------------------------------
from ctypes import windll, wintypes, Structure, c_short, c_ushort, byref, c_ulong
from readline import console

#------------------------------------------------
# Win32 API
#------------------------------------------------
SHORT = c_short
WORD = c_ushort
DWORD = c_ulong

STD_OUTPUT_HANDLE = DWORD(-11) # $CONOUT

# These are already defined, so no need to redefine.
COORD = wintypes._COORD
SMALL_RECT = wintypes.SMALL_RECT
CONSOLE_SCREEN_BUFFER_INFO = console.CONSOLE_SCREEN_BUFFER_INFO

#------------------------------------------------
# Main
#------------------------------------------------
wk32 = windll.kernel32

hSo = wk32.GetStdHandle(STD_OUTPUT_HANDLE)
GetCSBI = wk32.GetConsoleScreenBufferInfo

def cpos():
csbi = CONSOLE_SCREEN_BUFFER_INFO()
GetCSBI(hSo, byref(csbi))
xy = csbi.dwCursorPosition
return '({},{})'.format(xy.X,xy.Y)

cls='\x1b[H'
print('\n'*61)
print(cls+'12345', end='', flush=True); print(' {}'.format(cpos()), flush=True)

# 12345 (5,503)

关于python - 如何在 Windows 终端中从 Python 获取当前文本光标位置?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70732748/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com