Форум программистов, компьютерный форум, киберфорум
QML
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.73/11: Рейтинг темы: голосов - 11, средняя оценка - 4.73
487 / 365 / 93
Регистрация: 10.03.2011
Сообщений: 1,513
Записей в блоге: 5
1

Композиция в связывании C++ и QML

30.05.2018, 21:02. Показов 2046. Ответов 15
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Есть у меня один класс, который я хочу впихнуть в QML. Он представляет из себя набор структур. Пусть для удобства изложения это будет персонаж ЧМОРПГ. Класс состоит из структур поменьше, каждая из которых имеет флаг наличия.
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
struct CharacterPart 
{ 
    bool m_valid;
    virtual QDataStream& operator << (QDataStream&) const = 0;
    virtual QDataStream& operator >> (QDataStream&) = 0;
};
struct CharacterPartHealth : public CharacterPart
{ 
    int m_maxHP;
    int m_curHP;
    QDataStream& operator << (QDataStream&) const { /*...*/ };
    QDataStream& operator >> (QDataStream&) { /*...*/ };
};
struct CharacterPartItem : public CharacterPart
{ 
    int m_id
    QDataStream& operator << (QDataStream&) const { /*...*/ };
    QDataStream& operator >> (QDataStream&) { /*...*/ };
};
 
struct Character 
{
    CharacterPartHealth m_part1;
    QVector<CharacterPartItem> m_part2;
    // ...
};
Класс используется для хранения данных персонажа игры, получаемых от сервера. Персонаж никогда не приходит к нам целиком, его приходится набирать кусками из разных сообщений и локальных данных, потому и такие сложности.

Плохие новости:
- Данные хранятся не только в виде структур, но и в различных контейнерах (например, инвентарь хранится в QVector).
- Динамической памяти не используется. Всё создаётся на стеке.
- Класс очень большой - порядка трёхсот структур с максимальной глубиной вложенности 10, порядка тысячи полей.
- Существующий код везде использует ссылки на структуры и прямой доступ к полям. Его очень много.
Хорошие новости:
+ Класс описан в XML-файле, так что можно сгенерировать всё, что душе угодно. Текущая версия так и получена.

Цель минимум - получить доступ из QML на чтение ко всем полям, включая контейнеры.
Цель максимум - получать полноценные объекты, полностью наблюдаемые из QML, с минимальным оверхедом по памяти и размеру метаклассов, и с изменением существующих обращений из C++ кода через банальный регексп. Да, я понимаю, что губа у меня не дура, но лучше мечтать о молодой Мерлин Монро, чем о старой Мадонне.

Что мне нужно от вас: идеи несколько лучше, чем унаследовать всё от QObject. Летали, знаем, не летает. Собсно, проблема в том, что в QML я глубоко не погружался, и тем более, в связывание QML с C++.
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
30.05.2018, 21:02
Ответы с готовыми решениями:

Выяснить, что представляют из себя отношения Ф композиция Ф и Ф композиция Ф^{-1}
Добрый день. До этого у меня было такое задание: Выяснить, какими из свойств: рефлексивность,...

Подсветка QML элементов QML-ного плагина в QtCreator в случае нахождения QML файлов плагина в ресурсах!
Здравствуйте! Если сделать плагин для QML и подключить его в основном проекте ну как - то так:...

QMl/QT при нажатии на кнопку должен окрыться другой qml файл
Додал anchors Вот что я сделал: import QtQuick 2.5 import QtQuick.Controls 1.4 ...

Как подключить QML-файл в C++ по моде, а также получить ссылки на QML-элементы в C++
Читал в интернете, как подключать QML-файлы. Кто-то использует QQmlView, кто-то...

15
Заблокирован
30.05.2018, 21:26 2
1. Для начала, что это вообще за бред? Что значит "у меня есть класс, состоящий из структур", класс - есть класс, у него есть поля (данные/переменные), которые, к слову, могут быть у типа твоей структуры...
Или ты имеешь ввиду, что у тебя есть базовый класс, от которого наследуется куча других (структура != класс) ?

2. Какая разница, как он по сети прилетает, прилетели какие-то данные - обновил их в объекте своего персонажа.
3. Если ты хочешь использовать объект какого-то класса в QML, он должен быть унаследован от QObject-а, хотя есть и другой мини варианта без наследования от QOjbect-а с написанием макроса Q_GADGET в объявление класса (вместо Q_OBJECT), но там есть ограничения, вроде сигналов и слотов нет..

