【问题标题】:Python win32gui application - trying to quit from external threadPython win32gui 应用程序 - 试图从外部线程退出
【发布时间】:2021-11-27 23:32:06
【问题描述】:

我有一个 python 应用程序,它使用通过 win32 创建的托盘图标来控制 tkinter GUI。托盘图标可以向 tkinter GUI 发出命令(隐藏/显示/关闭/等),但由于它位于单独的线程中,它不会接受来自 tkinter GUI 的命令(例如退出程序)。

我在这里找到了一个响应,其中概述了访问托盘图标线程的过程: How to DestroyWindow from remote thread?

  1. 从 GetWindowThreadProcessId() 获取托盘图标的线程 ID
  2. 使用 SetWindowsHookEx() 安装消息挂钩
  3. 使用消息挂钩触发托盘图标线程上的退出命令

这听起来很简单,但我不清楚如何在实践中实现它。

第一步很简单:

tid, pid = win32process.GetWindowThreadProcessId(self.hwnd)

有人可以提供有关步骤 2 和 3 格式的示例/指导吗?

【问题讨论】:

  • 听起来很像XY Problem。你最终想要完成什么?
  • 总体目标是这样的:程序显示一个用户可以与之交互的窗口,该窗口被最小化为托盘图标而不是关闭。程序可以从托盘图标关闭或最大化(例如,它与音量/网络图标出现在同一位置)。问题出在我的混合使用 win32 和 tkinter 的实现中,如果没有上述方法,它们不喜欢跨线程通信。这是否有助于概述我正在做的事情?我想用tkinter,因为我熟悉它,但托盘图标似乎需要win32。
  • SendMessagePostMessage 跨线程工作。只需向应用程序窗口发送或发布消息,即可将其关闭。消息在拥有窗口的线程上发送,所以一切正常。
  • 感谢您的反馈。搜索了更多,找到了一个像你描述的那样工作的例子。具体代码只是:win32gui.PostMessage(self.hwnd, win32con.WM_CLOSE, 0, 0)

标签: python multithreading winapi hook


【解决方案1】:

IInspectable 在 cmets 中建议的解决方案是直接使用 PostMessage,如下所示:

win32gui.PostMessage(self.hwnd, win32con.WM_CLOSE, 0, 0)

这允许 tkinter GUI 告诉 win32 托盘图标退出而不会遇到与线程相关的访问错误。

【讨论】:

    猜你喜欢
    • 2010-12-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-27
    • 2020-02-14
    • 2014-01-18
    • 2011-08-01
    相关资源
    最近更新 更多