首页 文章

从QML简单访问C对象数据

提问于
浏览
1

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

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

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

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

以下是我在Qt项目文档中阅读时希望的简单示例:"This enables C++ data and functions to be accessible directly from QML, often with little or no modification."

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

    为了:

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

    Setting the image source :如果你还记得,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";
                      }
            }
        }
    

    然而,函数赢得't run by itself: you'll必须将它与一个信号相关联,我将在你的C类中创建(将函数放在一个名为 signals: 的标签下(不在 public 内 - 参见here关于如何写信号)) . 根据你的例子,我猜你的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) .

    Array handling :在C方面,看起来最好的方法是通过QList . 幸运的是,QList迭代非常类似于普通数组 . 我找到this,这应该有帮助 - 只是忽略第二个维度 .

    希望这可以帮助 .

相关问题