Wir haben eine ziemlich große QtQuick-Anwendung, mit vielen modalen Dialogen. Alle diese Modalitäten haben ein einheitliches Aussehen und Verhalten und haben Links, Buttons, einen Inhalt und zusätzliche Warnungs-Widgets. Wir verwenden die folgende Basisklasse (PFDialog.qml):Crash in QQuickItem destructor/changeListeners beim Schließen der Anwendung (Qt 5.6)
Window {
property alias content: contentLayout.children
ColumnLayout {
id: contentLayout
}
}
und erklären Dialoge auf folgende Weise (main.qml):
Window {
visible: true
property var window: PFDialog {
content: Text { text: "Foobar" }
}
}
Das Problem ist, dass, wenn die Anwendung geschlossen ist, ein segfault passiert im QQuickItem-Destruktor. Dieser Segfault ist schwer zu reproduzieren, aber hier ist ein todsicherer Weg, dies zu ermöglichen: Mit Visual Studio im Debug-Modus wird der freigegebene Speicher mit 0xDDDDDDD gefüllt, wobei jedes Mal der Segfault ausgelöst wird. https://github.com/wesen/testWindowCrash
Der Absturz passiert in QQuickItem::~QQuickItem
:
for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
QQuickAnchorsPrivate *anchor = d->changeListeners.at(ii).listener->anchorPrivate();
if (anchor)
anchor->clearItem(this);
}
Der Grund dafür ist, dass der Inhalt unseres Dialogs (das Text-Element in dem obigen Beispiel)
Vollbeispielanwendung finden Sie hier ist ein QObject-Kind des Hauptfensters, aber ein visuelles Kind des Dialogfensters. Beim Schließen der Anwendung wird zuerst das Dialogfenster zerstört, und zu dem Zeitpunkt, zu dem das Textelement gelöscht wird, ist das (noch als ChangeListener registrierte) Dialogfenster veraltet.
Nun meine Frage:
- dieser Fehler ein QtQuick ist? Sollte der Dialog sich selbst als changeListener für seine Kinder abmelden, wenn er zerstört wird (ich denke es sollte)
- ist unser
property alias content: layout.children
Muster korrekt, oder gibt es einen besseren Weg dies zu tun? Dies geschieht auch bei der Deklaration eines Standardeigenschaftenalias.
Der Vollständigkeit halber, hier ist, wie wir es in unserer Anwendung Hotfix. Wenn sich der Inhalt ändert, reparieren wir alle Elemente im Layoutelement. A von Eleganz, wie Sie alle zustimmen werden.
Können Sie die Frage bitte mit einem in sich geschlossenen Testfall bearbeiten? –
Es tut mir leid, nicht sicher, ich folge dir. Dies ist ungefähr so eigenständig wie ich kann (die 8 Zeilen an der Spitze sind die ganze Anwendung). Sie können das Repository klonen, wenn Sie etwas aus der Box haben möchten. –
Oh, OK, Entschuldigung, ich habe nicht verstanden, dass es alles war. Vielen Dank! –