Russian Qt Forum

Qt => Qt Quick => Тема начата: nwnclv от Ноябрь 30, 2014, 21:21



Название: Про костанты, исключения, итераторы
Отправлено: nwnclv от Ноябрь 30, 2014, 21:21
Hi

тут пара вопросов про С++ + QML, на которые не могу найти ответ.

1: Как правильно протягивать константы из C++ кода? В rootContext как-то не очень охота их ставить. Как это идеологически правильно в QML делается? Например у меня есть интерфейс для работы с неким девайсом, я регаю класс для работы с ним для QML

Код
C++ (Qt)
qmlRegisterType<MyCoolDevice>( ... )
и вот для некоторых его методов ( которые Q_INVOKABLE ) нужны некие константы. Правильно ли эти константы (в C++ описаны как enum) сделать ему read-only свойствами? Есть ли способ зарегать прямо енум, чтоб при его дополнении/изменении не пришлось переписывать свойства класса?

2: Есть ли способ обработки исключений, брошенных в C++ коде, прям в QML?
Структура
Код
Javascript
try { } catch( exception ) { }
  в JS не работает. Приложение просто валится с криком в лог. Если нет такой возможности, то есть ли единая точка входа исполнения всех вызовов из QML, которую я могу обработать из C++. Просто оборачивать каждый вызов как-то это костыльно сильно.

3: У меня есть интерфейс некоего итератора. Можно ли на его основе только из QML/JS строить модель для листа/дерева, например. Примеры почему-то всегда указывают на необходимость постройки модели в C++, и потом уже ее использовать в QML. Выглядит он как-то так

Код
C++ (Qt)
struct iterator_iface {
   virtual ~iterator_iface( ) { }
   virtual void next( ) = 0;
   virtual bool end( ) const = 0;
   virtual iterator_iface *clone( ) const = 0;
   virtual iterator_value &get( ) = 0;
   virtual const iterator_value &get( ) const = 0;
};


Спасибо =)


Название: Re: Про костанты, исключения, итераторы
Отправлено: navrocky от Декабрь 01, 2014, 13:35
Есть ли способ зарегать прямо енум, чтоб при его дополнении/изменении не пришлось переписывать свойства класса?
Зарегать как enum можно, см. Q_ENUMS. Ограничение только в том, что эти enum должны быть объявлены внутри класса наследника от QObject.

2: Есть ли способ обработки исключений, брошенных в C++ коде, прям в QML?
Надо избегать прохождения исключения через внутренности Qt (нельзя кидать в слоте или в Q_INVOKABLE), т.к. исключения официально не поддерживаются. Поэтому тебе в любом случае надо оборачивать и использовать сигналы или коды возврата.

3: У меня есть интерфейс некоего итератора. Можно ли на его основе только из QML/JS строить модель для листа/дерева, например. Примеры почему-то всегда указывают на необходимость постройки модели в C++, и потом уже ее использовать в QML. Выглядит он как-то так
Для создание модели внутри QML надо использовать ListModel или просто список JS типов:
Код
property var list: ["one", "two", "three"]

Если модель из плюсов, то только наследник от QAbstractItemModel. В принципе, ты её можешь обвесить вспомогательными методами, которые будут Q_INVOKABLE и конструировать модель прямо из QML.


Название: Re: Про костанты, исключения, итераторы
Отправлено: nwnclv от Декабрь 01, 2014, 19:12
Спасибо за ответы. Странно, что мне не пришло письмо :-/

Цитировать
Зарегать как enum можно, см. Q_ENUMS. Ограничение только в том, что эти enum должны быть объявлены внутри класса наследника от QObject.

Да вот это я знаю. Проблема в том, что у меня енумы генерятся. В принципе пока и так хватит. Не думаю, что буду менять протокол часто.
Цитировать
Надо избегать прохождения исключения через внутренности Qt (нельзя кидать в слоте или в Q_INVOKABLE), т.к. исключения официально не поддерживаются. Поэтому тебе в любом случае надо оборачивать и использовать сигналы или коды возврата.
Это очень печальная новость :-/ Неужели нет ни малейшего способа положить на стек JS движка какую-нить строку в качестве JS исключения? Ну окей, .. а как обычно делают такие вещи? У меня вызовы возвращают много разношерстной инфы от bool до сложных оъектов. Как сделать универсальный метод, который бы a) не ломал такое поведение, b) не заставлял писателя на QML делать сотню костылей? Вот например такой кусок тестового кода:
Код
Javascript
 
   var f = components.newFs( generalClient )
   var i = f.info( "/dev/random" )
   lbl.text = "file /dev/random: "
       + i.exists + " "
       + i.directory + " "
       + i.empty + " "
       + i.regular + " "
       + i.symlink + " "
    f.writeFile( "/home/data/test.rnd",
                 f.readFile( "/dev/random", 10 ) )
Не хотелось бы ломать такую схему ...

Цитировать
Для создание модели внутри QML надо использовать ListModel или просто список JS типов:
а, с этим более или менее понятно. Но пока не дошел до этого.


Название: Re: Про костанты, исключения, итераторы
Отправлено: nwnclv от Декабрь 02, 2014, 00:14
В общем с исключениями сделал следующее:

Каждый вызов обложил прологом и эпилогом, в котором устанавливаю объекту fail-state и текст ошибки в случае исключений. Выполнение следующего метода будет невозможно пока failed не скинут явно.
Способ корявый и костыльный, но, по всей видимости, единственный доступный для интеграции в QML.  >:(

Можно обертку в JS сделать как-нить так

Код
Javascript
if( f.failed ) {
   throw f.error
}


Название: Re: Про костанты, исключения, итераторы
Отправлено: kambala от Декабрь 02, 2014, 01:04
Есть ли способ зарегать прямо енум, чтоб при его дополнении/изменении не пришлось переписывать свойства класса?
Зарегать как enum можно, см. Q_ENUMS. Ограничение только в том, что эти enum должны быть объявлены внутри класса наследника от QObject.
вообще-то нет: для этого достаточно внутри класса поместить Q_GADGET


Название: Re: Про костанты, исключения, итераторы
Отправлено: navrocky от Декабрь 03, 2014, 10:55
Есть ли способ зарегать прямо енум, чтоб при его дополнении/изменении не пришлось переписывать свойства класса?
Зарегать как enum можно, см. Q_ENUMS. Ограничение только в том, что эти enum должны быть объявлены внутри класса наследника от QObject.
вообще-то нет: для этого достаточно внутри класса поместить Q_GADGET
Хм, спасибо за наводку, этого не знал. Правда, пробросить enum, не лежащие в классе, или enum из существующих классов всё равно не получится. Но это уже к изначальному вопросу не относится...