Question

J'ai un programme en Python qui obtient une poignée de fenêtre via COM à partir d'un autre programme (pensez du programme Python comme Addin) Je mets cette fenêtre pour être parent du cadre principal de Python de sorte que si l'autre programme minimise, le python cadre aussi. Le problème est quand je vais sortir et essayer de fermer ou détruire le cadre principal, le frame.close ne se termine jamais son exécution (même si elle ne disparaît) et l'autre programme refuse de fermer moins d'être tué avec TaskManager.

Voici à peu près les mesures que nous prenons:

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

Quelqu'un a des idées sur ce ou de l'expérience avec ce genre de chose?

Je vous remercie de toute aide avec ceci!

[Modifier] Ceci est seulement le cas lorsque j'utilise la poignée en tant que parent, si je viens d'obtenir la poignée et fermer le programme python, l'autre programme ferme fin

Était-ce utile?

La solution 3

Ma résolution à cette question est un peu piraté, et certes pas la solution la plus élégante que je suis venu jamais avec - mais ça fonctionne plutôt efficacement ...

En fait mes pas sont pour commencer un fil que les sondages pour voir si la poignée de fenêtre est inexistante ou non. Bien qu'il soit encore existant, ne rien faire. Si elle n'existe plus, tuer l'application python, permettant à la poignée (et l'application principale) à libérer.

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

Encore une fois, il se sent un peu hackish, mais je ne vois pas vraiment une autre façon de le contourner. Si quelqu'un d'autre a de meilleures résolutions, s'il vous plaît poster.

Autres conseils

Je me demande si votre appel Close peut être suspendu dans le gros gestionnaire. Avez-vous essayé d'appeler Destroy à la place? Si cela ne fonctionne pas, alors la seule solution semble être « reparentage » ou « détacher » votre cadre - Je ne vois pas une façon de le faire dans wx, mais vous pourriez peut-être descendre à l'API win32 pour que une tâche ...?

Si reparentage est tout ce dont vous avez besoin, vous pouvez essayer frame.Reparent(None) avant frame.Close()

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top