#qt #qml
#qt #qml
Вопрос:
Я пытаюсь динамически создавать, а затем уничтожать компонент на основе взаимодействия пользователя с флажком в QML. Установите флажок «Создать компонент». Снимите флажок, уничтожьте компонент. Создание компонента работает, но его уничтожение — нет. Компонент все еще там.
В документации в QT docs здесь упоминается, что метод destroy должен работать после создания компонента. Есть идеи, что я могу здесь делать неправильно? Приведенный ниже код.
import QtQuick 2.7
import QtQuick.Layouts 1.1
import QtQuick.Controls 2.1
Rectangle {
property var deficiencyType
width: 600
height: 800
color:"white"
CheckBox {
id:checkbox
text: "Check deficiency on/off"
onClicked: {
if (checked) {
deficiencyType = Qt.createComponent("Form.qml")
deficiencyType.createObject(columnRef)
} else {
deficiencyType.destroy()
console.log(deficiencyType)
}
}
}
ColumnLayout {
id:columnRef
Layout.fillHeight: true
Layout.fillWidth: true
anchors {
top: checkbox.bottom
topMargin: 10
}
}
}
Ответ №1:
Для этого случая вы могли бы использовать загрузчик, например :
import QtQuick 2.7
import QtQuick.Layouts 1.1
import QtQuick.Controls 2.1
Rectangle {
width: 600
height: 800
color:"white"
CheckBox {
id: checkBox
text: "Check deficiency on/off"
}
ColumnLayout {
Layout.fillHeight: true
Layout.fillWidth: true
anchors {
top: checkbox.bottom
topMargin: 10
}
Loader {
id: formLoader
active: checkBox.checked
source: "Form.qml"
}
}
}
Существует несколько способов обработки динамических компонентов QML. Вы также должны проверить эти :
Редактировать:
Чтобы обрабатывать динамическое создание нескольких элементов из определенной модели, вы должны использовать повторитель, подобный этому :
import QtQuick 2.7
import QtQuick.Layouts 2.14
import QtQuick.Controls 2.14
Rectangle {
width: 600
height: 900
color:"white"
property ListModel forms: ListModel {
ListElement {
formName: "Form one"
formSource: "Form1.qml"
}
ListElement {
formName: "Form two"
formSource: "Form2.qml"
}
ListElement {
formName: "Form three"
formSource: "Form3.qml"
}
}
RowLayout {
anchors.fill: parent
Repeater {
model: forms
delegate: Item {
CheckBox {
id: checkBox
text: "Check " modelData.formName " on/off"
}
ColumnLayout {
Layout.fillHeight: true
Layout.fillWidth: true
anchors {
top: checkbox.bottom
topMargin: 10
}
Loader {
active: checkBox.checked
source: modelData.formSource
}
}
}
}
}
}
Комментарии:
1. Я согласен, что большую часть времени Qt.createComponent/ CreateObject не нужен. Чем меньше императивного кода, тем лучше. Чтобы быть еще более декларативным, вы могли бы просто привязать свойство Loader
active
checked
к свойству CheckBox и избавиться от обработчикаonClicked
сигналов.2. Спасибо за пример загрузчика. Это определенно сработало бы для примера, который я привел выше. Но я не упомянул, что у меня есть 10 разных флажков, которые генерируют 10 разных форм, возможно, одновременно. Итак, мне нужно установить несколько источников для источника загрузчика. Вот почему я сначала не преследовал Loader. Я могу создать 10 разных загрузчиков, но является ли это лучшей практикой здесь?
3. Вы должны использовать повторитель для динамического создания нескольких разных элементов QML. Посмотрите на
model
свойство, которое позволяет вам предоставлять модель списка данных.
Ответ №2:
Как сказал @Alaenix, вместо вас может работать загрузчик. Но, чтобы прямо ответить на ваш вопрос, проблема с вашим destroy() заключается в том, что вы уничтожаете компонент, а не созданный вами объект. Итак, меняем этот код:
deficiencyType = Qt.createComponent("Form.qml")
deficiencyType.createObject(columnRef)
к этому:
var component = Qt.createComponent("Form.qml")
deficiencyType = component.createObject(columnRef)
должно решить вашу проблему.
Комментарии:
1. Хотя использование загрузчиков может быть лучшей практикой, как сказал @Alaenix, этот ответ решает проблему, с которой я столкнулся. Я не упоминал, что мне приходилось генерировать несколько форм, поэтому для настройки загрузчиков потребуется больше времени. Но это отлично работает для меня.