简体   繁体   中英

Qt create object in c++ and expose to QML

Im trying to develop a game, but is not only related to a game, but to anything. My question is: How do you create/delete/manage objects on c++ and they appear/disapear/change in qml?

I know that many users will tell me to read

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

and so on...

I have read all of them. I know how to use it that way somehow, like the example of changing a number, that is a property and its exposed to QML so it automatically changes, but that is not my question.

Let's put some simple code for example

class Unit {

int posX, posY;
int energy;

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

Then we will implement all the logic in c++ inside the main and all necessary subclases.

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 {...}
....    
}

That basically is to handle the UI related to the Unit, but I repeat, all the logic will be done in once again in c++.

In the example before mentioned, I want, when I create a new unit, this will appear directly inside QML.

How to do? Im really sure is possible to be done, and Im sure is quite simple, I just didnt found out. I dont need code, just a hint, or a reference, or tutorial.

In case the solution is really on one of the emails I wrote before, I ask you to explain it more detail, because I still didnt found out.

Thanks a lot!

Here is how to connect C++ to QML

  • Make your C++ class inherit from QObject (meaning it should also have the Q_OBJECT macro above public:
  • Add the Q_INVOKABLE macro in front of some of your public methods so they can be called from QML. eg Q_INVOKABLE int doStuff(int myParam);

  • In your main file, register the class so QML can find it: qmlRegisterType<Foo>("MyFoo", 1, 0, "Foo");

  • Import your C++ class in your QML file import MyFoo 1.0 (note that it is 1.0 because in qmlRegisterType, I passed the parameters 1 and 0)
  • You can now add your C++ class to the QML File. Foo { id: foo} and can call your methods from elsewhere in QML eg

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

If you want to Dynamically create QML components, you can do it like this:

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

If you want QML to respond to C++ messages, add a signal to C++

signals:
      void makeComponent(QString message);

then in the QML Widget, you can put a function for when this signal is called

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

If you're not familiar with how signals work, it's pretty simple. In a C++ method, you just use the keyword emit then call it like it a method

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

If you want your newly created QML Element to send data back to C++

  • Give your component an identifier
  • Connect your component signal to your C++ Class
  • When your component emits the signal, make it include its identifier in the call to 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)
}

In summary, I have explained how to:

  • Have C++ invoke functions in QML
  • How to call C++ functions from QML
  • How to create new elements dynamically in QML
  • How to make these new elements call C++ functions

This should be everything you need to pass your data between QML and C++

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM