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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: Динамическое создание объектов  (Прочитано 6831 раз)
lighting
Гость
« : Февраль 05, 2013, 17:10 »

Пробовал создавать объекты в QML динамически, из js файла как в примере samegame. В целом все получилось, но возникла одна проблема которую никак не придумаю как обойти.
Создаю объект из следующего qml файла
Код
Javascript
import QtQuick 1.1
import "../../worker.js" as Worker
 
Item {
   id: base
   property bool selected: false;
   property int index: 0
   width: childrenRect.width
   height: childrenRect.height
   Rectangle {
       anchors.fill: caption
       color: "transparent"
       visible: selected
       border {color: "steelblue"; width: 2}
   }
   Text {
       id: caption
       color: "white"
   }
   MouseArea {
       id: mouseArea
       anchors.fill: parent
       onPressed: Worker.changeSelection(base.index);
   }
}
 
глобальные переменные JavaScript файла
var maxIndex = 10;
var labels = new Array(maxIndex);  //массив хранящий динамически созданные объекты

Функция в которой создаются объекты:
Код
Javascript
function addLabel(text) {
   var component;
   for (var i = 0; i < maxIndex; i++)
       if (labels[i] == null)
       {
           component = Qt.createComponent("TextLabel.qml");
           if (component.status == Component.Ready)
           {
               var dynamicObject = component.createObject(editPage);
               if (dynamicObject == null) {
                   console.log("error creating label", component.errorString());
                   return false;
               }
               dynamicObject.selected = false;
               dynamicObject.x = editPage.width/2;
               dynamicObject.y = editPage.height/20;
               dynamicObject.text = text;
               dynamicObject.index = i;
 
           } else {
               console.log("error loading block component", component.errorString());
               return false;
           }
           labels[i] = dynamicObject;
           return true;
       }
}

Функция которая вызывается по событию из созданного объекта
Код
Javascript
function changeSelection(index) {
   if (selectedLabelIndex == -1) labels[index].selected = true;
...
}
Проблема заключается в следующем - если вызывать changeSelection() из js файла или main.qml то все работает нормально, но в случае если вызвать ее из созданного объекта (onPressed: Worker.changeSelection(base.index)Подмигивающий то получаю сообщение об ошибке labels[index] - undefined.
Насколько я понял проблема возникла из-за того что объекты хранящиеся в labels создавались внутри addLabel() и т.к. они создавались с помощью  Qt.createComponent() то им присвоился контекст addLabel() который был по выходу из функции удален и соответственно глобальную переменную labels в их контексте уже не видно. Собственно вопрос - как сменить контекст для создаваемых объектов чтобы labels в нем был виден.
Записан
twp
Гость
« Ответ #1 : Февраль 10, 2013, 13:55 »

а можно выложить архив с кодом чтоб самому попробовать?
Записан
lighting
Гость
« Ответ #2 : Февраль 12, 2013, 14:38 »

извини за задержку, вот проект. Замысел был в том чтобы можно было добавлять Label, по щелчку выделялся конкретный экземпляр, после чего его можно было бы таскать по всей форме, но пока-что это не получается.
Записан
twp
Гость
« Ответ #3 : Февраль 12, 2013, 22:52 »

В общем основная проблема в том, что JS скрипт Worker было объявлен и в main.qml и в TextLabel.qml что в итоге привело к тому, что у каждого был свой экземпляр Worker. Я немного подправил твой пример, убрал Worker из TextLabel.qml и добавил ему сигнал clicked(). При создании объекта TextLabel этот сигнал динамически коннектится со слотом onLabelClicked() из в main.qml и уже в нем происходит передача индекса TextLabel в Worker.changeSelection(). Там же установливается цель для перетаскивания, поскольку такой биндинг не работает
Код
Javascript
drag.target: Worker.selectedLabel == null ? test : Worker.selectedLabel
 
скорее всего потому что Worker не QML объект и соответсвенно selectedLabel не является свойством QML объекта
Там еще осталась проблема с перетаскиванием - TextLabel таскается только когда кликаешь вне ее области
Записан
lighting
Гость
« Ответ #4 : Февраль 13, 2013, 13:24 »

twp спасибо за подсказку, я искал да не там. Никак не думал что у меня  будет два ( и даже больше) экземпляра Worker.
Биндинг не получается скорее всего из-за того что нет сигнала, указывающего что Worker.selectedLabel изменился. Ну а проблема с перетаскиванием это мелочь, в лоб можно решать так
Код
Javascript
   MouseArea {
...
       enabled: !selected
...
   }
в TextLabel, ну или поэлегантнее способ найти.
Записан
twp
Гость
« Ответ #5 : Февраль 13, 2013, 22:52 »

twp спасибо за подсказку, я искал да не там. Никак не думал что у меня  будет два ( и даже больше) экземпляра Worker.
А отладчиком пользовался? Это довольно легко определить, если поставить точки останова в функциях Worker. Отладчик сразу показывает количество labels, а оно разное для main.qml и TextLabel.qml
Записан
lighting
Гость
« Ответ #6 : Февраль 14, 2013, 09:57 »

В QML я пока-что отлаживал только с помощью console.log  видимо надо переходить к более действенным инструментам.
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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