在QML插件中注册一个C++抽象类,并从QML中引用它




我正在写一个Qt应用程序
我已经将我的应用程序分离为QML前端和C++插件后端
在我的C++插件中,我有一个会话抽象类,我想将其公开给QML,我也有一些该类的实现
我希望我的QML前端只知道Session类,而不关心它是哪种会话的细节。
我尝试了qmlRegister*的一些变体来向QML注册我的会话类型,但要么会话需要是具体的(如qmlRegisterType的情况(,要么它注册得很好,但我不能像property Session session中那样从QML引用会话类型,甚至不能从QML实例化会话
有人知道我该怎么做吗?

更新
不起作用的示例:
在main.cpp中:

char const* const uri = "com.nogzatalz.Downow";
qmlRegisterUncreatableType<downow::Session>(uri, 1, 0, "Session", "Abstract type");

In DowNow.qml:

import QtQuick 2.0
import com.nogzatalz.Downow 1.0
Item {
    property Session session
}

我通过qmlRegisterInterface实现了这一点。我的虚拟调用是InputDeviceConfigurator:

class InputDeviceConfigurator : public QObject
{
    Q_OBJECT
public:
    explicit InputDeviceConfigurator(QObject *parent = 0);
    Q_INVOKABLE virtual QString deviceId() = 0;
}

我注册如下:

qmlRegisterInterface<InputDeviceConfigurator>( "InputDeviceConfigurator" );

然后使用继承的类JoystickConfigurator:

class JoystickConfigurator : public InputDeviceConfigurator
{
public:
    JoystickConfigurator( JoystickDevice * device );
    // InputDeviceConfigurator interface
    virtual QString deviceId() override;
}

而且我可以使用它:

 Component.onCompleted: console.log( UserInputManagement.getConfigurator().deviceId() )

UserInputManagement只是一个单独的:

Q_INVOKABLE InputDeviceConfigurator  * getConfigurator();

据我所知,使用抽象类作为定义是不可能创建变量的。

您可以在qml代码中将会话变量声明为QtObject,您将失去qtcreator的自动完成功能
但是,所有使用Q_property宏声明的属性和所有Q_INVOKABLE函数在运行时仍然可用。

如果您想拥有几乎相同的语义,我建议您创建一个使用qmlRegisterSingletonType注册到QML的单例C++类,并让该类携带"session"变量。然后在Session抽象类上保留qmlRegisterUnreatableType,这样在qml代码中您就可以编写类似于的内容

MySingleton.session

并在qtcreator中保持qml的自动完成
作为奖励,如果您的用户可以在不重新启动应用程序的情况下多次登录/注销,您还可以创建一个信号"SessionChanged"。

最新更新