Пытаюсь заставить призрак всего, что находится в моем буфере обмена, появиться там, где находится мой текстовый курсор.Python

Программы на Python
Ответить Пред. темаСлед. тема
Anonymous
 Пытаюсь заставить призрак всего, что находится в моем буфере обмена, появиться там, где находится мой текстовый курсор.

Сообщение Anonymous »

Я создаю программу, которая может хранить историю буфера обмена, которую вы можете прокручивать, чтобы выбрать, что вставить. Я хочу, чтобы появился призрачный текст (там, где находится текстовый курсор) из того, что у вас сейчас есть в буфере обмена. Я пытался решить эту проблему в течение недели и несколько раз заходил в тупик.
Это тестовая программа, которая должна разобраться с призрачным отображением и показать его при нажатии клавиши CTRL, где находится курсор. но это не работает: (Положение курсора (относительно окна) всегда (0, 0), независимо от того, что я делаю)

Код: Выделить всё

class GhostDisplay:
def __init__(self):
# Initialize ghost display window
self.ghost_display = tk.Tk()
self.ghost_display.overrideredirect(1)  # Remove window decorations
self.ghost_display.attributes('-topmost', True)  # Always on top
self.ghost_display.withdraw()  # Start hidden

self.ghost_label = tk.Label(self.ghost_display, fg='white', bg='black', font=('Arial', 12))
self.ghost_label.pack()

# Thread for listening to hotkeys
self.listener_thread = threading.Thread(target=self._hotkey_listener, daemon=True)

def _get_text_cursor_position(self):
"""Get the position of the text cursor (caret) in the active window."""
try:
hwnd = win32gui.GetForegroundWindow()  # Get the handle of the active window
logging.info(f"Active window handle: {hwnd}")

caret_pos = win32gui.GetCaretPos()  # Get the caret (text cursor) position
logging.info(f"Caret position (relative to window): {caret_pos}")

rect = win32gui.GetWindowRect(hwnd)  # Get the window's position on the screen
logging.info(f"Window rectangle: {rect}")

# Calculate position relative to the screen
x, y = rect[0] + caret_pos[0], rect[1] + caret_pos[1]
logging.info(f"Text cursor position: ({x}, {y})")
return x, y
except Exception as e:
logging.error(f"Error getting text cursor position: {e}")
return None

def show_ghost(self):
"""Display the ghost near the text cursor with clipboard content."""
content = pyperclip.paste()
pos = self._get_text_cursor_position()

if pos:
x, y = pos
logging.info(f"Positioning ghost at: ({x}, {y})")
self.ghost_label.config(text=content)
self.ghost_display.geometry(f"+{x+5}+{y+20}")  # Position slightly offset from the cursor
self.ghost_display.deiconify()  # Show the ghost window
else:
# Fall back to positioning near the mouse
x, y = win32api.GetCursorPos()
logging.info(f"Falling back to mouse cursor position: ({x}, {y})")
self.ghost_label.config(text=f"(Fallback) {content}")
self.ghost_display.geometry(f"+{x+5}+{y+20}")
self.ghost_display.deiconify()

def hide_ghost(self):
self.ghost_display.withdraw()
logging.info("Ghost hidden.")

def _hotkey_listener(self):
"""Listen for hotkey to show/hide the ghost display."""
def on_press(key):
try:
if key in {keyboard.Key.ctrl_l, keyboard.Key.ctrl_r}:
logging.info("Ctrl pressed. Showing ghost.")
self.show_ghost()
except Exception as e:
logging.error(f"Error in hotkey listener (on_press): {e}")

def on_release(key):
try:
if key in {keyboard.Key.ctrl_l, keyboard.Key.ctrl_r}:
logging.info("Ctrl released. Hiding ghost.")
self.hide_ghost()

# Kill switch is Esc
if key == keyboard.Key.esc:
logging.info("ESC pressed.  Exiting program.")
self.stop()
except Exception as e:
logging.error(f"Error in hotkey listener (on_release): {e}")

with keyboard.Listener(on_press=on_press, on_release=on_release) as listener:
listener.join()

def run(self):
self.listener_thread.start()  # Start hotkey listener
self.ghost_display.mainloop()

def stop(self):
self.ghost_display.destroy()
sys.exit(0)
if __name__ == "__main__":
open("ghost_display_debug.log", "w").close()
app = GhostDisplay()
try:
app.run()
except KeyboardInterrupt:
app.stop()
Вторая проблема связана с невозможностью переопределить функцию вставки Windows. Я пытаюсь сделать так, чтобы призрак появлялся при нажатии ctrl+v (здесь вы можете пролистать историю вставок), а затем вставлять, когда нажимается ctrl+v и отпускается ctrl или v. Это мой тестовый код для блокировки функции вставки Windows по горячей клавише (F9):

Код: Выделить всё

custom_paste_enabled = True

def simulate_paste():
content = pyperclip.paste()
print(f"Custom Pasted: {content}")

def toggle_custom_paste():
global custom_paste_enabled
custom_paste_enabled = not custom_paste_enabled
print(f"Custom paste {'enabled' if custom_paste_enabled else 'disabled'}.")

def custom_paste_handler(e):
if custom_paste_enabled:
print("Ctrl+V intercepted. Suppressing OS behavior.")
simulate_paste()  # Perform custom paste
return False  # Suppress  this key event
return True  # Allow the normal paste

# Set up the hotkeys
keyboard.add_hotkey('F9', toggle_custom_paste)  # F9 to toggle custom paste
keyboard.hook(custom_paste_handler)  # Hook into all key events

print("Listening for keyboard events. F9 to toggle custom paste. Ctrl+V to test.")

try:
keyboard.wait('esc')  # Kill switch is Esc
except KeyboardInterrupt:
print("\nExiting.")
Любая помощь или предложения по этому поводу будут очень признательны и чрезвычайно полезны. Я мало что нашел об этом в Интернете, и я здесь на исходе.

Подробнее здесь: https://stackoverflow.com/questions/792 ... text-curso
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «Python»