QML Как рисовать разные для grabToImage()
Есть ли какой-нибудь возможный способ сделать grabToImage()
буфер отличается от того, что отображается в графическом интерфейсе? я использую ChartView
без легенды в графическом интерфейсе и хотите экспортировать его в PNG
с легендой. Итак, я стараюсь:
chartView.legend.visible = true
chartView.update()
chartView.grabToImage(function(result) {
console.log("grabbed")
var path = filename.toString().replace(/^(file:\/{2})/,"");
console.log(path + result.saveToFile(path));
chartView.legend.visible = false
update();
});
Но оба эти обновления происходят только после того, как элемент управления выходит из этой функции, поэтому я не получаю легенду в PNG. Также хотелось бы, чтобы появление легенды было незаметным для пользователя. Есть ли способы сделать это в QML?
1 ответ
Я не уверен, правильно ли я вас понял.
Мое предложение состоит в том, чтобы не схватить Item
вы отображаете, но копию этого, который вы затем изменяете, как вам нравится.
Копирование здесь не означает, что у вас есть один и тот же объект дважды, но что вы визуализируете его дважды, используя ShaderEffectSource
, Прежде чем схватить это ShaderEffectSource
к изображению, вы можете добавить все, что вам нравится.
В моем примере я показываю простой Rectangle
с хорошим градиентом. Что я сохраняю, то же самое Rectangle
который расширяется Text
'Я легенда'. Пользователь не увидит этот текст в представлении в любое время.
Rectangle {
id: commonView
width: 200
height: 200
gradient: Gradient {
GradientStop { position: 0; color: 'steelblue' }
GradientStop { position: 1; color: 'orange' }
}
MouseArea {
anchors.fill: parent
// don't grab the rectangle itself.
onClicked: legendView.grabToImage(function(result) {
console.log(result.saveToFile("something.png"));
});
}
}
ShaderEffectSource {
id: legendView
visible: false // Does not need to be shown.
sourceItem: commonView
width: 200
height: 200
Text {
anchors {
right: parent.right
bottom: parent.bottom
}
text: 'I am legend'
}
}
Вы можете оптимизировать производительность, только имея ShaderEffectSource
активен или даже создан при необходимости.
Вы можете использовать ShaderEffectSource.live
-возможность отключить его обновление. Тогда используйте scheduleUpdate()
запустить обновление.
Это может выглядеть так:
Rectangle {
id: commonView
width: 200
height: 200
gradient: Gradient {
GradientStop { position: 0; color: 'steelblue' }
GradientStop { id: gs1; position: 1; color: 'orange' }
}
MouseArea {
anchors.fill: parent
onClicked: {
gs1.position -= 0.1
legendView.save()
}
}
}
ShaderEffectSource {
id: legendView
y: 200
visible: false // Do not render it (will only be rendered when called grapToImage()
sourceItem: commonView
width: 200
height: 200
live: false // Will only be updated, when explicitly called for
function save() {
console.log('Schedule Save')
scheduleUpdate() // explicitly update. grabToImage() will force rendering afterwards.
legendView.grabToImage(function(result) {
console.log(result.saveToFile("something" +gs1.position.toFixed(1) + ".png"));
})
}
// Put additional stuff on it.
Text {
anchors {
right: parent.right
bottom: parent.bottom
}
text: 'I am legend!'
}
}