Какова цель? Для чего тебе QML? Почему не хочешь наследоваться от QObject-а, жалко 16-и байт для единственного объекта твоего персонажа или что?
0
487 / 365 / 93
Регистрация: 10.03.2011
Сообщений: 1,513
Записей в блоге: 5
30.05.2018, 21:43  [ТС] 3
1) Композиция
Не тыкай тут меня носом, как маленького. Я понял, что я написал. Ты понял, что я написал. Все, кто может быть полезен, поняли, что я написал.

2) Большая. Например, желателен нативный способ узнать валидность структуры - через сравнение с nil, что не делается в лоб. А хочется.

3) Окей, что с контейнерами? Если бы всё упиралось только в Q_PROPERTY, вопроса бы не было.

Добавлено через 4 минуты
Для чего мне QML? Для всего. Какая, к чёрту, разница?

От QObject не хочу наследоваться по причине пункта 2 из минусов. Переход со стека на динамику будет очень болезненным. Примерно на 45000 ошибок компиляции разной степени сложности. В основном, в недрах qhash.h и qvector.h Или ты не в курсе, что operator=, как и копирующий конструктор, у QObject выпилен?
0
Заблокирован
30.05.2018, 22:19 4
Цитата Сообщение от icpu Посмотреть сообщение
Окей, что с контейнерами? Если бы всё упиралось только в Q_PROPERTY, вопроса бы не было.
что с контейнерами? По дефолту QML распознаёт только QVariantMap и QVariantList.
короче, у тебя есть уже готовый проект какой-то игры, в котором все классы не унаследованы от QObject и ты хочешь рендерить её графику в QML, для этого тебе нужны puppet-ы/"зеркала" объектов твоих C++ классов в QML?

Добавлено через 3 минуты
Цитата Сообщение от icpu Посмотреть сообщение
- Динамической памяти не используется. Всё создаётся на стеке.
это кстати эпик фейл любого проекта
0
487 / 365 / 93
Регистрация: 10.03.2011
Сообщений: 1,513
Записей в блоге: 5
30.05.2018, 22:43  [ТС] 5
UAIS, про контейнеры знаю.
Про конечные цели не в курсе: может быть, будут рисовать, может быть - скриптовать, а может - выбросят правку в дохлые форки. Есть задача: пробросить данные класса до QML. Остальное меня пока не особо волнует.

Кстати, не плохая идея, заменить контейнеры на свои, которые будут иметь простые проперти int size и T* item. Так можно делать простой обход по индексу\ключу\кастовать в QVariantList. Интересно, а получится ли сделать каст в nil в QML?

Добавлено через 10 минут
Цитата Сообщение от UAIS Посмотреть сообщение
это кстати эпик фейл любого проекта
Эпик фейл любого проекта - застрять на технологии, которую уже 10 лет не обновляют. Не вижу никаких ОСОБЫХ недостатков - главный объект всё равно создаётся на куче, сегментация памяти структуры на порядок меньше, как и сложность контроля доступа к данным. По крайней мере, не упадёшь в сегфолт, если что-то пошло не так.
0
Заблокирован
30.05.2018, 23:45 6
Цитата Сообщение от icpu Посмотреть сообщение
Про конечные цели не в курсе: может быть, будут рисовать
Рисовать много на QML не получиться, уж очень он тормозной, особенно инстанциатор у него тормозной, то есть что бы создать какую-то тысячу объектов в QML - будешь ждать хз сколько... QML подходить только для GUI, саму игру, ну там 3D графику или какую-то 2D карту игры конечно же нужно рисовать на OpenGL.
Лично я обычно делал GUI на QML, затем делал свой класс рендера, наследника от QQuickFramebufferObject и в нём уже рисовал что нужно. Наследника этого класса можно прямо в QML создавать, т.к. он наследуется от QQuickItem.
Вот глянь мой старый ролик (снимался на дохлой видео карте), там вначале меню (ну и фон и пр) - оверлеится над 3Д, то есть на фоне QQuickFramebufferObject, а над ним - меню:

Я тебе это к тому, что лучше бы ты сразу озвучил, чего тебе нужно от QML, а я бы тебе сказал, что можно сделать, а что нельзя.

Цитата Сообщение от icpu Посмотреть сообщение
Интересно, а получится ли сделать каст в nil в QML?
получится, ты ж всю не декларативную бизнес логику в QML пишешь на javascript, там и скастишь что нужно.

