Comment tuer un WxPython application lorsque l'utilisateur clique sur un cadre de proximité
L'application est censée se fermer lorsque je clique sur le bouton fermer de la fenêtre principale. Mais la façon dont j'ai mis en place, il se ferme avec une Segmentation fault
quand je clique sur le bouton.
Je m'inquiète de la sécurité de l'arrêt du programme, parce que j'ai besoin de persister trucs disque plus tard.
Quel est le bonne façon non-violente de mettre fin à un WxPython demande si un bouton de fermeture?
Ici est le "principal" de la boucle du programme, j'ai mis en œuvre:
if __name__ == "__main__":
app = wx.App(False)
mf = MainFrame(None, title='Spectrum Checker') #subclasses frame
mf.register_close_callback( app.Destroy) #what is the apt func?
app.MainLoop()
Ici est de savoir comment il est mis en œuvre le rappel à l'intérieur de la MainFrame
:
def __init__(self, parent, title):
...
self.Bind(wx.EVT_CLOSE, self._when_closed)
...
def _when_closed(self, event):
if self.__close_callback__:
self.__close_callback__()
Vous devez vous connecter pour publier un commentaire.
Ici est la méthode normale de la fermeture d'un cadre:
Maintenant, si vous avez une liaison à wx.EVT_CLOSE, puis vous vous retrouverez dans une boucle infinie jusqu'à obtenir une erreur de segmentation. La principale raison de se lier à EVT_CLOSE est de sorte que vous pouvez attraper la clôture de l'événement et de demander à l'utilisateur de sauvegarder leurs informations. Si vous souhaitez faire cela, alors vous devez utiliser
self.Destroy
au lieu de "auto.Fermer" afin de ne pas continuer à tirer de cet événement.Comme cela a déjà été mentionné, dans votre gestionnaire, vous devez assurez-vous de fin de threads, de détruire les icônes de la barre des tâches, fermer les fichiers ouverts, etc donc, rien n'accroche. Voir aussi: http://wxpython.org/docs/api/wx.CloseEvent-class.html
OP outre
J'ai été confronté à deux problèmes, je remercie tous les trois des réponses pour m'aider à les trouver:
D'abord, le cadre ne répond pas à
self.Close()
ouself.Destroy()
parce qu'il a un attributself.stuff
qui a un thread en cours d'exécution. Ce fil doit d'abord être fermés.Deuxième,
self.Close()
dans un gestionnaire qui répond à proximité des événements et des causes d'une récurrence infinie lorsqu'il est appelé. Cela provoque une erreur d'exécution (erreur de segmentation, profondeur de récursion dépassé). La solution est d'utiliserself.Destroy()
à la place.Je ne suis pas sûr pourquoi avez-vous besoin de ce rappel pour fermer l'application? Si vous ne l'oblige en rien à la
MainFrame
, l'application sera automatiquement fermé lorsque vous cliquez sur le bouton fermer. Sauf si vous avez une autre thread en cours d'exécution qui empêche le processus à la fin. Si vous voulez toujours de se lier à la clôture de l'événement et de faire quelque chose avant la fermeture, vous devez utiliserevent.Skip()
dans le gestionnaire d'événements si vous voulez continuer à fermer la fenêtre. Sinon, l'événement n'est pas propagée et gestionnaire par défaut n'est pas exécutée. Un exemple:Lorsque vous exécutez le code et cliquez sur fermer - l'application est fermée. Lorsque vous modifiez la fonction de callback à
lambda: False
la fenêtre ne sera pas fermée depuisSkip
n'est pas appelé.app = wx.App(False)
) et de laisser l'enfant à proximité de l'événement se propager vers le haut pour elle?wx.Destroy
qui semble obsolète. Dans mon exemple, vous pouvez effectuer enregistrer dans la fonction de rappel, lorsque la fonction renvoie True, le programme sera fermé juste après l'enregistrement.L'une des réponses ci-dessus décrit à l'aide de Détruire() plutôt que de le Fermer() pour enregistrer les informations utilisateur avant de quitter l'application. Voici un exemple de code demandant à l'utilisateur s'il a l'intention de cesser de fumer. Si elles répondent à l'affirmative, il "détruit" le cadre et ferme l'application.
La fermeture de tout le haut niveau des cadres dans l'application devrait mettre fin à l'application sans avoir besoin de se lier à fermer ou quoi que ce soit d'autre. Vous pouvez fermer vous-même avec
.Close()
si vous en avez plusieurs, ou certains qui sont cachés.Aussi, si vous avez un TaskBarIcon, qui devront être détruits avant que l'application se termine.
Je pense que votre seg fault pourrait être une autre raison, à voir avec la façon dont les cadres d'abattre et de détruire leurs enfants. Je voudrais essayer pas à pas dans le code et découvrez à quel point le seg fault qui se passe.
self.Close()
à_when_closed