根据语言更改标志的Python脚本

问题描述 投票:0回答:1

问题描述:

我正在开发一个程序,该程序可以跟踪用户的语言,并根据检测到的语言在光标附近显示相应的标志。该标志仅应在文本光标(工字形)处于活动状态时显示,而不是在显示标准鼠标箭头时显示。

问题:

当文本光标再次变为鼠标箭头时,标志停止更新,之后标志不再变化

重现步骤:

  1. 程序应根据检测到的语言在光标附近显示一个标志。

  2. 当光标第二次变为工字形(文本光标)时,标志不再更新

预期行为:

无论是工字形光标还是标准箭头光标,该标志都应该更新并正确显示在光标附近。

import pyautogui
import win32api
import win32con
import win32gui
import ctypes
from PIL import Image, ImageTk
import tkinter as tk
import os

# Configuration
PNG_FLAGS_DIR = r'D:\work\pyProj\Mova\icons'
CURSOR_WIDTH = 20
CURSOR_HEIGHT = 16

current_language = None


# Get system language based on keyboard layout
def get_system_language():
    lang_id = ctypes.windll.user32.GetKeyboardLayout(0)
    lang_id = lang_id & 0xFFFF
    language_map = {
        0x0409: 'en',
        0x0809: 'uk',
        0x0422: 'ukr',
        0x0415: 'pl',
    }
    lang = language_map.get(lang_id, 'en')
    global current_language
    if current_language != lang:
        current_language = lang
    return current_language


# Update the flag image on the canvas based on the system language
def update_flag_image():
    lang = get_system_language()
    file_names = {
        'en': 'united-states-flag-icon.webp',
        'uk': 'united-kingdom-flag-icon.webp',
        'ukr': 'ukraine-flag-icon.webp',
        'pl': 'poland-flag-icon.webp',
    }
    png_file = file_names.get(lang, 'united-states-flag-icon.webp')
    flag_path = os.path.join(PNG_FLAGS_DIR, png_file)

    if os.path.exists(flag_path):
        try:
            flag_img = Image.open(flag_path).resize((CURSOR_WIDTH, CURSOR_HEIGHT))
            flag_img_tk = ImageTk.PhotoImage(flag_img)
            canvas.delete("all")  # Clear existing images
            canvas.create_image(0, 0, anchor='nw', image=flag_img_tk)
            canvas.image = flag_img_tk
        except Exception as e:
            print(f"Error updating flag: {e}")
    else:
        print(f"File not found: {flag_path}")


# Check if the cursor is a caret
def is_caret_cursor():
    x, y = win32api.GetCursorPos()
    hwnd = win32gui.WindowFromPoint((x, y))
    cursor_info = win32gui.GetCursorInfo()
    cursor_handle = cursor_info[1]
    return cursor_handle == win32gui.LoadCursor(None, win32con.IDC_IBEAM)


# Update the flag position and visibility based on the cursor type
def update_position():
    x, y = pyautogui.position()
    flag_width, flag_height = CURSOR_WIDTH, CURSOR_HEIGHT

    if is_caret_cursor():
        root.geometry(f'{flag_width}x{flag_height}+{int(x) + 10}+{int(y) + 10}')
        if not root.winfo_viewable():
            root.deiconify()
        update_flag_image()  # Update flag when caret is visible
    else:
        if root.winfo_viewable():
            root.withdraw()
        update_flag_image()  # Update flag even when caret is not visible

    root.after(100, update_position)


# Periodically check and update the language flag
def periodic_language_check():
    update_flag_image()
    root.after(1000, periodic_language_check)


# Tkinter setup
root = tk.Tk()
root.title("Mova")
root.geometry(f"{CURSOR_WIDTH}x{CURSOR_HEIGHT}+0+0")
root.attributes('-topmost', True)
root.attributes('-transparentcolor', 'white')
root.overrideredirect(True)

canvas = tk.Canvas(root, width=CURSOR_WIDTH, height=CURSOR_HEIGHT, bg='white', highlightthickness=0)
canvas.pack()

# Start the main loop
root.withdraw()
update_position()  # Update position and visibility
periodic_language_check()  # Update flag based on language change
root.mainloop()
python winapi
1个回答
0
投票

当光标在文本和鼠标模式之间切换时,您的代码似乎无法保持标志图像更新。这导致标志意外消失。

为了确保标志仅在可见时更新,我们将修改 update_flag_image 函数以在更新图像之前检查窗口是否显示。这是改进后的代码:

def update_flag_image():
    lang = get_system_language()
    # ... (rest of your code to get flag path)

    if os.path.exists(flag_path) and root.winfo_viewable():  # Only update if window is visible
        try:
            # ... (rest of your code to update the image on canvas)
        except Exception as e:
            print(f"Error updating flag: {e}")
    else:
        print(f"File not found: {flag_path}")

通过添加条件 root.winfo_viewable(),我们确保仅当窗口在屏幕上实际可见时才更新标志图像。这可以防止不必要的更新并确保标志在需要时正确显示。

还有,

您可能会考虑使用更高效的图像格式(例如 PNG)以获得更好的性能。 可以通过使用更具体的异常类型来改进错误处理。 对于更复杂的标志逻辑,请考虑使用专用标志类来管理其状态和行为。

我希望这有帮助!如果您还有其他问题,请告诉我。 HTH

© www.soinside.com 2019 - 2024. All rights reserved.