wxPython无法关闭有窗口句柄的父框架
我有一个用Python写的程序,它通过COM从另一个程序获取一个窗口的句柄(可以把这个Python程序想象成一个插件)。我把这个窗口设置为主Python窗口的父窗口,这样如果另一个程序最小化,Python窗口也会跟着最小化。问题是,当我想退出程序,尝试关闭或销毁主窗口时,frame.close这个操作总是无法完成(虽然窗口确实消失了),而且另一个程序也不愿意关闭,只有通过任务管理器强制结束。
我们大致采取的步骤如下:
if we are started directly, launch other program
if not, we are called from the other program, do nothing
enter main function:
create new wx.App
set other program as frame parent:
Get handle via COM
create a parent using wx.Window_FromHWND
create new frame with handle as parent
show frame
enter main loop
App.onexit:
close frame
frame = None
handle as parent = None
handle = None
有没有人对此有什么想法或者经验可以分享?
非常感谢任何帮助!
[编辑] 只有在我把这个句柄当作父窗口使用时才会出现这个问题,如果我只是获取句柄然后直接关闭Python程序,另一个程序就能正常关闭。
3 个回答
0
如果你只需要改变父级,可以在 frame.Close()
之前试试 frame.Reparent(None)
。
1
我在想,你的 Close
调用可能在关闭处理程序里卡住了。你有没有试过用 Destroy
呢?如果这样还是不行,那唯一的解决办法似乎就是“重新归属”或者“分离”你的窗口。我在 wx
里没看到有办法做到这一点,不过也许你可以直接使用 win32 API 来完成这个任务……?
0
我这个解决办法有点儿像是临时拼凑出来的,老实说也不是我想出来的最优雅的方案——不过它确实有效...
简单来说,我的步骤是启动一个线程,去检查窗口的句柄是否存在。只要它还存在,就什么都不做。如果它不再存在了,就结束这个Python应用程序,这样就能释放句柄(和主应用程序)。
class CheckingThread(threading.Thread):
'''
This class runs a check on Parent Window to see if it still is running
If Parent Window closes, this class kills the Python Window application in memory
'''
def run(self):
'''
Checks Parent Window in 5 seconds intervals to make sure it is still alive.
If not alive, exit application
'''
self.needKill = False
while not self.needKill:
if self.handle is not None:
if not win32gui.IsWindow(self.handle):
os._exit(0)
break
time.sleep(5)
def Kill(self):
'''
Call from Python Window main application that causes application to exit
'''
self.needKill = True
def SetHandle(self, handle):
'''
Sets Handle so thread can check if handle exists.
This must be called before thread is started.
'''
self.handle = handle
再次强调,这个方法感觉有点儿不太正规,但我真的想不到其他更好的办法。如果其他人有更好的解决方案,请分享一下。