当用户输入某些内容时,我正在try 打开一个弹出窗口.

我在某处读到,Windows只允许您在从主窗口调用弹出窗口的情况下对其进行聚焦.

我在网上搜索了一下,发现这个"变通办法"并不是很有效,因为强制聚焦的方法不起作用:

def bring_window_to_foreground(self):
       self.top_window.update_idletasks()
       hwnd = win32gui.FindWindow(None, "Select Expansion")
       shell = win32com.client.Dispatch("WScript.Shell")
       shell.SendKeys("%")
       time.sleep(0.1)
       shell.SendKeys("%")
       win32gui.SetForegroundWindow(hwnd)
       # Send another Alt key to nullify the activation
       self.top_window.focus_force()

但有时这不起作用,应用程序使用"ALT"键来显示菜单,如记事本,有时会出现问题.

有没有什么库或Windows API可以用来将我的tkinter窗口发送到前台,总是在顶部和焦点上,而不是从主窗口应用程序调用它,它将被最小化?

还有一个问题?如何在文本光标的同一位置或更靠近文本光标的位置显示此弹出窗口?我正在使用下面的代码,但不起作用:

def get_caret_position(self):
        class GUITHREADINFO(ctypes.Structure):
            _fields_ = [("cbSize", ctypes.c_ulong),
                        ("flags", ctypes.c_ulong),
                        ("hwndActive", ctypes.wintypes.HWND),
                        ("hwndFocus", ctypes.wintypes.HWND),
                        ("hwndCapture", ctypes.wintypes.HWND),
                        ("hwndMenuOwner", ctypes.wintypes.HWND),
                        ("hwndMoveSize", ctypes.wintypes.HWND),
                        ("hwndCaret", ctypes.wintypes.HWND),
                        ("rcCaret", ctypes.wintypes.RECT)]
 
        guiThreadInfo = GUITHREADINFO(cbSize=ctypes.sizeof(GUITHREADINFO))
     
        hwnd = win32gui.GetForegroundWindow()
     
        processID = ctypes.c_ulong()
        threadID = ctypes.windll.user32.GetWindowThreadProcessId(hwnd, ctypes.byref(processID))  # <-- Corrected line
     
        if ctypes.windll.user32.GetGUIThreadInfo(threadID, ctypes.byref(guiThreadInfo)):
            caret_x = guiThreadInfo.rcCaret.left
            caret_y = guiThreadInfo.rcCaret.top
            return caret_x, caret_y
        else:
            return None, None

推荐答案

以下是我的解决方案代码:

def create_popup(tk_queue, key_listener_instance):
    print("Entered create_popup")  # Debugging
    while True:
        queue_data = tk_queue.get()
        msg, data = queue_data[:2]  # Only take the first two values
 
        current_window = getActiveWindow()
        current_win_title = current_window.title if current_window else "Unknown Window"
         
        if msg == "create_popup":
            print("About to stop listener and create popup")  # Debugging
            key_listener_instance.stop_listener()
 
            windows = gw.getWindowsWithTitle(current_win_title)
            if windows:
                main_win = windows[0]
                pyautogui.click(main_win.left + 10, main_win.top + 10)
            else:
                print(f"No window with title '{current_win_title}' found.")
 
            popup = ctk.CTk()  # Use ctk instead of tk
            popup.title("Select Expansion")
 
            for i, option in enumerate(key_listener_instance.expansions_list):
                raw_button_text = option['expansion'] if 'expansion' in option else "Undefined"
                button_text = truncate_text(raw_button_text, 60)
                button = ctk.CTkButton(
                    popup,
                    text=button_text,
                    command=partial(key_listener_instance.make_selection, i, popup),
                    font=("Work Sans", 12),
                    anchor="w"
                )
                button.pack(fill=ctk.X, padx=10, pady=5)
 
            # Update idle tasks to get updated dimensions
            popup.update_idletasks()
 
            # Get the content width and height
            content_width = 400
            content_height = popup.winfo_height()
 
            # Set the geometry of the popup to fit the content
            popup.geometry(f"{content_width}x{content_height}")
           
          
            def on_closing():
                try:
                    print("Trying to restart the listener...")  # Debugging
                    key_listener_instance.start_listener()  # Start the listener
                except Exception as e:
                    print(f"Failed to restart listener. Exception: {e}")
                finally:
                    popup.destroy()
 
            popup.protocol("WM_DELETE_WINDOW", on_closing)
            print("Setting WM_DELETE_WINDOW protocol")  # Debugging
 
            popup.attributes("-topmost", True)
            popup.focus_force()
 
            print("Entering Tkinter mainloop")  # Debugging
            popup.mainloop()

Python相关问答推荐

如何对行使用分段/部分.diff()或.pct_change()?

Ibis中是否有一个ANY或ANY_UTE表达,可以让我比较子查询返回的一组值中的值?

如何在Python中增量更新DF

基本链合同的地址是如何计算的?

覆盖Django rest响应,仅返回PK

Python -根据另一个数据框中的列编辑和替换数据框中的列值

有条件地采样我的大型DF的最有效方法

如何使用没有Selenium的Python在百思买着陆页面上处理国家/地区 Select ?

三个给定的坐标可以是矩形的点吗

如何将ctyles.POINTER(ctyles.c_float)转换为int?

使用新的类型语法正确注释ParamSecdecorator (3.12)

根据另一列中的nan重置值后重新加权Pandas列

rame中不兼容的d类型

ODE集成中如何终止solve_ivp的无限运行

Odoo 16使用NTFS使字段只读

pandas在第1列的id,第2列的标题,第3列的值,第3列的值?

什么是合并两个embrame的最佳方法,其中一个有日期范围,另一个有日期没有任何共享列?

合并帧,但不按合并键排序

通过ManyToMany字段与Through在Django Admin中过滤

python中csv. Dictreader. fieldname的类型是什么?'