Я пытаюсь создать окно, в котором я могу нарисовать треугольники и удалить любой из них с помощью Shape {} . В приведенном ниже примере я могу нарисовать 2 типа треугольника:
- Треугольник вверх: зеленый и заполненный
- Треугольник вниз: желтый и не заполненный
По сути, я выбираю тип треугольника (с кнопкой в правом нижнем углу), затем нажимаю в любом месте окна, чтобы получить треугольник.
Когда я нажимаю, динамически создается треугольник, который сохраняется в свойстве triangleList . Затем я вызываю функцию shape.update () , чтобы обновить data свойство shape. Эта часть работает хорошо.
Здесь обновление функции, которое я использую в Shape (поскольку данные - это список, я должен переназначить новый список.):
function update()
{
data = [];
var d = [];
for (var i = 0; i < canvas.triangleList.length; i++)
{
d.push( canvas.triangleList[i] );
}
data = d;
}
Появляется моя проблема когда я пытаюсь удалить треугольник. В моем примере я могу удалить первый, последний или все треугольники. Когда я удаляю треугольник, сначала я удаляю значение в triangleList , затем я снова вызываю shape.update () . Это работает, когда я удаляю все треугольники или последний.
Однако, когда я пытаюсь удалить первый треугольник, данные не обновляют свои объекты, даже если я даю ему новый список, На самом деле, он всегда удаляет последний треугольник. Ниже приведен пример:
свойство данных понимает, что на один треугольник меньше, но не обновляет другие треугольники. Единственное решение, которое я нашел, это изменить свойство, а затем вернуться к исходному значению. Таким образом, данные принудительно обновляются. Но я должен сделать это для каждого свойства , которое может быть различным (цвета и позиции). Следовательно, моя функция update () выглядит следующим образом:
for (var i = 0; i < canvas.triangleList.length; i++)
{
d.push( canvas.triangleList[i] );
////// Change properties one by one to force the refresh
// Force path redraw. Otherwise only the last path can be deleted
d[i].startX++;d[i].startX--;
// Force line color update
d[i].strokeColor = "red"
d[i].strokeColor = d[i].isUp ? "green" : "yellow";
// Force fill color update
d[i].fillColor = "red";
d[i].fillColor = d[i].isUp ? "green" : "transparent";
data = d;
}
Я предлагаю вам закомментировать эти строки, чтобы увидеть разницу. Я мог бы использовать этот трюк для принудительного обновления, но мой реальный код действительно больше, чем в этом примере, и я использую привязки.
Поэтому мой вопрос: Есть ли способ принудительно обновить обновление без необходимости изменения каждое свойство?
Вот полный код, если вы хотите проверить его:
import QtQuick 2.9;
import QtQuick.Controls 2.2;
import QtQuick.Shapes 1.0;
ApplicationWindow {
visible: true; width: 640; height: 480;
Rectangle {
id: canvas;
anchors.fill: parent;
color: "black";
property var triangleList: [];
property bool triangleUp: true;
MouseArea {
anchors.fill: parent;
onClicked: {
var triangle = componentTriangle.createObject(componentTriangle, {
"isUp" : canvas.triangleUp,
"startX" : mouse.x,
"startY" : mouse.y,
}, canvas);
canvas.triangleList.push(triangle);
shape.update();
}
} // MouseArea
Shape {
id: shape;
anchors.fill: parent;
function update()
{
data = [];
var d = [];
for (var i = 0; i < canvas.triangleList.length; i++)
{
d.push( canvas.triangleList[i] );
///////////// HOW TO AVOID THE PART BELOW? /////////////
////// Change properties one by one to force the refresh
// Force path redraw. Otherwise only the last path can be deleted
d[i].startX++;d[i].startX--;
// Force line color update
d[i].strokeColor = "red"
d[i].strokeColor = d[i].isUp ? "green" : "yellow";
// Force fill color update
d[i].fillColor = "red";
d[i].fillColor = d[i].isUp ? "green" : "transparent";
//////////////////////////////////////////////////////
}
data = d;
// I make sure data has at least one path to ensure the refresh
if (data.length == 0)
data.push(Qt.createQmlObject('import QtQuick 2.9; import QtQuick.Shapes 1.0; ShapePath {startX:0;startY:0;}', canvas,
"force_refresh"));
}
} // Shape
} // Rectangle
//////////// Buttons to handle the triangles
Column {
anchors.bottom: parent.bottom;
anchors.right: parent.right;
Button {
text: canvas.triangleUp? "Draw triangleUp" : "Draw triangleDown";
onClicked: { canvas.triangleUp = !canvas.triangleUp; }
} // Button
Button {
text: "Clear first";
onClicked: {
canvas.triangleList[0].destroy();
canvas.triangleList.splice(0,1);
shape.update();
}
} // Button
Button {
text: "Clear last";
onClicked: {
canvas.triangleList[canvas.triangleList.length -1].destroy();
canvas.triangleList.splice(canvas.triangleList.length -1,1);
shape.update();
}
} // Button
Button {
text: "Clear all";
onClicked: {
for (var i = 0; i < canvas.triangleList.length; i++)
canvas.triangleList[i].destroy();
canvas.triangleList = [];
shape.update();
}
} // Button
}
//////////// Component to draw the triangle
Component {
id: componentTriangle;
ShapePath {
property bool isUp;
property real offsetX: isUp? -20 : 20;
property real offsetY: isUp? -30 : 30;
strokeColor: isUp ? "green" : "yellow";
strokeWidth: 3;
fillColor: isUp ? "green" : "transparent";
PathLine { x: startX - offsetX; y: startY - offsetY }
PathLine { x: startX + offsetX; y: startY - offsetY }
PathLine { x: startX; y: startY }
} // ShapePath
}
}
Большое спасибо за вашу помощь и не стесняйтесь спрашивать меня, если я не был ясен .
Хорошего дня!