友達を作る方法C ++とQML

画像

彼らは私にテストタスクを送った。 C ++とQMLを使用してQtでチェスを記述する必要があります。 QMLは以前は勉強せず、聞いて読んだだけだったので、C ++とQtライブラリのみを使用して書くことにしました。 QMLでグ​​ラフィックパーツを作成、送信、返送、および書き換えを依頼しました。 何もする必要はありません。私は座ってこの奇跡を研究し、グラフィック部分を書き直しました。 今、私は私の経験を共有したいと思います。



チェスを書くプロセス全体を説明するのではなく、QMLを理解するプロセスだけを説明します。 この記事は、QMLの初心者に役立つと思います。



始めましょう

アプリケーションウィンドウは2つの部分に分かれています。左のボードには図があります。 移動の適切なログ(割り当てに応じて必要)およびコントロールボタン(新しいゲーム、終了、保存など)

QMLでは、チェス盤とその上のピースを再作成する必要があります。 すべての数学の動きはC ++で書かれています。



QMLとウィジェットを使用するため、 QT + = qml quick declarativeを含めます。 宣言モジュールはQML 2.0で動作しないため、QML 1.1で動作します。 Declarativeを使用するのは、QWidgetと互換性があるためです。 QMLを操作するための他のすべてのコンポーネントはそうではありません。



QDeclarativeViewを準備し、このクラスを再定義します。

Decl.hファイル

#ifndef DECL_H #define DECL_H #include <QtWidgets> #include <QtDeclarative> class MyDecl : public QDeclarativeView { Q_OBJECT protected: virtual void mouseReleaseEvent(QMouseEvent *me); public: MyDecl(QWidget *parent = 0); ~MyDecl(); signals: void declMouseRelease(int x, int y); }; #endif // DECL_H
      
      





Decl.cppファイル

 #include "decl.h" MyDecl::MyDecl(QWidget *parent) : QDeclarativeView(parent) { } MyDecl::~MyDecl() { } void MyDecl::mouseReleaseEvent(QMouseEvent *me) { emit declMouseRelease(me->x(), me->y()); }
      
      





これはなぜですか? 実際には、数字の制御はマウスで実行されます。 QMLからシグナルを取得するのは難しいため、このウィジェットからハンドラーにシグナルを送信します。



次に、プログラムのメインクラスにオブジェクトを作成します。

 MyDecl *decl;
      
      





将来のQMLファイルをそれに接続し、変数を設定して、ウィンドウに表示します。 これはコンストラクタで行います:

  decl = new QDeclarativeView; decl->engine()->rootContext()->setContextProperty("w1x", 0); decl->engine()->rootContext()->setContextProperty("w1y", 0); decl->engine()->rootContext()->setContextProperty("w1a", 0); decl->engine()->rootContext()->setContextProperty("w1c", 0); decl->engine()->rootContext()->setContextProperty("w1t", "texture.png"); decl->setSource(QUrl(QStringLiteral("qrc:/Images/main.qml"))); connect(decl, SIGNAL(declMouseRelease(int,int)), SLOT(getBoardMouse(int,int))); QHBoxLayout *mainWindow = new QHBoxLayout; QVBoxLayout *boardLayout = new QVBoxLayout; boardLayout->addWidget(decl,0, Qt::AlignTop | Qt::AlignLeft); mainWindow->addLayout(boardLayout, 4);
      
      





マウスを移動する計算を行わないように、QMLパーツが描画されるウィジェットを左上に配置します。 ボードの座標(0; 0)は、ウィジェットの座標(0; 0)に対応します。

変数w1xw1yw1cw1tw1aが必要な理由を以下に説明します。



main.qmlを作成してプロジェクトに接続します

 import QtQuick 1.1 Rectangle { width: 480 height: 480 Image { x: 0 y: 0 source: "Textures/board.png" } }
      
      





これまでのところ、チェス盤のみをロードしています

画像



次に、その上に数字を配置する必要があります。

 import QtQuick 1.1 Rectangle { width: 480 height: 480 Image { x: 0 y: 0 source: "Textures/board.png" Rectangle { x: w1x y: w1y width: 56 height: 56 color: w1c ? "#8000ff80" : "#00000000" Image { x: 0 y: 0 source: w1t visible: w1a } } } }
      
      





ここで何が書かれているか少し理解できます。

Imageの内側に、56x56の四角形を配置しました(これは、この実装では、ボード上の1つの正方形のサイズとまったく同じです)。 座標はいくつかの変数w1xおよびw1yに依存します。 座標は、親オブジェクト、この場合は画像(ボード)に相対的です。 セル内にImageオブジェクトを作成します-これはチェスの駒になります。 座標(0; 0)を設定すると、彼女は親のRectangleと共に移動します。 図のテクスチャは、変数w1tに示されます。 変数w1cは 、この図形が選択されているかどうかを判断するために必要です。選択されている場合、長方形は明るい緑色で塗りつぶされます。 彼らはフィギュアを殺すことができ、それを描く必要はありません。w1aがこれを担当します。



