Tengo un programa en Python que obtiene un identificador de ventana a través de COM desde otro programa (piense en el programa Python como un complemento) Configuré esta ventana para que sea el padre del marco principal de Python para que si el otro programa se minimiza, el marco de Python también lo hará . El problema es que cuando salgo e intento cerrar o destruir el marco principal, frame.close nunca completa su ejecución (aunque desaparece) y el otro programa se niega a cerrar a menos que se elimine con TaskManager.

Estos son aproximadamente los pasos que tomamos:

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

¿Alguien tiene alguna idea sobre esto o experiencia con este tipo de cosas?

¡Apreciaría cualquier ayuda con esto!

[Editar] Este es solo el caso cuando uso el identificador como padre, si solo obtengo el identificador y cierro el programa Python, el otro programa cierra bien

1
Fry 2 jun. 2009 a las 23:33

3 respuestas

La mejor respuesta

Mi resolución a esto es un poco pirateada, y ciertamente no es la solución más elegante que se me haya ocurrido, pero funciona de manera bastante efectiva ...

Básicamente, mis pasos son comenzar un hilo que sondea para ver si el identificador de la ventana existe o no. Si bien aún existe, no hagas nada. Si ya no existe, elimine la aplicación python, permitiendo que se libere el identificador (y la aplicación principal).

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

Una vez más, se siente un poco duro, pero realmente no veo otra forma de evitarlo. Si alguien más tiene mejores resoluciones, publique.

0
Fry 21 oct. 2011 a las 11:28

Me pregunto si su llamada Close puede estar colgando en el controlador cercano. ¿Has intentado llamar a Destroy en su lugar? Si eso no ayuda, entonces la única solución parecería ser "volver a pintar" o "separar" su marco; no veo una forma de hacerlo en wx, pero tal vez podría ir a win32 API para esa tarea ...?

1
Alex Martelli 2 jun. 2009 a las 20:15

Si todo lo que necesita es volver a realizar la prueba, puede probar frame.Reparent(None) antes de frame.Close()

0
FogleBird 4 jun. 2009 a las 20:46