where am I supposed to catch it?
Questo è esattamente il motivo per Qt non supporta generare eccezioni attraverso le connessioni del segnale/di slot. Se lo provate, vedrete questo messaggio:
Qt has caught an exception thrown from an event handler. Throwing exceptions from an event handler is not supported in Qt. You must reimplement QApplication::notify() and catch all exceptions there.
Come si parla, è possibile creare una sottoclasse QApplication e riprendere eccezione lì, ma che sarà un modo molto fastidioso di gestire le cose.
Se possibile, suggerirei di riscrivere il numero in modo che non venga generato.
Cosa succede se non si può riscrivere count()?
Ad esempio, che succede se count() fa parte di una funzione in una libreria di terze parti che stai utilizzando?
Non esiste alcun slot in una libreria Qt ufficiale, quindi se si utilizza una libreria di terze parti con uno slot che genera, è probabilmente un segno che non è una buona libreria. Se si desidera utilizzarlo comunque, è consigliabile che anziché acquisirlo in QApplication::notify
, invece di creare un adattatore.
Che cosa significa? Per prima cosa crea un oggetto che acquisisce il tuo oggetto di terze parti abbozzato nel costruttore. In esso, scrivi uno slot che avvolge una chiamata allo slot di lancio con un blocco try/catch. Ora invece di collegarti allo slot dell'oggetto di terze parti abbozzato, connettiti allo slot dell'oggetto appena creato.
Facendo l'eccezione che cattura in questo modo mantiene il codice correlato insieme e impedisce a QApplication::notify
di riempirsi con un gruppo di blocchi try/catch non collegati se si verifica più di una di queste funzioni problematiche.
Ad esempio:
class BadCounter {
Q_OBJECT
public slots:
void count() { throw CounterError("unable to count"); }
};
class CounterAdaptor {
Q_OBJECT
BadCounter* counter_;
public:
CounterAdaptor(BadCounter* counter) {
counter_ = counter;
}
public slots:
void count() {
try {
counter_->count();
} catch (const CounterError& e) {
std::cerr << e.what() << std::endl;
}
}
};
int main() {
BadCounter engine;
CounterAdaptor adaptor(&engine);
QThread* thread = new QThread();
connect(thread,SIGNAL(started()),&adaptor,SLOT(count()));
thread.start();
... // etc...
delete thread;
}
Che cosa succede se si desidera gestire qualcosa che potrebbe essere gettato da qualche parte?
L'ovvio esempio di questo tipo di preoccupazione globale è un'eccezione imprevista. Gli errori possono accadere ovunque. Sarebbe auspicabile registrare quanti più dettagli possibile sull'evento, in modo che la causa potesse essere identificata e corretta. In questo caso, è che desidera reimplementare QApplication::notify
nella propria sottoclasse come mostrato in jichi's answer. Usare un gestore globale per le preoccupazioni globali è abbastanza ragionevole.
Forse si dovrebbe mettere il blocco try-catch nella funzione count(). .. – Kobe
#vBx count thea – smallB
Quindi la soluzione fornita nella domanda è buona – Kobe