Просто сделайте два объекта qml дочерними элементами корня Item
, а затем возьмите этот корневой элемент, и он захватит все его содержимое.
Просто убедитесь, что корневой элемент достаточно велик, чтобы вместить дочерние элементы, а дочерние элементы не находятся в отрицательном пространстве, потому что он захватит только то, что находится внутри посадочного места корневого элемента.
Вы также можете выполнять композицию вручную из C++ или даже QML.
Проблема, описанная в вашем комментарии, заключается в том, что вы не можете перемещать вещи, так что вы можете сделать? Вместо исходных объектов QML в качестве родителей одного и того же корня вы можете иметь два элемента Image
, затем вы захватываете элемент A и устанавливаете результат захвата в качестве источника изображения A, затем делаете то же самое для элемента B и, наконец, , вы захватываете корневой элемент, который захватывает два изображения вместе.
Хорошо, вот быстрый пример, он выглядит немного сложным, потому что захваты являются асинхронными, и вам нужно дождаться завершения отдельных результатов захвата, прежде чем вы сможете получить «последний» корневой элемент, поэтому используется таймер. В этом примере разные предметы выложены в ряд, но вы можете скомпоновать их как угодно:
ApplicationWindow {
id: window
visible: true
width: 640
height: 480
Rectangle {
id: s1
visible: false
width: 200
height: 200
color: "red"
}
Rectangle {
id: s2
visible: false
width: 200
height: 200
color: "blue"
}
Row {
id: joiner
visible: false
Image { id: t1 }
Image { id: t2 }
}
Image {
id: result
y: 200
}
Timer {
id: finish
interval: 10
onTriggered: joiner.grabToImage(function(res) {result.source = res.url})
}
Component.onCompleted: {
s1.grabToImage(function(res) {t1.source = res.url})
s2.grabToImage(function(res) {t2.source = res.url; finish.start() })
}
}
Сначала два прямоугольника захватываются и используются в качестве источников для изображений в джойнере, затем джойнер захватывается и отображается в результирующем изображении, все объекты, кроме конечного результирующего изображения, скрыты.
Еще проще, вы можете использовать этот изящный маленький помощник, чтобы быстро объединить любое количество элементов в одном изображении:
Item {
id: joinHelper
visible: false
property Component ic: Image { }
property var cb: null
Row { id: joiner }
Timer {
id: finish
interval: 100
onTriggered: joiner.grabToImage(joinHelper.cb)
}
function join(callback) {
if (arguments.length < 2) return // no items were passed
var i
if (joiner.children.length) { // clean previous captures
for (i = 0; i < joiner.children.length; ++i) {
joiner.children[i].destroy()
}
}
cb = callback // set callback for later
for (i = 1; i < arguments.length; ++i) { // for every item passed
var img = ic.createObject(joiner) // create empty image
// need to capture img by "value" because of JS scoping rules
// otherwise you end up with only one image - the final one
arguments[i].grabToImage(function(temp){ return function(res){temp.source = res.url}}(img))
}
finish.start() // trigger the finishing step
}
}
И вы используете это так:
joinHelper.join(function(res) { result.source = res.url }, s1, s2)
Он по-прежнему использует строку, но вы можете легко настроить ее для создания собственного макета. Он работает, передавая окончательный обратный вызов и все элементы, которые вы хотите захватить, внутри он создает изображение для каждого элемента, помещает их в контейнер, а затем запускает таймер завершения.
Обратите внимание, что в зависимости от того, насколько быстро работает система, насколько сложны элементы и каково их количество, вам может потребоваться увеличить интервал таймера, потому что окончательный обратный вызов должен выполняться только после того, как все захваты были завершены, источники изображений были назначены и размеры изображений были изменены, чтобы придать ряду правильные размеры.
Я также аннотировал большинство вещей, чтобы их было легче понять.
person
dtech
schedule
10.07.2017