Qt destructeur de l'appel d'fermé widget
Il y a une application qui gère les commandes de texte. J'ai un widget Qt qui est fermée avec quelques close *
de commande. Qt::WA_DeleteOnClose
attribut est défini pour ce widget, il reçoit closeEvent, mais destructeur pour cet objet est appelé plus tard (je suppose que sur la veille). Si j'ai deux commandes
close *; get something;
le programme se bloque parce que get something
est appelé avant destructeur pour ce widget, donc il tente d'accéder aux données supprimées par close *
de commande. Comment puis-je la force de Qt pour appeler les destructeurs? QCoreApplication::processEvents()
après la commande de fermeture ne l'aide pas.
J'ai eu ce problème après changement de l'intervalle qt version 4.7.2 de la section 4.3.3. Il n'y a pas de multithreading ici.
Merci d'avance.
ajouté
Voici l'exemple de code.
test *t = new test();
t->show();
std::cout << "before deleteLater()" << std::endl;
t->deleteLater();
std::cout << "after deleteLater()" << std::endl;
QCoreApplication::sendPostedEvents();
QCoreApplication::processEvents();
std::cout << "after processEvents()" << std::endl;
de la classe de test est dérivé de QDialog. Il imprime test()
dans le constructeur et ~test()
dans le destructeur. Ce code donne le résultat suivant
test()
before deleteLater()
after deleteLater()
after processEvents()
~test()
Selon la documentation de Qt, il faut supprimer l'objet de l'avant-dernier cout, ai-je le droit? Ressemble à un bug de Qt, quelqu'un sait quelque chose à ce sujet? Aucune solution de contournement?
J'ai posé la question dans la liste de diffusion Qt, mais toujours en attente d'une réponse.
Grâce.
encore une mise à jour
Ce code
Dialog::~Dialog() {
std::cout << "~test()" << std::endl;
}
int main(int argc, char* argv[]) {
QApplication app(argc, argv);
Dialog* dlg = new Dialog();
dlg->setAttribute(Qt::WA_DeleteOnClose);
dlg->show();
dlg->close();
std::cout << "before sendPostedEvents()" << std::endl;
QCoreApplication::sendPostedEvents();
std::cout << "after sendPostedEvents()" << std::endl;
return app.exec();
}
imprime cette
before sendPostedEvents()
after sendPostedEvents()
~test()
mais dès que j'ajoute closeEvent gestionnaire et appel deleteLater() dans la fonction de gestionnaire sendPostedEvents commence à supprimer des différés d'objets.
void Dialog::closeEvent(QCloseEvent* ev) {
deleteLater();
QWidget::closeEvent(ev);
}
imprime cette
avant sendPostedEvents()
~test()
après sendPostedEvents()
Quelqu'un peut-il expliquer ce que l'enfer qui se passe là-bas? Est-ce juste un bug? Puis-je l'utiliser comme une solution de contournement?
Comment cela fonctionne? Ne devrait pas Qt appel deleteLater() automatiquement, après closeEvent est acceptée si CloseOnDelete attribut est défini?
- S'il vous plaît, pourriez-vous mettre une mise à jour ici si vous trouverez une solution. J'ai le même problème et je suis vraiment curieux de voir comment il pourrait être résolu.
Vous devez vous connecter pour publier un commentaire.
Réglage
Qt::WA_DeleteOnClose
signifie qt pouvez supprimer à tout moment après l'appel declose()
parce que qt utilisedeleteLater()
en interne. Vous pouvez vous assurer de la suppression à l'aide deQObject::détruit()
signal.Qt::WA_DeleteOnClose
drapeau et simplement le supprimer. Vous serez sûr ensuite.sendPostedEvents()
trop. doc.qt.nokia.com/latest/qcoreapplication.html#processEventsdelete obj
avecobj->deleteLater(); QCoreApplication::sendPostedEvents();
ou processEvents() ne fonctionne pas encore.processEvents
devrait supprimer cet objet. Parce quedeleteLater
envoie un événement de widget et de l'appel deprocessEvents
avec aucun argument devrait gère tous les événements publiés. Il peut être un bug de qt. Je pense que vous devriez écrire ce problème [email protected] maillist.QCoreApplication::processEvents explicitement saute supprimer sur les gros événements. Vous avez besoin de passer QEventLoop::DeferredDeletion à processEvents(). c'est à dire QCoreApplication::processEvents(QEventLoop::DeferredDeletion);