C ++应用程序中的QML,反之亦然

时间:2013-08-13 09:22:32

标签: c++ qt qml

考虑一个简单的GUI显示相当复杂的计算输出的情况。

现在我想用 QML 编写一个漂亮的自定义GUI 我还想在 QT C ++ 中编写我的后台应用程序。

我坐在QT文档前面并且不知道 如果我 1)应该写一个 QML应用程序并以某种方式将我的C ++类嵌入其中 (绝对可能)或者如果我 2)应该写一个 C ++应用程序 并以某种方式将QML GUI嵌入其中并从我的类中修改QML属性 (这也是可能的)

我已经使用QT Widgets为GUI编写了C ++中的所有内容。我只想将GUI移动到QML并保留C ++类,即使我愿意将接口重写为GUI。

可能的anser:

下面标记的解决方案建议保留C ++类并通过SIGNALS和SLOTS专门连接GUI。所以基本上我最终得到了一个main.cpp来实例化我的主工作类并显示如下的QML GUI:

QQuickView viewer;
viewer.setSource(QUrl("./qml/main.qml"));
viewer.show();

然后我添加了myClass并给我一个对象来进行连接:

MyClass myClass;
QQuickItem* item = viewer.rootObject();
QObject::connect(item, SIGNAL(buttonClicked()), &myClass, SLOT(mySlot()));
QObject::connect(&myClass, SIGNAL(mySignal(QVariant)), item, SLOT(updateGUI(QVariant)));

在C ++类中实现插槽和信号时,必须使用QVariant对象来传输数据。然后QML文件实现SIGNALS,例如用于单击按钮和SLOTS以接收要显示的数据。

这正是我所希望的。我的非GUI代码的唯一变化是通过SIGNALS和SLOTS进行所有交互。现在我甚至可以将两个GUI(QML / Widgets)用于我的应用程序。

2 个答案:

答案 0 :(得分:8)

只需在C ++中编写核心逻辑,将其与信号和插槽连接,您就可以将相同的组件与小部件一起使用,也可以与QML一起使用。

这不是火箭科学,C ++逻辑允许使用C ++和QML,JS逻辑 - 只有QML。 C ++和Qt API是更合理的解决方案,因为从JS中你实际上无法访问Qt API的那么多功能,只有少数方法被“移植”到QML世界中。但是所有高性能数据容器和执行性能本身都是用C ++编写的。

如果你只需要显示结果并且控制台不够好,我宁愿继续使用QtWidgets,因为添加声明性模块会大大减慢编译速度。小部件模块现在是独立的,所以你甚至用QtWidgets添加“额外”模块(在Qt4中它是QtGui的一部分)但它更轻。在使用小部件对核心逻辑进行原型设计之后,您可以实现一个QML接口,并将其连接到现有的信号/插槽/属性和使用它们的绑定。

不,你没有在C ++类中嵌入QML,反过来说,C ++是更低层的层,用于创建QML组件。至于实际的实例化,你可以双向进行 - 如果你向QML引擎注册一个基于QObject的类,你可以用QML实例化它。或者您可以在C ++中实例化该类,并且只在QML上下文中使用它 - 这并不重要。如果您需要单个对象,最好在main()函数中使用C ++实例化它,并使其在QML上下文中可用,如果它是您打算实例化的组件,则创建一个QML组件。

您可以使用QML中的JS对核心逻辑进行原型设计,然后将其移植到C ++中(如果您也需要)。这看起来像是两倍的努力,但是如果你让你的床铺正确,它实际上提高了生产率,因为原型设计在QML中要快得多,捕获错误更加安全和信息丰富,如果你做好API,移植JS代码到C ++通常是一个小麻烦 - 用具体类型替换一些var,用.替换一些->和类似的东西。

你真正希望在C ++中做的任何“精心计算”。每次计算完成后,您只需将其作为信号发出,并自动将结果显示在信号连接的任何插槽中,即小部件或QML中,或者甚至同时显示两者。

答案 1 :(得分:0)

这是基于意见的。没有“真正的”答案可能。对我来说,使用Qt插件编写QML和'扩展'qml更容易。那是因为我这样做了一个大项目。其他人可能有其他经历,可能因为这样而不同的方法。我们的“生活故事”都不能帮助你。