Array as Observable
jheinen opened this issue · comments
How would I use an array as Observable (within a Repeater
)? I both tried using it as a model
parameter or as a value
parameter in the delegate. In the first case the window is empty, in the second case an error occurs ("Unable to assign qmlwrap::qvariant_any_t to double"
).
ENV["QT_QUICK_CONTROLS_STYLE"] = "Fusion"
using QML
using Observables
mktempdir() do folder
path = joinpath(folder, "test.qml")
write(path, """
import QtQuick 2.12
import QtQuick.Controls 2.4
import org.julialang 1.1
ApplicationWindow {
title: "Test"
visible: true
Grid {
rows: 5
columns: 1
Repeater {
model: 5
delegate: Row {
Slider {
value: slider
}
}
}
}
}
""")
slider = Observable(zeros(5))
loadqml(path; slider=slider)
exec_async()
while true
sleep(1)
slider[][5] = rand()
end
end
Hi Josef,
This probably isn't exactly what you are looking for, but with a Repeater
you need to use a ListModel
:
ENV["QT_QUICK_CONTROLS_STYLE"] = "Fusion"
using QML
using Qt5QuickControls2_jll
mktempdir() do folder
path = joinpath(folder, "test.qml")
write(path, """
import QtQuick 2.12
import QtQuick.Controls 2.4
import org.julialang 1.1
ApplicationWindow {
title: "Test"
visible: true
Grid {
rows: 5
columns: 1
Repeater {
model: slider
delegate: Row {
Slider {
onValueChanged: {
sliderval = value;
}
Component.onCompleted: {
value = sliderval;
}
}
}
}
}
}
""")
slidervalues = (collect(0.2:0.2:1.0))
slider = ListModel(slidervalues)
addrole(slider, "sliderval", identity, setindex!)
loadqml(path; slider=slider)
exec()
println("slider values: $slidervalues")
end
At this time, Observables doesn't really fit into that, I'm assuming you want to update the ListModel
from Julia here?
Hi Bart, thanks for you help. This works fine, but how would I now inform the Qt5 run-time to update the slider widget(s) (from an asynchronously triggered function)?
OK, this appears to do the trick:
ENV["QT_QUICK_CONTROLS_STYLE"] = "Fusion"
using QML
using Qt5QuickControls2_jll
qml_data = QByteArray("""
import QtQuick 2.12
import QtQuick.Controls 2.4
import org.julialang 1.1
ApplicationWindow {
title: "Test"
visible: true
Grid {
rows: 5
columns: 1
Repeater {
model: slider
delegate: Row {
Slider {
id: sliderControl
onValueChanged: {
sliderval = value;
}
Component.onCompleted: {
value = sliderval;
}
Connections {
target: slider
function onDataChanged() { sliderControl.value = sliderval; }
}
}
}
}
}
}
""")
slidervalues = (collect(0.2:0.2:1.0))
slider = ListModel(slidervalues)
addrole(slider, "sliderval", identity, setindex!)
qengine = init_qmlengine()
ctx = root_context(qengine)
set_context_property(ctx, "slider", slider)
qcomp = QQmlComponent(qengine)
set_data(qcomp, qml_data, QML.QUrl())
create(qcomp, qmlcontext());
exec_async()
After the exec_async
, you can use the REPL to modify the sliders like this:
slider[1] = 1
Thanks a lot. That works fine ...