1

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

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

现在我知道这个问题已经被问过了,我已经看到了答案和 Qt 文档。然而,我并不满意。我所看到的,这样做的方法似乎是将 Q_PROPERTY 从我想从 QML 访问的每个变量中取出。这在我看来是乏味和不必要的,更不用说它会将代码拉伸到原始长度的 3 倍,从而使阅读变得更糟。此外,例如,在大多数情况下,我不需要向数据成员写入函数。

当我可以只为我需要的情况编写 Q_INVOKABLE getter 时,为什么还要为 Q_PROPERTY 开销而烦恼呢?

这是我在阅读 Qt 项目文档时希望它是多么简单的一个示例:“这使得 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 似乎......太荒谬了。

也许我在某个地方遗漏了什么,在这种情况下,我谦虚地道歉。感谢您对此事的任何想法。

4

1 回答 1

0

为了:

Q_PROPERTY:当您查看引用的页面时,他们讨论了使用该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:(NOT within public- 请参阅此处了解如何编写信号))。根据您的示例,我猜您的 C++ 对象被称为Game.

Game {
    id: gameKeeper //or whatever you want to name it
    onUpdate: Image1.getImage() //replace onUpdate with your signal
}

Image {
    id: Image1

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

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

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

数组处理:在 C++ 方面,看起来最好的方法是通过 QList。幸运的是,QList 的迭代与普通数组非常相似。我发现了这个,这应该会有所帮助——只需忽略第二个维度。

希望这可以帮助。

于 2013-05-22T02:21:42.260 回答