http://blog.csdn.net/xugangjava/article/details/8294716
ShowModal的原理
在主event loop中插入一个循环 来拦截 主窗口事件,当模态对话框退出时,取消这个循环,主窗口继续响应时间。
现在程序中开启了一个模态对话框,然后后台一个Timer要求退出程序,或者点击右下角退出程序
点击右下角退出,或者后台timer需要执行退出,(用户长期离开,自动退出)
在wxpython中 一般将一个Frame(loginFrame) 的Parent设置为NULL 然后
self.SetTopWindow(loginFrame)
self.SetExitOnFrameDelete(True)
执行loginFrame Close的时候 程序将自动退出
但是如果 存在模态对话框 退出后 关闭TOP Window 后 程序无法退出,程序仍然在event loop,
在退出的时候,需要检测到模态对话框 然后 关闭掉 然后再来执行 退出程序
加入如下代码实现
mainFrame=UiManager.MainFrame() mHwnd=mainFrame.GetHandle() hwnd= windll.user32.GetLastActivePopup(mHwnd) if hwnd!=mHwnd: win32gui.SendMessage(hwnd,WM_CLOSE,0,0)GetLastActivePoup获取最近弹出的对话框句柄 并发送关闭消息,后退出主窗口
如果在 模态对话框 上在开模态对话框 则
#关闭 上次弹出的模态对话框 def EvtClose(self,evt): mainFrame=UiManager.MainFrame() mHwnd=mainFrame.GetHandle() hwnd= windll.user32.GetLastActivePopup(mHwnd) if hwnd!=mHwnd: win32gui.SendMessage(hwnd,WM_CLOSE,0,0) wx.CallLater(200,lambda :win32gui.SendMessage(mHwnd,WM_CLOSE,0,0))#再次 发送关闭消息, else: #do close logic
必须 全部关闭 然后才能退出应用程序,CallLater是很重要的,向对话框 发送WM_CLOSE 后 模态对话框 不是马上销毁的,
必须等待 自身的 event loop退出后关闭,
GetLastActivePoup
后SendMessage(WM_CLOSE)
再次GetLastActivePoup 发现得到是 已经关闭了的 窗口句柄,所以在此发送消息,逐一关闭 已经弹出的对话框