我正在尝试模仿QML中的patcher接口,其中用户可以单击节点并按照此处显示的方式将其连接到另一个节点:
https://youtu.be/rtgGol-I4gA?t=4m15s
最终在QML中连接这些节点将在相应的C ++图中设置指针。创建一个QML节点实例化一个C ++等价物,到目前为止一直很好。但是对于该死的补丁本身,我无法找到一个聪明的解决方案。
我试图制作一个补丁"在第一次单击时实例化的类,然后使用拖放连接到第二个。它提供了一个起点和终点,以便画布可以绘制补丁(线)。初始端点本身,一旦点击第二个节点就会被修改......
import QtQuick 2.7
Item {
id: root
height: 30
width: 30
property Canvas myCanvas
property var start
property var end
Component.onCompleted: {
end = root
}
onXChanged: myCanvas.requestPaint()
onYChanged: myCanvas.requestPaint()
Rectangle {
id: rect
color: "blue"
anchors.fill: root
MouseArea {
id: mouseArea
anchors.fill: rect
Drag.active: true
drag.target: root
drag.axis: Drag.XAndYAxis
drag.minimumX: 0
drag.minimumY: 0
onReleased: mouseArea.Drag.drop()
}
}
}
但是在创建时设置拖动不起作用,它仍然需要鼠标释放和另一次单击/拖动。 (我也不能让这一点下降,但一次只能解决一个问题......)
我对正确的方法表达了一些意见。
答案 0 :(得分:1)
我会在C++
中将其作为一个固定项,一个"字段"。我的意思是绘制所有节点和"补丁"在此项目中,实施QQuickItem
或QQuickPaintedItem
。因此,您可以根据需要重新实现所有鼠标事件。您也可以使用Canvas
完成所有工作,例如:
import QtQuick 2.7
import QtQuick.Window 2.0
impor
Window
{
id: mainWindow
width: 800
height: 800
x: (Screen.width - width) / 2
y: (Screen.height - height) / 2
visible: true
Canvas {
id: canvas
property var objects: []
property var connections: []
property int objectSize: 50
property int objectCount: 30
property point startPoint: Qt.point(0,0)
property point endPoint: Qt.point(0,0)
anchors.fill: parent
focus: true
Component.onCompleted: {
fillField();
}
function fillField() {
for(var i = 0;i < canvas.objectCount;i ++) {
do {
var x = canvas.objectSize + Math.round(Math.random() * (mainWindow.width - canvas.objectSize * 2));
var y = canvas.objectSize + Math.round(Math.random() * (mainWindow.height - canvas.objectSize * 2));
if(checkCoord(x, y) === true) {
objects.push(Qt.point(x,y));
break;
}
} while(true);
}
canvas.requestPaint();
}
function checkCoord(_x, _y) {
for(var i = 0;i < objects.length;i ++) {
if(Math.abs(objects[i].x - _x) < canvas.objectSize &&
Math.abs(objects[i].y - _y) < canvas.objectSize) {
return objects[i];
}
}
return true;
}
onPaint: {
var ctx = getContext("2d");
ctx.beginPath();
ctx.fillStyle = Qt.rgba(1,1,1,1);
ctx.fillRect(0,0,width,height);
ctx.fillStyle = Qt.rgba(1, 0, 0, 1);
ctx.strokeStyle = Qt.rgba(0.8, 0.8, 0.8, 1);
ctx.lineWidth = 3;
ctx.lineCap = "round";
ctx.lineJoin = "round";
for(var i = 0;i < objects.length;i ++) {
ctx.ellipse(objects[i].x - canvas.objectSize/2,objects[i].y - canvas.objectSize/2,canvas.objectSize,canvas.objectSize);
}
if(startPoint.x !== 0 && startPoint.y !== 0) {
ctx.moveTo(startPoint.x, startPoint.y);
ctx.lineTo(endPoint.x, endPoint.y);
}
ctx.fill();
ctx.stroke();
ctx.beginPath();
ctx.strokeStyle = Qt.rgba(0, 0, 1, 1);
ctx.lineWidth = 5;
for(var i = 0;i < connections.length;i ++) {
ctx.moveTo(connections[i].start.x, connections[i].start.y);
ctx.lineTo(connections[i].end.x, connections[i].end.y);
}
ctx.stroke();
ctx.beginPath();
ctx.fillStyle = Qt.rgba(1,1,0,1);
for(var i = 0;i < connections.length;i ++) {
ctx.ellipse(connections[i].start.x - 5, connections[i].start.y - 5, 10, 10);
ctx.ellipse(connections[i].end.x - 5, connections[i].end.y - 5, 10, 10);
}
ctx.fill();
}
MouseArea {
anchors.fill: parent
onPressed: {
var point = canvas.checkCoord(mouse.x, mouse.y);
if(point !== true) {
canvas.startPoint = point;
}
else
canvas.startPoint = Qt.point(0,0);
}
onReleased: {
if(canvas.startPoint.x === 0 && canvas.startPoint.y === 0)
return;
var point = canvas.checkCoord(mouse.x, mouse.y);
if(point === true)
canvas.startPoint = Qt.point(0,0);
else {
if(point.x !== canvas.startPoint.x || point.y !== canvas.startPoint.y) {
canvas.connections.push({
start: Qt.point(canvas.startPoint.x,canvas.startPoint.y),
end: Qt.point(point.x, point.y)
});
}
canvas.startPoint = Qt.point(0,0);
}
canvas.requestPaint();
}
onPositionChanged: {
if(canvas.startPoint.x !== 0 && canvas.startPoint.y !== 0){
canvas.endPoint = Qt.point(mouse.x, mouse.y);
canvas.requestPaint();
}
}
}
Keys.onPressed: {
switch(event.key)
{
case Qt.Key_Escape:
canvas.objects = [];
canvas.connections = [];
canvas.startPoint = Qt.point(0,0);
canvas.endPoint = Qt.point(0,0);
canvas.fillField();
break;
case Qt.Key_Backspace:
canvas.connections.pop();
canvas.requestPaint();
}
}
}
Text {
text: " Esc - rearange, Backspace - undo ";
}
Text {
text: "Draw your own constellation"
font.bold: true
font.capitalization: Font.AllUppercase
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: parent.top
}
}