Цитата Сообщение от icpu Посмотреть сообщение
Кстати, не плохая идея, заменить контейнеры на свои, которые будут иметь простые проперти int size и T* item.
я так и не понял, к чему весь этот геморрой? Типа, у тебя есть QVector<int> и ты не хочешь его трогать, но хочешь получить к нему доступ в QML? Я уже не помню точно, но вроде в QML можно пробрасывать простой QVector, только ты его не можешь присвоить в виде модели QML, но вроде как в дважа скрипте неявно с ним работать сможешь, почитай тут: http://doc.qt.io/qt-5/qtqml-cp... -data.html
В общем, чем тебе не нравятся твои контейнеры и зачем ты на них обёртку делаешь? В QML хочешь пробросить?

Цитата Сообщение от icpu Посмотреть сообщение
По крайней мере, не упадёшь в сегфолт, если что-то пошло не так.
сразу прослеживается в тебе любовь к гарбедж коллекторам, на шарпах что ли пересидел?

Цитата Сообщение от icpu Посмотреть сообщение
Не вижу никаких ОСОБЫХ недостатков
главные недостаток - отсутствие гибкости при написание софта, т.к. с указателями работать намного проще
0
487 / 365 / 93
Регистрация: 10.03.2011
Сообщений: 1,513
Записей в блоге: 5
31.05.2018, 05:37  [ТС] 7
Цитата Сообщение от UAIS Посмотреть сообщение
В QML хочешь пробросить?
Цитата Сообщение от icpu Посмотреть сообщение
Цель минимум - получить доступ из QML на чтение ко всем полям, включая контейнеры.


Цитата Сообщение от UAIS Посмотреть сообщение
Типа, у тебя есть QVector<int>
Типа, у меня есть TopologyObjects<Placeholder>, который тоже контейнер. Насколько я знаю, в QML даже QVector<long long> не поддерживается.
Только кастами в int, что для меня не приемлемо. Вот я и хочу найти способ лучше, чем QVariantList.

Не по теме:

Цитата Сообщение от UAIS Посмотреть сообщение
сразу прослеживается в тебе любовь к гарбедж коллекторам, на шарпах что ли пересидел?
Давай обойдёмся без телемедицины. Я и так с трудом сдерживаю свой острый язык.

0
Заблокирован
31.05.2018, 09:06 8
Цитата Сообщение от icpu Посмотреть сообщение
Я и так с трудом сдерживаю свой острый язык
ты его не сдерживаешь и мне тебе помогать как-то противно маленько
Цитата Сообщение от icpu Посмотреть сообщение
в QML даже QVector<long long> не поддерживается.
QML не предназначен для математических вычислений, он используется для быстрого прототипирования UI. Так же, основные объекты своего софта можешь объявлять в QML и соединять их как требуется.
Я у тебя в третий и последний раз спрашиваю, для чего ты собрался использовать QML? Что конкретно ты собрался делать в QML со своими C++ классами? Для чего тебе в QML передавать QVector<long long>? Ответа не поселедует - иди лесом и сам разбирайся, надоело гадать

Добавлено через 32 минуты

Не по теме:

P.S.: и вообще, я не сторонник общаться в хамской манере, заряда свежести словесным поносом с геймдева и так хватает на весь день :rofl:

0
487 / 365 / 93
Регистрация: 10.03.2011
Сообщений: 1,513
Записей в блоге: 5
31.05.2018, 09:07  [ТС] 9
Артподготовка

Не по теме:

UAIS, спасибо, что рассказал, что QML слишком медленный для 3D. Это открытие года! Большое спасибо! Тебя об этом просили? Нет. Вот и не надо отвечать на вопросы, которые тебе не задавали, человеку, у которого на 11 тем ~1000 ответов в подфоруме Qt. Наверное, такой человек что-то знает о Qt и QML.

Не надо мне рассказывать, что QML медленный. Или что он JavaScript. Или что на нём принято рисовать на мобилках. Или что он транслируется в браузеры. Или что можно без него. Или что есть lua. Или что тебе там не приятно. Тебя не об этом спрашивали. Мой вопрос был конкретный - и касался он C++.

Мне глубоко поровну, как будут использовать написанный мною код. Если хотят, пусть хоть на обоях распечатывают и офис обклеивают. Мне нужно эффективно решить задачу. Моя задача: дать доступ к структурам из QML. Чем больше и нативнее - тем лучше. И я её решаю. Я знаю, что она решаема, мне просто нужны хинты. Если тебе нечего сказать полезного, лучше сдержи себя и промолчи. Спасибо.


Бомбёж окончен.

