从QML简单访问C ++对象数据

时间:2013-04-17 22:22:18

标签: c++ qml

我正在使用qml在Qt / C ++中制作棋盘游戏。所有重要的游戏数据都在一个类中表示。我的目的是让qml表访问这个对象并根据数据绘制游戏板。

将C ++数据成员公开给QML的最简单方法是什么?

现在我知道问题已被提出,我已经看到了答案和Qt文档。但是,我不满意。我所看到的,这样做的方法似乎是从我想从QML访问的每个变量中取出Q_PROPERTY。这对我来说是单调乏味且不必要的,更不用说它会将代码扩展到原始长度的3倍,这使得阅读显着变差。此外,在大多数情况下,我不需要对数据成员执行写入功能,例如。

为什么我只能在我需要的情况下编写Q_INVOKABLE getter时,为什么还要花费Q_PROPERTY开销呢?

以下是我在Qt Project文档中阅读时希望的简单示例:“这使得C ++数据和函数可以直接从QML访问,通常很少或根本没有修改。”

class game : public QObject
{
    Q_OBJECT
public:
    explicit game(QObject *parent = 0);
    colors NPC[3]; // colors being an enum declared elsewhere
    player players[4]; // player is a non-QObject class containing player stats
}
...
game gMain;
QDeclarativeContext *context = viewer.rootContext();
context->setContextProperty("Game",&gMain);

我理想世界的QML:

Image {
    id : Image1
    source: { if (Game.NPC[0] === 0) {
                  if (Game.players[1].LifeCount > 0) {
                      return "pics/FigG.png"
                  }
                  else {
                      return "pics/StoneG.png"
                  }
             }

现在我可以通过QML获得多少接近,我该如何解决? 我特别感兴趣的是处理简单的C ++样式数组和枚举(在游戏中有很多这样的数组) - 我是否需要编写辅助函数,例如int Game.GetNPCAt(int i)而不仅仅使用Game.NPC[i]

我意识到我不想这样做的方式是经过尝试和信任,并且有充分的理由......但是在我的情况下(小型单人项目)似乎使用大炮来杀死苍蝇(虽然qml中的GUI构建部分非常简单且使用起来非常愉快) - 还必须包含每个数据成员,包括像int这样最简单的成员......看起来非常过分。

也许我错过了某个地方,在这种情况下,我谦卑地道歉。感谢您对此事的任何想法。

1 个答案:

答案 0 :(得分:0)

按顺序:

Q_PROPERTY :当您查看page that you quoted时,他们会讨论使用Q_PROPERTY方法向QML公开属性。如果你不使用Q_PROPERTY,我的理解是你的变量不会被QMLViewer注册(或你有什么)。 Q_PROPERTY需要Q_INVOKABLE来获取/设置变量。但是,如果您不使用Q_PROPERTY,则您的类属性不会出现在QML中。

设置图像源:如果您记得,QML是CSS和JavaScript之间的伪造。如果您只是想根据Image元素之外的条件来改变图像的来源,您可以创建一个JavaScript函数来实现您所引用的内容:

Image {
    id: Image1

    function getImage()
    {
        if (Game.NPC[0] === 0)
        {

            if (Game.players[1].LifeCount > 0) {
                      Image1.source="pics/FigG.png";
                  }
                  else {
                      Image1.source="pics/StoneG.png";
                  }
        }
    }

但是,该函数不会自行运行:您必须将它与信号相关联,我将在C ++类中创建该信号(将该函数放在名为signals:的标签下(不在{ {1}} - 请参阅here了解如何写信号))。根据您的示例,我猜测您的C ++对象被称为public

Game

理论上,你应该能够用JavaScript以这种方式引用数组(我自己并不熟悉JS)。

数组处理:在C ++方面,看起来最好的方法是通过QList。幸运的是,QList迭代非常类似于普通数组。我找到了this,这应该有所帮助 - 只需忽略第二维。

希望这有帮助。