Die einfache Antwort ist: Vermeiden Sie Ihre Nachricht Handler reentering, dann:
// C++11, Qt 5.4+
void myMessageHandler(…) {
thread_local bool entered = false;
if (entered) return; // oops
QScopedValueRollback set{entered, true};
…
}
// C++11, Qt 4.8+
void myMessageHandler(…) {
thread_local bool entered = false;
if (entered) return; // oops
QScopedValueRollback back{entered};
entered = true;
…
}
// C++98, Qt 4
QThreadStorage<bool> entered;
void myMessageHandler(…) {
if (entered.localData()) return;
QScopedValueRollback back(entered.localData());
entered.localData() = true;
…
}
Das war die alte und dumme Antwort, denn Nachwelt:
Es führt zu unendlicher Rekursion nur, wenn Ihre Protokollierung synchron ist. Sobald Sie die Protokollierung asynchron vornehmen, erhalten Sie das Problem nicht mehr: Der Message-Handler wird nicht mehr neu eingegeben, da Sie ihn sofort nach dem Aussenden eines Signals verlassen, und die Signalemission über eine in der Warteschlange stehende Verbindung wird mit Null oder Null gesendet mehr QMetaCallEvent
Instanzen zu den Ereigniswarteschlangen relevanter Threads und das ist es.
Asynchrone Protokollierung wird erreicht, indem ein Signal im Message-Handler ausgegeben wird und das Protokollschreiben von einem Slot/Funktor gehandhabt wird, der über eine explizit eingereihte Verbindung mit dem Signal verbunden ist. Wahrscheinlich möchten Sie, dass sich Ihr Logger in einem eigenen Thread befindet. Das ist also ein sehr natürlicher Ansatz und funktioniert hervorragend.
Ja, Qt selbst verwendet diese Debug/Warnfunktionen, Sie müssen sich also selbst schützen. – peppe