Цитата Сообщение от UAIS Посмотреть сообщение
Для чего тебе в QML передавать QVector<long long>?
UID? Не, не слышал.
0
Заблокирован
31.05.2018, 09:30 10
Цитата Сообщение от icpu Посмотреть сообщение
UID? Не, не слышал.
так а для чего он тебе в QML? Работай с ним в С++. Или ты хочешь их в какой-то таблице вывести или что? Если нужно чисто отобразить, переделывай в строку и отображай что вздумается

Добавлено через 13 минут
Цитата Сообщение от icpu Посмотреть сообщение
что QML слишком медленный для 3D
он не медленный в 3D, скорость 3D зависит от твоей видеокарты и грамотности твоих шейдеров, для 3D в QML достаточно добавить один Item, в котором и будет всё отображаться, рисовать конечно же ты будешь через С++. В QML медленный Instantiator и Repeater, которые динамический создают объекты QML, а они все динамический создаются на старте из текста, то есть втупую парситься код QML каждого элемента при создание, хотя конечно есть и QML Compiler, но это уже отдельная тема. Я к чему тебе сказал всё это, ты ж не говоришь о сути проекта, по этому, я предположил, что ты в каком-то Item-е QML будешь создавать тысячи дочерних Item-ов для отображения карты своей чуда ролевой игры, так вот такой трюк не удастся.

Цитата Сообщение от icpu Посмотреть сообщение
у которого на 11 тем ~1000 ответов в подфоруме Qt
ой ой ой...как круто, да если б меня тут не банили уже в 100500-й раз, у меня б тут форумная репутация была б в сто раз круче Забей, мне на неё всегда было наплевать.

Цитата Сообщение от icpu Посмотреть сообщение
Или что он транслируется в браузеры
мечтай, есть сетевой стример экрана Qt, который позволяет одному юзеру подключиться к твоему удалённому софту на Qt и юзать его экран, но транслятора QML - HTML нет.

Цитата Сообщение от icpu Посмотреть сообщение
Моя задача: дать доступ к структурам из QML
вы там сами по себе в команде что ли? Ну раз так, делай тупо на каждую структуру враппер в виде класса с макросом Q_OBJECT, если нужны сигналы и слоты или от Q_GADGET (он более легковесный), если сигналы не нужны, но всякие Q_PROPERTY и Q_INVOKABLE для вызовы функций там всё равно есть. Для создания объектов классов твоих врапперов используй в QML Instantiator (http://doc.qt.io/Qt-5/qml-qtqml-instantiator.html), эта штука работает по принципе new, а для создания графических элементов QML, в которых захочешь что-то рисовать - используй Repeater

Добавлено через 6 минут
Цитата Сообщение от icpu Посмотреть сообщение
Кстати, не плохая идея, заменить контейнеры на свои, которые будут иметь простые проперти int size и T* item
В общем, если тебе наплевать на всё, делай тупо врапперы и не парься
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
struct Data
{
    QString one;
    QString two;
    QVector<long long> idVector;
};
 
class Wrapper : public QObject
{
    Q_OBJECT
public:
    Wrapper() {}
 
signals:
 
public slots:
    QString getId(long long id)
    {
        if(id < 0 || id > m_data.idVector.size() - 1)
            return QString();
        return QString::number(m_data.idVector[id]);
    }
 
private:
    Data m_data;
};
0
487 / 365 / 93
Регистрация: 10.03.2011
Сообщений: 1,513
Записей в блоге: 5
31.05.2018, 09:46  [ТС] 11

Не по теме:

Цитата Сообщение от UAIS Посмотреть сообщение
ой ой ой...как круто, да если б меня тут не банили уже в 100500-й раз, у меня б тут форумная репутация была б в сто раз круче
Digital_Cry, ты штоле?
Наверное, речь была не о фаллометрии, а о наличии базовых познаний у собеседника. Так что ему не нужны твои видосики про 3D. Но это не точно.



Добавлено через 7 минут
UAIS, а кто эти враперы будет создавать? Вот конкретно кто будет выделять память? Я? Ручками? Про то и речь, что нужна автоматика для минимального насилия над существующим кодом. В ваших предложениях её не прослеживается - либо вам придётся написать более полный пример, чтобы он своей массой пробил дуб моего лба.
0
Заблокирован
31.05.2018, 09:46 12
Цитата Сообщение от icpu Посмотреть сообщение
Digital_Cry
у меня много имён на этом форуме, как я только не назывался... из особо задержавшихся перед баном вроде было newbie666, ну и Digital_Cry - тоже я
Так что спрашивай по QML что-то конкретное быстрее без лишней беллетристики, т.к. этот ник скоро тоже будет зачёркнут ))))
Я вообще я предпочитаю свой настоящий ник - ™•-=THE_MASTER=-•™.
0
icpu
31.05.2018, 09:51  [ТС]
  #13

