Qt обычно не использует или не поддерживает исключение (если вы можете в это поверить!)
Проверьте эти ссылки:
Почему Qt не использует исключенияобработка?
http://doc.qt.io/qt-5/exceptionsafety.html
Тем не менее, ответы @Crazy Eddie и @Macke довольно хороши, но не всегда работают.В частности, я обнаружил, что вы не можете использовать ни одну из них из функции слота, которую вы вызывали из QML.Итак, я создал хакерское решение этой проблемы.* Используйте это вместе с их - не вместо этого.
Сначала я создал класс, производный от QException, который я здесь пропущу, но это то, что вы, вероятно, захотите сделать.В этом посте я просто называю его «MyQException».
В любом случае, добавьте этот заголовок для класса с именем QmlSlotThrower
:
#ifndef QMLSLOTTHROWER_H
#define QMLSLOTTHROWER_H
#include "MyQException.h"
class QmlSlotThrower
{
public:
static QmlSlotThrower *get()
{
static QmlSlotThrower instance;
return &instance;
}
QmlSlotThrower( QmlSlotThrower const& ) = delete;
void operator=( QmlSlotThrower const& ) = delete;
void throwToTop( const MyQException &exception );
private:
QmlSlotThrower(){}
};
static QmlSlotThrower *qmlSlotThrower = QmlSlotThrower::get();
#define throwFromQmlSlot( exc ) qmlSlotThrower->throwToTop( exc ); return;
#endif // QMLSLOTTHROWER_H
Затем это cpp:
#include "QmlSlotThrower.h"
#include <QTimer>
class AsynchronousThrower: public QObject
{
Q_OBJECT
public:
void throwThis( const MyQException &exception )
{
exception_ = exception;
QTimer::singleShot( 0, this, SLOT( throwIt() ) );
}
private slots:
void throwIt(){ throw exception_; }
private:
MyQException exception_;
};
static AsynchronousThrower asycnThrower;
// This is needed to allow the Q_OBJECT macro
// to work in the private classes
#include "QmlSlotThrower.moc"
// --------------------------------
void QmlSlotThrower::throwToTop( const MyQException &exception )
{ asycnThrower.throwThis( exception ); }
Наконец, вот пример реализации:
void someQMLSlot()
{
// Qt has been progressively adding exception handling
// support, but you still cannot throw from a QML
// triggered slot. It causes an uncatchable fatal error!
// As a general rule, don't throw in Qt unless you are
// certain something is there to catch it. You cannot
// count on an uncaught exception handler at a top level
// to always work. This QML problem is a perfect example.
// So this is not an option here!
//throw MyQException( "Something terrible occured!" );
// This work around, however, can be used instead!
//throwFromQmlSlot( MyQException( "Something terrible occured!" ) )
// Or, to be more robust in illustrating how you can still use
// normal throws from nested functions even, you can do this:
try{ throw MyQException( "Something terrible occured!" ); }
catch( const MyQException &e) { throwFromQmlSlot( e ) }
qDebug() << "YOU SHOULD NEVER SEE THIS!!";
}
ТОЛЬКО ИСПОЛЬЗУЙТЕ МАКРО ПРЯМО С ВАШЕГО СЛОТА!