Russian Qt Forum
Ноябрь 06, 2024, 04:55 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Связать свойства динамически создаваемых объектов  (Прочитано 7622 раз)
chu
Гость
« : Февраль 20, 2012, 01:54 »

Имеются два типа компонентов: прямоугольники, динамически создаваемые при клике по сцене, и линии, динамически создаваемые при клике на пару прямоугольников. Нужно связать их координаты, чтобы при перемещении прямоугольника, конец связной с ним линии перемещался вслед за ним.

main.qml
Код:
import QtQuick 1.0

Item {
    id: root
    width: 800
    height: 600

    property double x1: 0
    property double y1: 0
    property bool isSecondPoint: false

    function createSceneItem(x,y) {
        var component = Qt.createComponent("Item.qml")
        var object = component.createObject(root)
        object.x =x
        object.y =y
        object.myclick.connect(click)
    }

    function click(xPos, yPos){
        console.log("click",xPos,yPos)
        if(isSecondPoint && (xPos!=x1 && yPos!=y1)) { drawLine(x1,y1,xPos,yPos) }
        else { x1 = xPos; y1 = yPos }
        isSecondPoint = !isSecondPoint
    }

    function drawLine(x1,y1,x2,y2) {
        var component = Qt.createComponent("Line.qml")
        var object = component.createObject(root)
        object.x1 = x1
        object.y1 = y1
        object.x2 = x2
        object.y2 = y2
        var alpha = Math.atan( (y2-y1)/(x2-x1)) * 180/ Math.PI
        alpha = (x2<x1) ? alpha+180 : alpha
        object.alpha = alpha
    }

    MouseArea{
        anchors.fill: root
        acceptedButtons: Qt.RightButton | Qt.LeftButton
        onClicked: {
            createSceneItem( mouseX, mouseY)
        }
    }
}

Item.qml
Код:
import QtQuick 1.0

Item {
    id: item
    signal myclick(double xPos, double yPos)

    Rectangle{
        id: back
        color: "lime"
        width: 100
        height: 50
        anchors.centerIn: item
    }

    MouseArea  {
        id: mousearea
        anchors.fill: back
        drag.target: item
        drag.minimumX: 0; drag.maximumX: 800-back.width
        drag.minimumY: 0; drag.maximumY: 600-back.height

        onClicked: { click(item.x,item.y) }
    }
}

Line.qml
Код:
import QtQuick 1.0

Item {
    id: line
    property double x1: 0
    property double y1: 0
    property double x2: 0
    property double y2: 0
    property double alpha: 0

    Rectangle {
        x: x1
        y: y1
        width: Math.sqrt((x2-x1)*(x2-x1) + (y2-y1)*(y2-y1))
        height: 3
        color: "tomato"
        transform: Rotation { origin.x: x; origin.y: y; angle: alpha}
    }
}
Записан
kvrus
Гость
« Ответ #1 : Февраль 24, 2012, 09:34 »

Привет.
Ничего не могу найти хорошего с этими динамически создающимися объектами. Получается так: динамически создавать объекты можно, но вот делать с ними анимацию или какие нибудь соединения сигналов или изменение свойств ты не сможешь. В примерах динамически создаются объекты в *.js файлах , сразу заносятся в массивы и дальнейшая логика программы может изменять свойства этих объектов только путем перебора всех элементов массива в функции js. Перерисовка объектов так же делается в js по событию таймера и без всяких там эффектов типа EasyCurve.
У меня складывается такой вывод
Если надо рисовать интерфейсы - то либо ты должен заранее знать все свои элементы и создать их один раз, описав их в QML, либо использовать модели для создания произвольного числа элементов (но с объектами в модели так же анимацию не сделаешь, можно поменять свойства через обращение к index из функции js).
 Если надо разработать игру - то в js создавай динамические объекты и сам определяй событие перерисовки (движение в игре) и всякие коллизии между объектами и их свойства. Соответственно связи между свойствами объектов тоже придется писать самому в функции JS.   
Записан
kvrus
Гость
« Ответ #2 : Февраль 24, 2012, 11:16 »

Попробуй сделать так:

Rectangle {
     id: sprite
     width: 25; height: 25
     x: 50; y: 15

     onXChanged: console.log("x property changed, emitted xChanged signal")
     onYChanged: console.log("y property changed, emitted yChanged signal")
}

То есть динамически созданному объекту назначь сигнал на изменение координаты (я так понял можно таким образом сигналы создавать на изменение любого свойства элемента). В обработчике вызови функцию js в которой обработай ситуацию изменения свойства и из скрипта измени свойство того объекта который надо было связать (но вытащить объект можно только перебором по массиву всех объектов).
Записан
OKTA
Гость
« Ответ #3 : Февраль 28, 2012, 00:43 »

