简体   繁体   English

wxPython不会与作为窗口句柄的父项关闭Frame

[英]wxPython won't close Frame with a parent who is a window handle

I have a program in Python that gets a window handle via COM from another program (think of the Python program as an addin) I set this window to be the main Python frame's parent so that if the other program minimizes, the python frame will too. 我有一个Python程序,它通过COM从另一个程序获取窗口句柄(认为Python程序是一个插件),我将此窗口设置为Python主框架的父窗口,这样,如果另一个程序最小化,Python框架也会。 The problem is when I go to exit, and try to close or destroy the main frame, the frame.close never completes it's execution (although it does disappear) and the other program refuses to close unless killed with TaskManager. 问题是当我退出并尝试关闭或破坏主框架时,frame.close永远不会完成其执行(尽管它确实消失了),而另一个程序则拒绝关闭,除非被TaskManager杀死。

Here are roughly the steps we take: 我们大致采取以下步骤:

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

Anybody have any thoughts on this or experience with this sort of thing? 有人对此有任何想法或经验吗?

I appreciate any help with this! 我对此表示感谢!

[Edit] This is only the case when I use the handle as a parent, if I just get the handle and close the python program, the other program closes fine [编辑]只有当我使用该句柄作为父项时,如果我只是获得了该句柄并关闭了python程序,其他程序就可以正常关闭了

I wonder if your Close call may be hanging in the close-handler. 我想知道您的“ Close呼叫是否可能挂在“关闭处理程序”中。 Have you tried calling Destroy instead? 您是否尝试致电Destroy If that doesn't help, then the only solution would seem to be "reparenting" or "detaching" your frame -- I don't see a way to do that in wx , but maybe you could drop down to win32 API for that one task...? 如果那没有帮助,那么唯一的解决方案似乎是“重新构造”或“分离”您的框架-我在wx中看不到这样做的方法,但也许您可以为此使用Win32 API一项任务...?

My resolution to this is a little bit hacked, and admittedly not the most elegant solution that I've ever come up with - but it works rather effectively... 我对此的解决方案有些破烂,并且公认不是我想出的最优雅的解决方案-但它的效果相当好...

Basically my steps are to start a thread that polls to see whether the window handle is existent or not. 基本上,我的步骤是启动一个轮询以查看窗口句柄是否存在的线程。 While it's still existent, do nothing. 虽然它仍然存在,但是什么也不做。 If it no longer exists, kill the python application, allowing the handle (and main application) to be released. 如果不再存在,请终止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

Again, it feels a little hackish, but I don't really see another way around it. 再说一次,这感觉有点骇人听闻,但我真的看不到其他解决方法。 If anybody else has better resolutions, please post. 如果其他人有更好的分辨率,请发布。

如果只需要重frame.Reparent(None) ,则可以在frame.Close()之前尝试frame.Reparent(None) frame.Close()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM