Qt C ++ QException: erreur de débogage

Je veux lire des objects à partir d’un fichier XML et je dois gérer deux exceptions: lorsque le fichier ne peut pas être ouvert et lorsque le contenu du fichier ne peut pas être chargé. (mal formaté) J’ai écrit la fonction suivante pour lire le contenu du fichier et 2 classes pour les exceptions. Le problème est que lorsque j’exécute mon application et que j’essaie de charger un fichier de format différent de XML, au lieu d’un message frindly qui indique qu’il existe une exception, j’ai une erreur de débogage: abort () est appelée. Qu’est-ce que je ne fais pas bien? fonction de lecture

QList VehicleHelper::readVehicles(QSsortingng fileName){ QList vehicles; Vehicle newVehicle; QFile file(fileName); QDomDocument document; if(!file.open(QIODevice::ReadOnly | QIODevice::Text)){ throw FileCannotBeOpenException(); } else{ if(!document.setContent(&file)){ throw InvalidXMLContentException(); } file.close(); } QDomElement root = document.firstChildElement(); QDomNodeList carElements = root.elementsByTagName("Car"); for(int i = 0; i < carElements.size(); i++){ QDomNode carNode = carElements.at(i); QDomElement carElement = carNode.toElement(); QString carID = carElement.attribute("ID"); //if the idNumber is null, generate one if(carID.isEmpty()){ QUuid newId = Vehicle::generateID(); newVehicle.setVehicleId(newId); } else { QUuid id; try{ id = QUuid::QUuid(carID); } catch(QException &ex){ continue; } newVehicle.setVehicleId(id); } } 

l’appel de la fonction

 void MainWindow::on_actionOpen_sortingggered() { if(isModified){ QMessageBox msgBox; QSsortingng message = "There are unsaved changes! Do you proceed? "; msgBox.setWindowTitle("Save Changes"); msgBox.setText(message); msgBox.addButton("Don't save",QMessageBox::NoRole); msgBox.addButton(QMessageBox::Save); msgBox.addButton(QMessageBox::Cancel); msgBox.setIcon(QMessageBox::Question); int result = msgBox.exec(); if(result == QMessageBox::Save){ VehicleHelper::writeVehicles(cars,filename); msgBox.close(); } else { QSsortingng fileName = QFileDialog::getOpenFileName(this,"Open file"); if(!fileName.isEmpty()){ setFileName(fileName); QFile file(fileName); try { cars = VehicleHelper::readVehicles(fileName); } catch(FileCannotBeOpenException &ex) { QMessageBox msgBox; msgBox.setIcon(QMessageBox::Critical); msgBox.setWindowTitle("Message!"); msgBox.setText("Failed to open file"); msgBox.setDefaultButton(QMessageBox::Ok); msgBox.exec(); return; } catch(InvalidXMLContentException &ex){ QMessageBox msgBox; msgBox.setIcon(QMessageBox::Critical); msgBox.setWindowTitle("Message!"); msgBox.setText("Failed to load data!"); msgBox.setDefaultButton(QMessageBox::Ok); msgBox.exec(); return; } setTakenNumbersList(cars); //set data to the table view populate(cars); } } } else { QSsortingng fileName = QFileDialog::getOpenFileName(this,"Open file"); if(!fileName.isEmpty()){ setFileName(fileName); QFile file(fileName); if(file.open(QFile::ReadOnly | QFile::Text)){ cars = VehicleHelper::readVehicles(fileName); setTakenNumbersList(cars); file.close(); //set data to the table view populate(cars); ui->actionAdd->setEnabled(true); ui->actionBy_name->setEnabled(true); ui->actionBy_registration_date->setEnabled(true); ui->actionBy_registration_number->setEnabled(true); ui->actionBy_revision_date->setEnabled(true); ui->actionBy_type->setEnabled(true); ui->actionClear_Search->setEnabled(true); ui->actionDelete->setEnabled(true); ui->actionEdit->setEnabled(true); ui->actionSave->setEnabled(true); ui->actionSave_As->setEnabled(true); } } } } 

principale

 int main(int argc, char *argv[]) { QApplication a(argc, argv); MainWindow w; try{ w.show(); } catch(QException &ex){ } return a.exec(); } 

Les exceptions proviennent du code qui s’exécute dans la boucle d’événements. En particulier, elles atteindront le QCoreApplication::notify() . Celui-ci est appelé indirectement à partir de a.exec() , via un appel de boucle d’événement intervenant du système d’exploitation.

Ainsi, vous ne pouvez pas simplement envelopper a.exec() dans un try / catch. Vous devez réimplémenter QCoreApplication::notify() comme suit:

 class MyApplication : public QApplication { public: MyApplication(int & c, char ** a) : QApplication(c,a) {} virtual bool notify(QObject * obj, QEvent * ev) { bool rc = true; try { rc = QApplication::notify(obj, ev); } catch (QException &ex) { ... } return rc; } }; int main(...) { MyApplication app(...); ... } 

Un autre problème avec votre code est qu’il crie d’utiliser le cadre de la machine à états . Vous devez avoir des états représentant le fichier en cours d’ouverture et de fermeture et des états intermédiaires, par exemple, lorsque la boîte de dialog “Modifications non enregistrées” apparaît. Ensuite, vous n’aurez pas ui->actionXYZ->setEnabled(true) autour du code. En supposant que vous ayez un état fileOpen , vous auriez

 fileOpen->assignProperty(ui->actionBy_name, "setEnabled", true); ... 

Ensuite, lorsque le fichier est ouvert, vous émettez un signal associé à une transition de signal dans la machine à états. La machine à états fera le rest – elle activera / désactivera les actions pour vous, etc.