Qt在c ++中创建对象并向QML公开

时间:2016-09-08 19:24:25

标签: c++ qt qml

我试图开发一款游戏,但它不仅与游戏有关,而且与任何事物有关。 我的问题是:你如何在c ++上创建/删除/管理对象,它们在qml中出现/消失/改变?

我知道很多用户会告诉我阅读

http://doc.qt.io/qt-4.8/qtbinding.html

http://doc.qt.io/qt-5/qtqml-cppintegration-contextproperties.html

http://doc.qt.io/qt-5/qtqml-cppintegration-interactqmlfromcpp.html

http://doc.qt.io/qt-5/qtqml-cppintegration-exposecppattributes.html

依旧......

我已经阅读了所有这些内容。我知道如何以某种方式使用它,比如更改数字的例子,这是一个属性,它暴露给QML,因此它会自动更改,但这不是我的问题。

让我们举一些简单的代码,例如

class Unit {

int posX, posY;
int energy;

void move()...
void create()...
void kill()
}

然后我们将在main和所有必需的子块中实现c ++中的所有逻辑。

Game.cpp 
class Game {
QList<Unit> listUnits;

moveUnits() {
for (int i = 0; i < units.size(); i++){
Unit unit;
unit.move();
}

createNewUnit(){
Unit unit = new Unit();
listUnits.append(unit);
}
}

On the other side will have Unit.qml 

Item{
property int posX;
property int posY;
Animation on X {...}
....    
}

这基本上是处理与Unit相关的UI,但我再说一遍,所有的逻辑都将在c ++中再次完成。

在前面提到的例子中,我想,当我创建一个新单元时,它将直接出现在QML中。

怎么办?我真的很有信心可以做到,我确信很简单,我只是没有发现。我不需要代码,只是一个提示,或参考,或教程。

如果解决方案真的出现在我之前写的一封电子邮件中,我请你详细解释一下,因为我还没找到。

非常感谢!

1 个答案:

答案 0 :(得分:4)

以下是如何将C ++连接到QML

  • 使您的C ++类继承自QObject(意味着它还应该具有Q_OBJECT以上的public:
  • 在一些公共方法前添加Q_INVOKABLE宏,以便可以从QML调用它们。例如Q_INVOKABLE int doStuff(int myParam);

  • 在您的主文件中,注册该类,以便QML可以找到它:qmlRegisterType<Foo>("MyFoo", 1, 0, "Foo");

  • 在QML文件import MyFoo 1.0中导入C ++类(请注意它是1.0,因为在qmlRegisterType中,我传递了参数1和0)
  • 您现在可以将C ++类添加到QML文件中。 Foo { id: foo}并且可以在QML的其他位置调用您的方法,例如

    function qmlDoSomething(val){   var newInt = foo.doStuff(val) }

如果您想动态创建QML组件,可以这样做:

function addComponent(){
  var comp = Qt.createComponent("ComponentFile.qml")
  var sprite = comp.createObject(myParent) //myParent should be whatever you want to add the component to
}

如果您希望QML响应C ++消息,请向C ++添加信号

signals:
      void makeComponent(QString message);

然后在QML Widget中,您可以在调用此信号时设置函数

Foo{
id: foo
onMakeComponent: { 
   console.log(message); 
   addComponent()
 }
}

如果您不熟悉信号的工作方式,那就非常简单了。在C ++方法中,您只需使用关键字emit然后将其称为方法

void myFunc(){
   //Do some stuff
   emit(makeComponent(someString));
}

如果您希望新创建的QML元素将数据发送回C ++

  • 为您的组件提供标识符
  • 将组件信号连接到C ++类
  • 当您的组件发出信号时,请在C ++调用中包含其标识符
function addComponent(componentName){
   var comp = Qt.createComponent("ComponentFile.qml")
   var sprite = comp.createObject(myParent)
   sprite.name = componentName
   sprite.mySignal.connect(foo.modifyComponent)
}

//In ComponentFile.qml
signal mySignal(string val)

function sendSignal(){
   mySignal(name)
}

总之,我已经解释了如何:

  • 让Q ++在QML中调用函数
  • 如何从QML调用C ++函数
  • 如何在QML中动态创建新元素
  • 如何使这些新元素调用C ++函数

这应该是在QML和C ++之间传递数据所需的一切