我正在尝试制作一个窗口,在其中可以绘制三角形并使用Shape {}]删除其中的任何三角形。在下面的示例中,我可以绘制两种类型的三角形:
[基本上,我选择三角形的类型(在右下角带有按钮),然后单击窗口上的任意位置以获取三角形。
一旦单击三角形,就会动态创建一个三角形,并将其存储在属性triangleList
中。然后,我调用函数shape.update()来更新shape的data属性。这部分效果很好。这里是我在Shape中使用的功能更新(因为数据是列表,所以我必须重新分配到新列表。):
中的值,然后再次调用shape.update()。当我删除所有三角形或最后一个三角形时,它会起作用。function update() { data = []; var d = []; for (var i = 0; i < canvas.triangleList.length; i++) { d.push( canvas.triangleList[i] ); } data = d; }
我尝试删除三角形时出现问题。在我的示例中,我可以删除第一个,最后一个或所有三角形。删除三角形时,首先删除triangleList
但是,当我尝试删除第一个三角形时,即使给它一个新列表,数据也不会更新其对象
。实际上,它总是删除最后一个三角形。下面是一个例子:数据属性可以理解,三角形少了一个,但它不会更新其他三角形。我发现的唯一解决方案是更改属性,然后返回到原始值。这样,它将强制更新数据。但是我必须对every property
进行更改(颜色和位置)。因此,我的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 } }
非常感谢您的帮助,如果我不清楚,请随时问我。
祝您有美好的一天!
我正在尝试制作一个窗口,在其中绘制三角形并使用Shape {}删除其中的任何三角形。在下面的示例中,我可以绘制两种类型的三角形:向上的三角形:绿色和实心的向下的三角形:黄色...
如果要处理许多项目(形状),建议对模型使用中继器。转发器负责根据模型的信息显示项目,并删除项目,而您只需要从模型中删除项目即可。