2011-05-04 8 views
1

J'écris une application de vision par ordinateur (C++ et OpenCV). Je crée une interface graphique avec wxWidgets - c'est très simple; un événement de bouton-presse appelle l'application de suivi pour commencer.Le programme ne se termine pas correctement

Mon appel à mettre fin à l'application (à savoir le bouton cliquer pour fermer) est la suivante:

// Exiting the App 
void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event)) 
{ 
    // true is to force the frame to close 
    Close(true); 
} 

Cela fonctionne généralement avec les applications de l'interface graphique plus triviales. Cependant, à cette occasion, le cadre disparaît encore, dans le gestionnaire de tâches, le processus semble continuer à fonctionner et à maintenir la mémoire. Il est très ennuyeux parce que si je lance ou déboguer l'application et ensuite faire quelques changements et essayer de courir à nouveau, sans terminer le processus manuellement au préalable, le compilateur génère une erreur de lien, car le .exe est

not found or not built by the last incremental link.

ai essayé d'insérer un sortie de force brute (1); dans la méthode onQuit mais cela provoque le blocage de l'application. Je ne suis pas sûr de ce que c'est .. lors de l'exécution sans l'interface graphique, l'application s'exécute et se termine bien (mais il est appelé légèrement différemment - de la fonction main() au lieu d'un gestionnaire d'événements bouton-presse appelle une classe de base abstraite).

Est-il possible que ce soit parce qu'une classe est déclarée avec une portée globale? Comme dans, dans un fichier j'ai une instance d'une classe déclarée en dehors de toute méthode de classe? Peut-être que wxWidgets ne peut pas gérer cela?

Pour clarifier:

Le cadre Je ferme est un cadre de niveau supérieur. Je n'ai eu aucun problème avec le même code GUI quand il n'appelle pas les méthodes de vision par ordinateur.

Je n'ai pas spécifiquement codé de multi-threading mais pour commencer, j'obtenais une erreur qui disait "Erreur: Impossible d'initialiser OLE". Pour résoudre ce problème, j'ai dû mettre wxUSE_DRAG_AND_DROP, wxUSE_CLIPBOARD, wxUSE_OLE et wxUSE_OLE_AUTOMATION à 0 (au lieu de 1), puis (re) compiler wxWidgets.

Je me demandais juste s'il y a une sorte de threading en cours avec HighGUI qui n'est pas cohérent avec WxWidgets? Quelqu'un d'autre a-t-il rencontré des problèmes similaires?

+0

Semble que vous avez plusieurs threads, et appelant 'Close()' ne les tue pas tous. – Dima

+0

Si vous n'êtes pas accroché dans l'événement de presse bouton généré par la fenêtre, qu'est-ce qui vous fait penser que quelque chose va se passer lorsque le bouton est pressé? Définir des points d'arrêt et déboguer ou afficher du code plus pertinent. – AJG85

Répondre

0

Merci pour toute l'aide, j'ai résolu le problème. Semble assez évident maintenant mais ne pouvait pas le comprendre à ce moment-là! À l'origine, mon application de vision par ordinateur s'appelait à partir d'une fonction principale. Cependant, avec le nouveau code GUI, il n'y a pas besoin de main, donc j'ai remplacé le main original par une classe shell. Bien que j'avais pris soin de libérer la mémoire allouée dans les méthodes de mes classes de vision par ordinateur, je n'avais pas été si prudent avec la fonction principale originale car une fois cette fonction terminée, toute la mémoire précédemment utilisée serait effacée par le programme. sortie régulière. La différence avec le nouveau code GUI est que lorsque la classe shell est terminée - le programme est toujours en cours d'exécution. L'idée était que même lorsque l'application de vision par ordinateur était terminée, la lumière bleue de ma webcam brillait toujours.

* Assurez-vous d'appeler cvReleaseCapture (capture &); pour libérer ce thread et libérer le matériel *

0

Votre appel à Close ferme uniquement le cadre, mais n'arrête pas l'application, car il ne s'agit pas de la dernière fenêtre de niveau supérieur. Le fichier wxWidget contient un sujet Window Deletion Overview. Il indique que

A wxWidgets application automatically exits when the last top level window (wxFrame or wxDialog), is destroyed. Put any application-wide cleanup code in wxApp::OnExit (this is a virtual function, not an event handler).

Votre cadre est-il le cadre de niveau supérieur? Sinon, vous devrez peut-être appeler Close ou Destroy sur un cadre de niveau supérieur.

+0

Merci, mais voir modifier dans la question d'origine. – kylestephens

1
::wxExit 

void wxExit() 

Quitte l'application après avoir appelé wxApp :: OnExit. Ne devrait être utilisé qu'en cas d'urgence: normalement, le cadre de niveau supérieur doit être supprimé (après avoir supprimé toutes les autres images) pour terminer l'application. Voir wxCloseEvent et wxApp.

Inclure les fichiers

<wx/app.h> 

Vous pouvez aussi simplement appeler la sortie de la fonction crt() qui va instantanément fermer tout.Cependant, si vous voulez plus de politesse que ces méthodes plutôt brutales (ce que vous voudrez peut-être faire en particulier si vous avez placé un code d'arrêt spécial dans wxApp :: OnExit ) alors vous voulez trouver le niveau supérieur fenêtre et fermez ça. Pour le faire à partir de n'importe où dans votre code

wxGetApp().GetTopWindow()->Close() 
+0

Alors, as-tu essayé wxExit() et exit()? – ravenspoint

+0

Oui, l'a placé dans la méthode OnExit() mais cela n'a pas fonctionné. Également essayé wxGetApp() -> GetTopWindow() -> Close() mais cette syntaxe est invalide et je suis sûr que je ferme ma fenêtre de haut niveau dans tous les cas. – kylestephens

+0

Si vous voulez de l'aide, vous devez être un peu plus prudent en suivant ce que les gens suggèrent. Essayez d'appeler :: wxExit() et d'appeler exit(). Pour wxGetApp, utilisez-vous DECLARE_APP – ravenspoint

Questions connexes