In QtQuick 2 mit den QtQuick Controls können Sie komplexe Desktop-Anwendungen erstellen. Es scheint mir jedoch, dass die gesamte UI beim Start der App deklariert und gleichzeitig erstellt werden muss. Alle Teile, die Sie nicht wollen, noch verwenden (zum Beispiel die File-> Öffnen-Dialog) noch erstellt werden müssen, aber sie sind versteckt, wie folgt aus:Qt 5 QML App mit vielen Windows oder komplexen UIs
ApplicationWindow {
FileDialog {
id: fileOpenDialog
visible: false
// ...
}
FileDialog {
id: fileSaveDialog
visible: false
// ...
}
// And so on for every window in your app and every piece of UI.
Nun, dies kann für einfache Anwendungen in Ordnung sein, aber für komplexe oder Apps mit vielen Dialogen ist das sicher eine verrückte Sache? Im traditionellen QtWidgets-Modell würden Sie Ihren Dialog bei Bedarf dynamisch erstellen.
Ich weiß, dass es einige Problemumgehungen dafür gibt, z. Sie können ein Loader
verwenden oder sogar QML-Objekte dynamisch direkt in Javascript erstellen, aber sie sind sehr hässlich und Sie verlieren alle Vorteile der netten QML-Syntax. Außerdem können Sie die Komponenten nicht wirklich "entladen". Nun, Loader
Ansprüche können Sie, aber ich habe es ausprobiert und meine App abgestürzt.
Gibt es eine elegante Lösung für dieses Problem? Oder muss ich einfach in den sauren Apfel beißen und alle möglichen UI für meine App auf einmal erstellen und dann die meisten davon verstecken?
Hinweis: this page hat Informationen über die Verwendung von Loader
s, um dies zu umgehen, aber wie Sie sehen können, ist es keine sehr nette Lösung.
Edit 1 - Warum ist Loader suboptimal?
Ok, um Ihnen zu zeigen, warum Loader
nicht wirklich so angenehm ist, betrachten Sie dieses Beispiel, das eine komplexe Aufgabe startet und auf ein Ergebnis wartet. Nehmen wir an, dass - im Gegensatz zu allen trivialen Beispielen, die normalerweise von Leuten gegeben werden - die Aufgabe viele Eingaben und mehrere Ausgaben hat.
Dies ist die Loader
Lösung:
Window {
Loader {
id: task
source: "ComplexTask.qml"
active: false
}
TextField {
id: input1
}
TextField {
id: output1
}
Button {
text: "Begin complex task"
onClicked: {
// Show the task.
if (task.active === false)
{
task.active = true;
// Connect completed signal if it hasn't been already.
task.item.taskCompleted.connect(onTaskCompleted)
}
view.item.input1 = input1.text;
// And several more lines of that...
}
}
}
function onTaskCompleted()
{
output1.text = view.item.output1
// And several more lines...
// This actually causes a crash in my code:
// view.active = false;
}
}
Wenn ich es ohne Loader
tun war, habe ich so etwas wie dieses haben könnte:
Window {
ComplexTask {
id: task
taskInput1: input1.text
componentLoaded: false
onCompleted: componentLoaded = false
}
TextField {
id: input1
}
TextField {
id: output1
text: task.taskOutput1
}
Button {
text: "Begin complex task"
onClicked: task.componentLoaded = true
}
}
die offensichtlich Weg ist einfacher. Was ich will eindeutig ist eine Möglichkeit für die ComplexTask
geladen werden und haben alle seine deklarativen Beziehungen aktiviert, wenn componentLoaded
auf True festgelegt ist, und dann die Beziehungen getrennt haben und die Komponente entladen, wenn componentLoaded
auf false festgelegt ist. Ich bin mir ziemlich sicher, dass es momentan keine Möglichkeit gibt, etwas in Qt zu machen.
Warum ist die Loader Lösung nicht schön? Warum ist es hässlich? Wenn Ihre App beim Setzen von "aktiv" auf "false" abstürzt, handelt es sich entweder um einen Fehler in Ihrer App oder über den Qt-Code und ist kein Argument gegen die Verwendung von Loader. Warum ist die Sichtbarkeit von Dingen in einer großen Anwendung verrückt? – Mitch
Das hört sich ein bisschen so an, als würde ich dich verhören, aber es sind nur wirklich neugierige Fragen. :) – Mitch
Siehe Updates. Und die Sichtbarkeit in großen Apps auf false zu setzen, ist verrückt, weil die Komponente immer noch geladen ist und Ressourcen verwendet. Es ist wie diese "eine Seite Websites", die alles vorladen. Sie sind in Ordnung, wenn Sie nur ein paar Seiten haben, aber Sie können diese Technik nicht verwenden, wenn Sie ein eBay oder Amazon machen. – Timmmm