wxPython не закроет фрейм с родителем, который является дескриптором окна
Вопрос
У меня есть программа на Python, которая получает дескриптор окна через COM из другой программы (подумайте о программе Python как о надстройке). Я установил это окно в качестве родительского элемента основного фрейма Python, чтобы, если другая программа свернется, фрейм Python тоже будет свернут. .Проблема в том, что когда я выхожу из системы и пытаюсь закрыть или уничтожить основной фрейм,frame.close никогда не завершает свое выполнение (хотя и исчезает), а другая программа отказывается закрываться, если ее не убить с помощью TaskManager.
Вот примерно какие шаги мы предпринимаем:
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
Мое решение этой проблемы немного взломано и, по общему признанию, не самое элегантное решение, которое я когда-либо придумывал, но оно работает довольно эффективно...
По сути, мои действия заключаются в том, чтобы запустить поток, который опрашивает, существует ли дескриптор окна или нет.Пока он еще существует, ничего не делайте.Если он больше не существует, завершите приложение 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
Опять же, это кажется немного хакерским, но другого пути решения я не вижу.Если у кого-то есть лучшее разрешение, пожалуйста, напишите.
Другие советы
Интересно, твой ли Close
вызов может зависать в обработчике закрытия.Вы пробовали позвонить Destroy
вместо?Если это не помогает, то единственным решением будет «переоформление» или «отсоединение» вашего фрейма — я не вижу способа сделать это в wx
, но, может быть, для этой задачи вы могли бы перейти к Win32 API...?
Если перевоспитание — это все, что вам нужно, вы можете попробовать frame.Reparent(None)
до frame.Close()