Upload folder using huggingface_hub
Browse files- __pycache__/candidate_window.cpython-313.pyc +0 -0
- __pycache__/caret.cpython-313.pyc +0 -0
- __pycache__/engine.cpython-313.pyc +0 -0
- candidate_window.py +53 -0
- caret.py +28 -0
- main.py +37 -0
__pycache__/candidate_window.cpython-313.pyc
ADDED
|
Binary file (2.87 kB). View file
|
|
|
__pycache__/caret.cpython-313.pyc
ADDED
|
Binary file (1.43 kB). View file
|
|
|
__pycache__/engine.cpython-313.pyc
ADDED
|
Binary file (915 Bytes). View file
|
|
|
candidate_window.py
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# candidate_window.py
|
| 2 |
+
import tkinter as tk
|
| 3 |
+
from caret import get_caret_rect
|
| 4 |
+
|
| 5 |
+
class CandidateWindow:
|
| 6 |
+
def __init__(self):
|
| 7 |
+
self.root = tk.Tk()
|
| 8 |
+
self.root.overrideredirect(True) # 无边框
|
| 9 |
+
self.root.attributes("-topmost", True)
|
| 10 |
+
|
| 11 |
+
self.label = tk.Label(
|
| 12 |
+
self.root,
|
| 13 |
+
text="",
|
| 14 |
+
bg="#222",
|
| 15 |
+
fg="white",
|
| 16 |
+
font=("Segoe UI", 12),
|
| 17 |
+
justify="left",
|
| 18 |
+
padx=8,
|
| 19 |
+
pady=4
|
| 20 |
+
)
|
| 21 |
+
self.label.pack()
|
| 22 |
+
|
| 23 |
+
self.visible = False
|
| 24 |
+
|
| 25 |
+
def set_text(self, text):
|
| 26 |
+
self.label.config(text=text)
|
| 27 |
+
|
| 28 |
+
def show(self):
|
| 29 |
+
if not self.visible:
|
| 30 |
+
self.visible = True
|
| 31 |
+
self.root.deiconify()
|
| 32 |
+
|
| 33 |
+
def hide(self):
|
| 34 |
+
self.visible = False
|
| 35 |
+
self.root.withdraw()
|
| 36 |
+
|
| 37 |
+
def update_position(self):
|
| 38 |
+
rect = get_caret_rect()
|
| 39 |
+
|
| 40 |
+
if rect:
|
| 41 |
+
x = rect.left
|
| 42 |
+
y = rect.bottom + 5 # 关键:显示在光标下方
|
| 43 |
+
|
| 44 |
+
self.root.geometry(f"+{x}+{y}")
|
| 45 |
+
|
| 46 |
+
def tick(self):
|
| 47 |
+
self.update_position()
|
| 48 |
+
self.root.after(10, self.tick) # 高频刷新(输入法常见)
|
| 49 |
+
|
| 50 |
+
def start(self):
|
| 51 |
+
self.hide()
|
| 52 |
+
self.tick()
|
| 53 |
+
self.root.mainloop()
|
caret.py
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# caret.py
|
| 2 |
+
import ctypes
|
| 3 |
+
from ctypes import wintypes
|
| 4 |
+
|
| 5 |
+
class GUITHREADINFO(ctypes.Structure):
|
| 6 |
+
_fields_ = [
|
| 7 |
+
("cbSize", ctypes.c_ulong),
|
| 8 |
+
("flags", ctypes.c_ulong),
|
| 9 |
+
("hwndActive", ctypes.c_void_p),
|
| 10 |
+
("hwndFocus", ctypes.c_void_p),
|
| 11 |
+
("hwndCapture", ctypes.c_void_p),
|
| 12 |
+
("hwndMenuOwner", ctypes.c_void_p),
|
| 13 |
+
("hwndMoveSize", ctypes.c_void_p),
|
| 14 |
+
("hwndCaret", ctypes.c_void_p),
|
| 15 |
+
("rcCaret", wintypes.RECT),
|
| 16 |
+
]
|
| 17 |
+
|
| 18 |
+
def get_caret_rect():
|
| 19 |
+
info = GUITHREADINFO()
|
| 20 |
+
info.cbSize = ctypes.sizeof(GUITHREADINFO)
|
| 21 |
+
|
| 22 |
+
ctypes.windll.user32.GetGUIThreadInfo(
|
| 23 |
+
0,
|
| 24 |
+
ctypes.byref(info)
|
| 25 |
+
)
|
| 26 |
+
|
| 27 |
+
# rcCaret 是屏幕坐标(关键)
|
| 28 |
+
return info.rcCaret
|
main.py
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# main.py
|
| 2 |
+
import keyboard
|
| 3 |
+
from candidate_window import CandidateWindow
|
| 4 |
+
from engine import Engine
|
| 5 |
+
|
| 6 |
+
cw = CandidateWindow()
|
| 7 |
+
engine = Engine()
|
| 8 |
+
|
| 9 |
+
def on_key(e):
|
| 10 |
+
if e.event_type != "down":
|
| 11 |
+
return
|
| 12 |
+
|
| 13 |
+
# ESC 隐藏
|
| 14 |
+
if e.name == "esc":
|
| 15 |
+
cw.hide()
|
| 16 |
+
engine.reset()
|
| 17 |
+
return
|
| 18 |
+
|
| 19 |
+
# 普通字符
|
| 20 |
+
if len(e.name) == 1:
|
| 21 |
+
candidates = engine.input(e.name)
|
| 22 |
+
|
| 23 |
+
text = "\n".join([
|
| 24 |
+
f"{i+1}. {c}" for i, c in enumerate(candidates)
|
| 25 |
+
])
|
| 26 |
+
|
| 27 |
+
cw.set_text(text)
|
| 28 |
+
cw.show()
|
| 29 |
+
|
| 30 |
+
# 空格选择(模拟)
|
| 31 |
+
if e.name == "space":
|
| 32 |
+
engine.reset()
|
| 33 |
+
cw.hide()
|
| 34 |
+
|
| 35 |
+
keyboard.hook(on_key)
|
| 36 |
+
|
| 37 |
+
cw.start()
|