変数w1xw1yw1cw1tw1aは、C ++から設定/変更されます。

  decl->engine()->rootContext()->setContextProperty("w1x", piece.x); decl->engine()->rootContext()->setContextProperty("w1y", piece.y); decl->engine()->rootContext()->setContextProperty("w1c", piece.choice); decl->engine()->rootContext()->setContextProperty("w1a", piece.active); decl->engine()->rootContext()->setContextProperty("w1t", piece.source);
      
      





setContextPropertyでは、最初のパラメーターはQMLのパラメーター名であり、 QStringを使用して動的に設定できます。 2番目は値です。 そして、これらの値に応じて、QMLの値が変わります。



このプロセスは最初の図で説明されており、そのうちの32しかありません。 したがって、わずかに異なる解決策があります。



まず、グラフィック部分をQMLに変更します。 新しいオブジェクトを作成します。

ファイルPieceSprite.qml

 iimport QtQuick 1.1 Rectangle { property string texture: "" property bool active: true width: 56 height: 56 Image { x: 0 y: 0 source: parent.texture visible: parent.active } Behavior on x { NumberAnimation { duration: 500 easing.type: Easing.InOutQuad } } Behavior on y { NumberAnimation { duration: 500 easing.type: Easing.InOutQuad } } }
      
      





テクスチャアクティブなパラメーターが追加されました。 画像(図)の場合、 x座標とy座標の変化を追跡して、図形がスムーズに動くようにします(動きのアニメーションを追加します)。



main.qmlに新しいオブジェクトを追加して変更し、 JavaScriptを使用してすべての形状を作成します

 import QtQuick 1.1 Rectangle { id: appWindow width: 480 height: 480 Image { x: 0 y: 0 source: "Images/Textures/board.png" Component.onCompleted: { var component = Qt.createComponent("PieceSprite.qml"); var compName; var sprite; for (var i = 1; i <= 16; i++) { for (var c = 0; c < 2; c++) { if (c == 1) { compName = "wp" + i; } else { compName = "bp" + i; } sprite = component.createObject(appWindow); if (sprite == null) { // Error Handling console.log("Error creating object"); } else { sprite.x = 0; sprite.y = 0; sprite.active = false; sprite.objectName = compName; } } } } } }
      
      





オブジェクトの名前を設定します。白い部分にはwp 、黒い部分にはbp 、さらに1〜16のシリアル番号を設定します。これらの名前でピースを参照します。



C ++では、コンストラクターで変数の定義を削除します。

  decl = new QDeclarativeView; decl->setSource(QUrl(QStringLiteral("qrc:/Images/main.qml"))); connect(decl, SIGNAL(declMouseRelease(int,int)), SLOT(getBoardMouse(int,int))); QHBoxLayout *mainWindow = new QHBoxLayout; QVBoxLayout *boardLayout = new QVBoxLayout; boardLayout->addWidget(decl,0, Qt::AlignTop | Qt::AlignLeft); mainWindow->addLayout(boardLayout, 4);
      
      





QMLのオブジェクトのパラメーターを変更するには、関数を作成します。

 void Chess::setQmlPieceParametr(const piece &p, bool setTexture) { char pColor = p.white ? 'w' : 'b'; //    / int x = offset_x + (p.cell.x() * piece_size); //     int y = offset_y + BOARD_SIZE - (p.cell.y() * piece_size); //  Y   QString compColor = p.choise ? "#8000ff80" : "#00000000"; //      ,   QString compName = QString("%1p%2").arg(pColor).arg(p.pId); //        QObject *pieceSprite = decl->rootObject()->findChild<QObject*>(compName); //      QML if (pieceSprite) { //   ,    pieceSprite->setProperty("x", x); pieceSprite->setProperty("y", y); pieceSprite->setProperty("active", p.active); pieceSprite->setProperty("color", compColor); if (setTexture) { //                pieceSprite->setProperty("texture", QString("Images/Textures/%1").arg(pColor) + p.texture); } } }
      
      





この関数を使用すると、1つの形状のパラメーターを設定できます。 ボード上のセルは端から始まらないが、高さは下から考慮されるため、座標を再計算する必要があります。

形状パラメーターはピース構造に保存されます。

 struct piece { QPoint cell; int type; bool first_step; QString texture; bool white; bool choise; bool active; int pId; };
      
      





実際、それがすべてです。 GoogleDoxのプロジェクトにリンクします。

これを読んでくれてありがとう。



PS:たまたまDeclarativeを使わなければならなかった。 これは良くないので、アプリケーションで使用することはお勧めしません。



All Articles