Проблема
Я делаю проект, используя Q_OBJECT и Q_PROPERTY для доступа к некоторым объектам из скриптов.У меня есть две проблемы:
- создание классов, использующих предварительные объявления с возможностью сценариев
- возвращение свойства в качестве указателя
Пояснения
1.Почему прямое объявление?
Класс B получает прямое объявление A, потому что A требует полный тип B в заголовке из-за шаблонов.В заголовке B необходим только неполный тип (A *), поэтому прямое объявление является действительным.
2.Зачем возвращать указатель?
Мы не можем вернуть копию, так как нам нужен доступ к реальному объекту в скрипте.Мы не можем вернуть ссылку, так как Qt не позволяет слотам возвращать ссылки - их тип будет игнорироваться, они будут возвращать только void *.
Код
Полный кодскачать на pastebin или в виде ZIP-архива или в виде ZIP-архива из доступен минимальный пример , для тестирования / воспроизведения: мне нужно было разделить файлы для пересылкидекларация и для МОС.Я добавил Makefile, чтобы проверить это.Сделайте deps: g ++, moc, Qt.
Важные части
class A; // forward declaration necessary, see explanation above
class B : public QObject {
Q_OBJECT
Q_PROPERTY(A a READ GetA) // <-- ERROR HERE
// ...
public slots:
A* GetA() {
return mA;
}
private:
A* mA;
// ...
}
Строка ошибки в скрипте:
print(bObj.GetA().GetName());
Ошибка компиляции
Эта ошибка исчезает, когда я закомментирую Q_PROPERTY выше.
tmp/B.moc.hpp:95:51: error: invalid use of incomplete type ‘struct A’
tmp/../B.hpp:10:7: error: forward declaration of ‘struct A’
Исключение скрипта
Когда я опускаю Q_PROPERTY и вызываю метод GetA () как слот из скрипта, я получаюследующее исключение:
Line 7: "TypeError: cannot call GetA(): unknown return type `A*'
(register the type with qScriptRegisterMetaType())"
При регистрации A * с помощью qRegisterMetaType<A*>("A*");
это изменяется на:
Line 7: "TypeError: Result of expression 'bObj.GetA().GetName'
[undefined] is not a function."
Это показывает, что GetA () не возвращает объект A или каким-то образом возвращаетуказатель, но скрипт не может разыменовать его.Затем GetA () фактически возвращает QVariant(A*)
, можно ли это как-то использовать?
Вопросы:
- Могу ли я как-то сделать Q_PROPERTY из неполного типа, или как мне избежатьпредварительное объявление?
- Могу ли я вернуть ссылку в слот (возможно, некоторые хитрости, например, класс, который оборачивает указатель и «переопределяет» скрипт
operator.
, если что-то подобное существует) или - Можно ли как-то разыменовать QVariant (A *) в A в QtScript?