Не по теме:

UAIS, никогда такого не было - и вот опять.

Цитата Сообщение от UAIS Посмотреть сообщение
заряд свежести словесным поносом с геймдева

0
Заблокирован
31.05.2018, 09:59 14
Цитата Сообщение от icpu Посмотреть сообщение
В ваших
я уже из падонка превратился в "вы" :-D
Цитата Сообщение от icpu Посмотреть сообщение
а кто эти враперы будет создавать? Вот конкретно кто будет выделять память? Я? Ручками? Про то и речь, что нужна автоматика для минимального насилия над существующим кодом.
Хмм....хмм....я кажется начинаю понимать твою читерскую задумку, ты хочешь пропарсить тонну чужого говнокода, что бы туда автоматический добавился код для доступа к этим структурам из QML? Брр...так или не так? Ну если так, то ты можешь накидать утилитку, которая будет создавать всё это барахло....

По поводу выделения памяти. Смотри, у тебя есть класс, унаследованный от QObject-а:
Кликните здесь для просмотра всего текста

C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#ifndef DEMO_H
#define DEMO_H
 
#include <QObject>
 
class Demo : public QObject
{
    Q_OBJECT
public:
    explicit Demo(QObject *parent = nullptr) {}
 
signals:
 
public slots:
};
 
#endif // DEMO_H

для того, что бы ты его мог объявлять в QML, тебе его нужно зарегать где-нибуть в man.cpp так:
Кликните здесь для просмотра всего текста

C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include "demo.h"
 
int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
 
    QGuiApplication app(argc, argv);
 
    qmlRegisterType<Demo>("GAME_STUFF", 1, 0, "Demo"); ///!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
    QQmlApplicationEngine engine;
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
    if (engine.rootObjects().isEmpty())
        return -1;
 
    return app.exec();
}


потом в QML файле импортировать то, что зарегал:

Не по теме:


C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import QtQuick 2.9
import QtQuick.Controls 2.2
import GAME_STUFF 1.0 ///////!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
ApplicationWindow
{
    visible: true
    width: 640
    height: 480
    title: qsTr("Tabs")
 
    Demo  ///Декларативное объявление твоего класса
    {
 
    }
}



и когда ты потом в коде QML напишешь Demo{}, как в коде выше, это будет означать, что объект этого класса будет создан автоматический при старте файла QML и будет удалён так же автоматический, т.к. в QML есть гарбедж коллектор, тебе об этом заботиться не нужно, нужно заботиться только об корректой инициализации и освобождения ресурсов внутри класса, но если у тебя в этом классе всё будет объявлено статический (как ты выражаешься - на стеке, а это не так), тогда вообще тебя ничего не колышит, все твои структуры так же автоматом удаляться.
0
487 / 365 / 93
Регистрация: 10.03.2011
Сообщений: 1,513
Записей в блоге: 5
31.05.2018, 10:38  [ТС] 15
Повтори для template <class T> class Demo : public QObject{ /*...*/};

Добавлено через 1 минуту
Ну или хотя бы для class MyDemo : public QObject { /*...*/ QVector<Demo> m_myDemo; /*...*/ };

Добавлено через 2 минуты
В том-то и дело, что задача не тривиальная.

Цитата Сообщение от UAIS Посмотреть сообщение
По поводу выделения памяти.
Которая выделяется из C++ кода. Напомню, твоя идея.
0
Заблокирован
31.05.2018, 11:17 16
Цитата Сообщение от icpu Посмотреть сообщение
template <class T>
для шаблонов используй QVariant и тупо возвращай его в qml, типа QVariant getData(int id), а что с ним будут делать в QML - сам говорил, уже не твоя забота
0
31.05.2018, 11:17
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
31.05.2018, 11:17
Помогаю со студенческими работами здесь

qml - что из себя представляет qml
Решил написать игру на Qt,выбор остановился на танчиках.Посмотрел примеры и понял что все игры ,что...

QML вызов другого qml
Всем привет. Название темы немного неверное. Вообщем проблема такая. Делаю игру на qml, и есть...

Ошибка при связывании БД
Не получается связать делпфи с БД Access 2003 в ConnectionString прописал все что нужно, пароль на...

AV при связывании IBQ и IBDb
Доброе утро! Столкнулся с проблемой связывания IBQuery и IBDatabase при динамической работе....


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
16
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru