1

qmlを使用してQt/C++でボードゲームを作成しています。すべての重要なゲーム データは、1 つのクラスで表されます。私の意図は、qml シートがこの 1 つのオブジェクトにアクセスし、データに応じてゲーム ボードを描画することです。

C++ データ メンバーを QML に公開する最も簡単な方法は何ですか?

質問がされたことがわかったので、回答と Qt のドキュメントを見てきました。しかし、私は満足していません。私が見たのは、これを行う方法は、QML からアクセスしたいすべての変数から Q_PROPERTY を作成することのようです。これは退屈で不必要に思えます。言うまでもなく、コードが元の長さの 3 倍に伸び、読みにくくなります。また、ほとんどの場合、たとえば、データ メンバーへの書き込み関数は必要ありません。

そして、必要な状況だけのために Q_INVOKABLE ゲッターを書くことができるのに、なぜ Q_PROPERTY オーバーヘッドに悩まされるのでしょうか?

以下は、Qt Project のドキュメントを読んだときに私が望んでいた単純さの例です

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 内ではなく) という名前のラベルの下に置きます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 は通常の配列と非常によく似た反復処理を行います。これは役立つはずです - 2番目の次元を無視してください

お役に立てれば。

于 2013-05-22T02:21:42.260 に答える