2009-10-09 1 views
0

je l'action suivante qui est exécutée quand un certain bouton est enfoncé dans une application Qt:Gestion des exceptions dans Qt Script avec C++?

#include <shape.h> 

void computeOperations() 
{ 
    polynomial_t p1("x^2-x*y+1"),p2("x^2+2*y-1"); 
    BoundingBox bx(-4.01, 4.01,-6.01,6.01,-6.01,6.01); 
    Topology3d g(bx); 
    AlgebraicCurve* cv= new AlgebraicCurve(p1,p2); 
    g.push_back(cv); 
    g.run(); 
    //Other operations on g. 
} 

Topology3d (...), AlgebraicCurve (..), BoundingBox (...), polynomial_t (...) sont des types définis par l'utilisateur définis dans le fichier d'en-tête correspondant .

Maintenant, pour certaines valeurs de p1 et p2, la méthode g.run() fonctionne parfaitement.

Ainsi, pour d'autres valeurs de p1 et p2, g.run() il ne fonctionne plus que la méthode est bloqué en quelque sorte et le message « application ne répond pas » apparaît et je dois tuer l'application.

Je voudrais avoir le comportement suivant: chaque fois g.run() prend trop de temps, est bloqué pour certains particulier les valeurs de p1, p2, je voudrais afficher une boîte d'avertissement en utilisant QMessageBox :: Attention.

J'essaie de le faire avec try {...} et catch {...}:

#include <shape.h> 

class topologyException : public std::runtime_error 
{ 
    public: 
     topologyException::topologyException(): std::runtime_error("topology fails") {} 
}; 

void computeOperations() 
{ 
    try 
    { 
     polynomial_t p1("x^2-x*y+1"),p2("x^2+2*y-1"); 
     BoundingBox bx(-4.01, 4.01,-6.01,6.01,-6.01,6.01); 
     Topology3d g(bx); 
     AlgebraicCurve* cv= new AlgebraicCurve(p1,p2); 
     g.push_back(cv); 
     g.run(); 
     //other operations on g 
     throw topologyException(); 
    } 
    catch(topologyException& topException) 
    { 
     QMessageBox errorBox; 
     errorBox.setIcon(QMessageBox::Warning); 
     errorBox.setText("The parameters are incorrect."); 
     errorBox.setInformativeText("Please insert another polynomial."); 
     errorBox.exec(); 
    } 
} 

Ce code compile, mais quand il l'exécute vraiment ne implémente le comportement requis.

Pour les polynômes pour lesquels g.run() est bloqué le code de boîte de message d'erreur est jamais atteint, plus pour les polynômes pour lesquels g.run() fonctionne bien, le message d'erreur boîte code est encore atteint en quelque sorte et la boîte apparaît dans l'application .

Je suis nouveau à la gestion des exceptions, donc toute aide est plus que accueilli.

Je pense que le programme est bloqué quelque part dans g.run() donc il n'atteint pas l'exception, je ne comprends toujours pas ce qui se passe réellement.

Encore je voudrais jeter cette exception sans aller dans le code de g.run(), cette fonction est implémentée comme partie d'une bibliothèque plus grande, que je viens d'utiliser dans mon code. Puis-je avoir ce comportement dans mon programme sans mettre try {...} catch {...} instruction block dans la fonction g.run()?

Répondre

1

Vous ne pouvez pas réaliser ce que vous voulez avec l'utilisation de try-catch. Si g.run() prend trop de temps ou va dans une boucle infinie, cela ne signifie pas qu'une exception sera levée.

Ce que vous pouvez faire est, vous pouvez déplacer les opérations qui prennent beaucoup de temps dans un autre thread. Démarrez ce thread dans votre gestionnaire d'événements et attendez qu'il se termine dans votre thread principal pendant un certain temps. Si cela ne se termine pas, tuez ce fil & affichez votre message.

Pour référence plus, lisez QThread, Qt Thread Support

0

Merci pour les suggestions. Alors je vois comment je devrais créer le fil, quelque chose comme:

class myopThread : public QThread 
{ 
public: 
    void run(); 
}; 

Je suis en train de réécrire la fonction run() et mettre toutes les opérations qui prennent beaucoup de temps en elle:

void myopThread::run() 
{ 
    polynomial_t p1("x^2-x*y+1"),p2("x^2+2*y-1"); 
    BoundingBox bx(-4.01, 4.01,-6.01,6.01,-6.01,6.01); 
    Topology3d g(bx); 
    AlgebraicCurve* cv= new AlgebraicCurve(p1,p2); 
    g.push_back(cv); 
    g.run(); 
    //other operations on g 

    exec(); 
} 

Ok, tout est clair jusqu'à maintenant, je ne vois toujours pas comment "Démarrer ce thread dans votre gestionnaire d'événements et attendre qu'il se termine dans votre thread principal pendant un certain temps.Si il ne se termine pas, tuer ce thread & montrez votre messagebox. " Je veux dire démarrer le thread dans le gestionnaire d'événements se réfère en quelque sorte à l'aide de la connexion (..Signal, Slot ..) encore je ne vois pas comment cela est fait exactement. Je n'ai jamais utilisé QThread auparavant, donc c'est plus que nouveau.

Merci beaucoup pour votre aide, madalina

0

La façon la plus élégante de résoudre ce que je connaisse est une valeur future. Si vous ne les avez pas déjà rencontrés, ils peuvent être très utiles dans des situations comme celle-ci. Supposons que vous ayez une valeur dont vous aurez besoin plus tard, mais vous pouvez commencer à calculer simultanément. Le code pourrait ressembler à ceci:

SomeValue getValue() { 
    ... calculate the value ... 
} 

void foo() { 
    Future<SomeValue> future_value(getValue); 
    ... other code that takes a long time ... 

    SomeValue v = future_value.get(); 
} 

Lors de l'appel de la méthode .get() bien sûr, la valeur calculée est retournée, que ce soit en appelant la fonction alors et là ou en récupérant la valeur de cache calculée dans un autre thread démarré lorsque Future<T> a été créé. Une bonne chose est que, au moins pour quelques bibliothèques, vous pouvez passer un paramètre de délai dans la méthode .get(). De cette façon, si votre valeur prend trop de temps à calculer, vous pouvez toujours débloquer. Une telle élégance n'est généralement pas atteinte.

Pour une bibliothèque de la vie réelle, vous pouvez essayer de regarder dans la bibliothèque documentée here. Si je me souviens bien, il n'a pas été accepté en tant que bibliothèque officielle des contrats à terme, mais il était certainement prometteur. Bonne chance!