http://developer.qt.nokia.com/wiki/QML-Dynamic-Objects
да можно там все)))
Записан
chu
Гость
« Ответ #4 : Февраль 28, 2012, 22:33 »

OKTA, спасибо за ссылку. Прочитал, но ответа на свой вопрос не нашел... Если не сложно, объясни пожалуйста какое решение ты имел ввиду.
Пока сделал по совету kvrus, за что ему огромное спасибо Улыбающийся

Добавил в item свойство num (порядковый номер), и обработку смены координат:
Код:
    onXChanged: posChanged(item.num,item.x,item.y)
    onYChanged: posChanged(item.num,item.x,item.y)
Изменил main.qml :
Код:
import QtQuick 1.0

Item {
    id: root
    width: 800
    height: 600

    signal newPos(int num, double x, double y)

    property int maxNum : 0
    property int lastNum : 0
    property double lastX : 0
    property double lastY : 0
    property bool isSecondPoint : false

    function createSceneItem(x,y) {
        var component = Qt.createComponent("Item.qml")
        var object = component.createObject(root)
        object.x =x
        object.y =y
        object.num = maxNum
        maxNum++
    }

    function click(itemNum, xPos, yPos){
        console.log("click",itemNum,xPos,yPos, isSecondPoint)
        if(isSecondPoint && (xPos!=lastX && yPos!=lastY)) {
            drawLine(lastX,lastY,lastNum, xPos,yPos, itemNum)
        }
        else { lastX = xPos; lastY = yPos; lastNum = itemNum }

        isSecondPoint = (!isSecondPoint)
    }

    function drawLine(x1,y1,num1,x2,y2,num2) {
        var component = Qt.createComponent("Line.qml")
        var object = component.createObject(root)
        object.x1 = x1
        object.y1 = y1
        object.num1 = num1
        object.x2 = x2
        object.y2 = y2
        object.num2 = num2

        newPos.connect(object.repaint)
    }

    function posChanged(itemNum,newX,newY) {
        newPos(itemNum,newX,newY)
    }

    MouseArea{
        anchors.fill: root
        acceptedButtons: Qt.RightButton | Qt.LeftButton
        onClicked: {
            createSceneItem( mouseX, mouseY)
        }
    }
}

Изменил line.qml :
Код:
import QtQuick 1.0

Item {
    id: line
    property int num1: 0
    property int num2: 0
    property double x1: 0
    property double y1: 0
    property double x2: 0
    property double y2: 0

    Rectangle {
        x: x1
        y: y1
        width: Math.sqrt((x2-x1)*(x2-x1) + (y2-y1)*(y2-y1))
        height: 3
        color: "tomato"       
        transform: Rotation { origin.x: x; origin.y: y; angle: calcAlpha(x1,y1,x2,y2)}
    }

    function calcAlpha(x1,y1,x2,y2){
        var alpha = Math.atan( (y2-y1)/(x2-x1)) * 180/ Math.PI
        alpha = (x2<x1) ? alpha+180 : alpha
        return alpha
    }

    function repaint(num,x,y){
        if      (num == num1) { x1 = x; y1 = y}
        else if (num == num2) { x2 = x; y2 = y}
    }
}
Записан
OKTA
Гость
« Ответ #5 : Февраль 29, 2012, 12:39 »

Ну суть какая))) СУть в том, чтобы передавать данные между имеющимся объектом и динамически созданном объектом, верно?)
Так вот есть пара механизмов основных для этого) например:
1. ДСО доступны функции и сигналы его "родителя"
2. ДСО может обращаться к свойствам своего родителя

по ссылке прочитай главу "Communication with Dynamic Objects" - в ней эти 2 случая и разобораны на двух примерах =))
Этого будет более, чем достаточно!!! (=
Записан
chu
Гость
« Ответ #6 : Февраль 29, 2012, 13:27 »

Ну суть какая))) СУть в том, чтобы передавать данные между имеющимся объектом и динамически созданном объектом, верно?)
Нет. Суть в том, чтобы передавать данные между двумя различными динамически созданными объектами.
Похоже что, красивее метода, описанного в моем предыдущем посте, ничего не найти...
Записан
OKTA
Гость
« Ответ #7 : Февраль 29, 2012, 16:01 »

Ну так чего жизнь усложнять, пускай линии твои создаются внутри прямоугольников!)) это же самое простое решение!!! =)))
Записан
chu
Гость
« Ответ #8 : Февраль 29, 2012, 18:49 »

Ну так чего жизнь усложнять, пускай линии твои создаются внутри прямоугольников!)) это же самое простое решение!!! =)))
И каким образом соединить созданную внутри прямоугольника линию с другим прямоугольником Непонимающий
Изначально я так и хотел сделать, но ничего не вышло, линия рисуется только в пределах прямоугольника!!!
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.051 секунд. Запросов: 21.