LINUX.ORG.RU

Не передаётся значение типа enum в сигнале. Что делать?

 , , ,


1

1

В моем проекте есть перечисление, для которого сделан отдельный класс:

DataQuality.h

#include <QObject>

class DataQuality
{
    Q_GADGET // Вместо QObject добавляется только рефлексия, которая исползуется в QML

public:

    enum class Value { // Нельзя использовать struct, так как с ним в QML все значения всегда будут undefined
        None=0,
        Normal=1,
        Imperfect=2
    };
    Q_ENUM(Value)
};

Этот класс регистрируется в QML-среде вот так:
qmlRegisterUncreatableType<DataQuality>("company.DataQuality", 1, 0, "DataQuality", "You cannot create an instance of the DataQuality.");

После чего в QML-коде можно прописать импорт:
import company.DataQuality 1.0

И значения типа DataQuality становятся доступными в QML:
console.log("DataQuality normal is: "+DataQuality.Value.Normal);

DataQuality normal is: 1

То есть, до этого момента все в порядке. Код в C++ и QML части практически становится единообразным, т. к. доступ к значениям enum выглядит так:
C++: DataQuality::Value::Normal
QML: DataQuality.Value.Normal

* * *

Проблема возникает в случае, если попробовать этот тип передавать в сигнале. Плюсовая часть:
signals:
    void setTransportAngle(float angle, DataQuality::Value quality);

...

emit setTransportAngle( 0.5, DataQuality::Value::Normal );

QML-часть:
        Connections {
            target: viewDataEmitter
            onSetTransportAngle: {
                courseIndicatorComponent.angle=angle;
                courseIndicatorComponent.quality=quality;
            }
        }

Компилится все без ошибок, но в момент исполнения QML-кода появляется ошибка:
IndicatorArea.qml:124: Error: Cannot assign [undefined] to double

То есть, не обрабатывается даже первый параметр сигнала. Но если вперед передвинуть quality, то ошибка будет аналогичной:
IndicatorArea.qml:124: Error: Cannot assign [undefined] to int

То есть, проблема тут не в конвертации в double или в int, а в том, что оба значения параметров сигнала undefined.

В связи с вышеозначенным вопрос: как в Qt/QML можно передавать через сигналы значения с нестандартным типом данных?

Кастую сюда EXL, Dendy, RazrFalcon, deep-purple.

★★★★★

Последнее исправление: Xintrea (всего исправлений: 4)

Пользуясь случаем, поинтересуюсь. Тоже поглядываю на QML, хочется попробовать что-нибудь на нём написать.

Но останавливает вот какой неизвестный момент: а как из Qt-кода передавать в QML-код всякие объекты с данными для последующего отображения в GUI? STL-контейнеры или структуры, например.

s3rjke
()
Ответ на: комментарий от s3rjke

Это всё об этом же — регистрируешь свои кучки нужным способом и они становятся доступными и/или для сигналов и/или для куемеля.

deep-purple ★★★★★
()
Ответ на: комментарий от deep-purple

Ага, в общем получилось так.

1. Помимо регистрации:

qmlRegisterUncreatableType<DataQuality>("company.DataQuality", ...

надо еще регистрировать тип:
qRegisterMetaType<DataQuality::Value>("DataQuality.Value");

Тогда данный тип начинает передаваться в сигнал/слотах, даже тех что в QML проброшены.

2. Что самое странное, теперь в C++ и в QML коде работает такое сокращенное обращение к значению:
C++: DataQuality::Normal
QML: DataQuality.Normal

То есть, без промежуточного пространства имен Value. Почему так происходит, понять не могу.

Xintrea ★★★★★
() автор топика
Ответ на: комментарий от Xintrea

3. Да забыл написать важную вещь. Чтобы короткий синтаксис работал, вот такой:

C++: DataQuality::Normal
QML: DataQuality.Normal

перечисление должно быть задано без ключевого слова class. То есть не так как в топике:
enum class Value {

а вот так:
enum Value {

Xintrea ★★★★★
() автор топика
Ответ на: комментарий от s3rjke

Но останавливает вот какой неизвестный момент: а как из Qt-кода передавать в QML-код всякие объекты с данными для последующего отображения в GUI? STL-контейнеры или структуры, например.

Регистрируешь свои STL-контейнеры или какую тебе нужно структуру по образу и подобию что написано здесь. И она будет пробрасываться.

Xintrea ★★★★★
() автор топика
Ответ на: комментарий от theNamelessOne

Наверно потому, что enum class (C++) создаёт пространство имён для своих значений, а enum (C) — не создаёт?

Видимо так. Тут вопрос больше в том, почему class срабатывает, а struct нет. По идее, class работать не должен, потому что все его члены по-умолчанию приватные, а struct работать должен, потому что у него все открыто. А конфигурация кода в ТС показывает, что ровно все наоборот.

Xintrea ★★★★★
() автор топика
Ответ на: комментарий от Stil

В чем отличие struct от class? Я имею в виду, что пишут про разницу struct от class, о которых пишут в книжках. Везде одно и то же: разницы нету, за исключением того, что все элементы класса по-умолчанию закрыты, а у struct - открыты. При этом внятно понять, что имеется в виду невозможно. То ли имеются в виду свойства и методы. То ли имеются в виду все содержание класса, включая значения перечислений. Вроде как сам тип перечислений - он торчит наружу, потому что это тип, на типы никаких ограничений видимости не может быть по структуре языка. А к чему относятся значения перечисления - нигде не написано. Вроде это часть типа, тогда ограничения видимости на использование DataQuality::Value::Normal быть не может в принципе. А тем не менее, с class у нас работает, а со struct не работает. Вот этому я и удивляюсь.

А тебе надо либо отвечать на вопрос, по делу, либо молча осознавать свое величие в понимании языка. Пока ты будешь рассказывать про книжки и ртфм, толку от тебя не будет никакого. Такими умниками как ты у нас весь интернет засран.

Xintrea ★★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.