Согласно документам , "Когда данные переносятся из C ++ в QML, право собственности на данные всегда остается за C ++. Исключением из этого правила является случай, когда QObject
возвращается из явногоВызов метода C ++: в этом случае механизм QML предполагает владение объектом, если явно не установлено, что владение объектом остается с C ++, вызывая QQmlEngine::setObjectOwnership()
с указанным QQmlEngine::CppOwnership
. "
Asпрограммист C ++, всякий раз, когда я вижу функцию, возвращающую необработанный указатель, я содрогаюсь.Зачем возвращать Foo*
, если вы можете вернуть std::unique_ptr<Foo>
или хотя бы std::shared_ptr<Foo>
или QSharedPointer<Foo>
?Кажется, что эта функциональность не встроена. Очевидно, что QML должен быть разрешен для std::unique_ptr<Foo>
.Взятие QSharedPointer<Foo>
действительно не поддерживается?Есть ли какой-то обходной путь?
Может быть, что-то вроде этого (вдохновлено http://doc.qt.io/qt-5/qtqml-cppintegration-data.html#value-types)?
template <typename T>
class QSharedNotNullPointerWrapper {
{
Q_GADGET
Q_PROPERTY(T& value READ value WRITE setValue)
public:
QSharedNotNullPointerWrapper(const QSharedPointer<T>& ptr)
: m_ptr(ptr) {
Q_ASSERT(m_ptr); // Not-null
}
operator QSharedPointer<T>&() { return m_ptr; }
const T& value() const { return *m_ptr; }
T& value() { return *m_ptr; }
void setValue(const T &val) { *m_ptr = val; }
private:
QSharedPointer<T> m_ptr;
};
#define DECLARE_SHARED_PINTER_METATYPE(NAME, T) \
using NAME = QSharedNotNullPointerWrapper<T>; \
Q_DECLARE_METATYPE(NAME)
Если что-то подобное сработает, тогда я мог бы сделать
DECLARE_SHARED_PINTER_METATYPE(MyFooPtr, Foo)
и затем получить функцию, возвращающую MyFooPtr
и безопасно передать ее в QML или C ++.