2009-06-10 19 views
5

Mam konsolę opartą na QCoreApplication, która ma liczniki czasu i nie obsługuje komunikacji w gnieździe, a także wykorzystuje zablokowany muteks.Czyszczenie przed zamknięciem QCoreApplication

Kiedy ręcznie zamknąć aplikację, daje błąd mówiąc niektóre mutex jest zablokowany i jest limit czasu. Czy jest jakiś sposób, aby wyczyścić aplikację konsolową, gdy użytkownik ją zamknie?

Odpowiedz

15

Oczyszczanie powinno być obsługiwane przez destruktory i relacje między potomkami.

aby Twój obiekt główny (jeden w głównym) dziecko z QApplication tak jest zniszczona ze wszystkimi jego Childs przed QApplication jest.

Czy jesteś pewien, że zabiłeś wszystkie swoje wątki? Jeśli jest to wątek z eventloop należy zadzwonić QThread::quit() aby opuścić eventloop przed wywołaniem QThread::wait()

Można również użyć pustkę QApplication::qAddPostRoutine (QtCleanUpFunction ptr) zrobić jakiś specjalny porządki.

Do debugowania te wiadomości można użyć QtMsgHandler qInstallMsgHandler (QtMsgHandler h) i napisać własny program obsługi wiadomości, aby uchwycić te ostrzeżenia. Jeśli możesz zasymulować problem, możesz ustawić punkt przerwania w komunikacie i zobaczyć na stosie, z którego pochodzi wiadomość.

void debugMessageHandler(QtMsgType type, const char *msg){ 
    if(QString(msg).contains("The message you can see in the console")){ 
     int breakPointOnThisLine(0);  
    } 

    switch (type) { 
     case QtDebugMsg: 
      fprintf(stderr, "Debug: %s\n", msg); 
      break; 
     case QtWarningMsg: 
      fprintf(stderr, "Warning: %s\n", msg); 
      break; 
     case QtFatalMsg: 
      fprintf(stderr, "Fatal: %s\n", msg); 
      abort(); 
    } 
} 

Aby oczyścić z destruktora i dziecko-rodzic relacji statek można złapać sygnał konsoli bliskie i nazywają QCoreApplication::exit() do instancji aplikacji.

#include <csignal> 
#include <QtCore/QCoreApplication> 
using namespace std; 

struct CleanExit{ 
    CleanExit() { 
     signal(SIGINT, &CleanExit::exitQt); 
     signal(SIGTERM, &CleanExit::exitQt); 
     signal(SIGBREAK, &CleanExit::exitQt) ; 
    } 

    static void exitQt(int sig) { 
     QCoreApplication::exit(0); 
    } 
}; 


int main(int argc, char *argv[]) 
{ 
    CleanExit cleanExit; 
    QCoreApplication a(argc, argv); 
    return a.exec(); 
} 
+0

prawie ukończona.po wywołaniu exit (0) musisz wykonać swój kod oczyszczania Qt, który nie znajduje się w procedurze obsługi wyjścia exitQt(). więc musisz powiązać swój kod czyszczenia Qt z sygnałem aboutToQuit(). sygnał aboutToQuit jest emitowany tylko po wywołaniu wyjścia qApp-> (0). –

+2

C++ 11 czyni to łatwiejszym: 'signal (SIGTERM, [] (int sig) {qApp-> quit();});' – ManuelSchneid3r

+0

To nie działa w pełni. Obiekt związany z oczyszczaniem uczyniłem dzieckiem aplikacji QApplication. Destruktor jest prawidłowo wywoływany, gdy okno jest normalnie zamknięte. Ale po wyłączeniu/wylogowaniu systemu destruktor podrzędny QApplication nigdy nie jest wywoływany. – galinette

1

można podłączyć do QCoreApplication::aboutToQuit sygnału i zrobić potrzeby oczyścić tam.

+2

Cześć Daniel, próbowałem tego, ale przerwa punkt nie trafi w podłączonym SLOT. Dokumentacja mówi o sygnaleToQuit, który jest emitowany po wywołaniu na QCoreApplication. Czy zamknięcie aplikacji konsoli wywołuje polecenie quit()? Dzięki, Suresh. –

5

Okazuje się, że zamknięcie zastosowanie linii sterowania (zaznaczone na Windows 7 & VS2010) poprzez wciśnięcie „bliskie” (czerwony x przycisk na pasku tytuł) przekazuje sygnał do stosowania STATUS_CONTROL_C_EXIT. Wszystkie wątki są przerywane za pomocą tego kodu.

Wątek główny wątek "(0x980) odszedł z kodem -1073741510 (0xC000013A).

Wątek "QThread" (0x2388) został zakończony z kodem -1073741510 (0xc000013a).

Oznacza to, że nie ma możliwości przechwycenia tego sygnału za pomocą sygnału QCoreApplication::aboutToQuit().

Spójrz na winnt.h lub ntstatus.h. Jest to wartość przypisana do stałej manifestu STATUS_CONTROL_C_EXIT. Środowisko wykonawcze po prostu decyduje o zakończeniu programu z kodem, aby odnotować anulowanie przez użytkownika operacji .

+0

Użyj SetConsoleCtrlHandler(), aby przechwycić te i wywołać qApp-> exit (42) – Macke

Powiązane problemy