2016-10-26 20 views
1

私はゲームを作成していますが、現在QMLに問題があります。私は自分のC++スレッドが何らかのQMLコンポーネント(例えばMouseArea)によって受け取られる決定をするのを待つようにする必要があります。より良い問題を示すために、私は私がやろうとしているものを表すいくつかの簡単なコードを書いている:QMLからユーザー入力を待つC++を作る方法

//main.cpp 
#include <QApplication> 
#include "someclass.h" 

int main(int argc, char *argv[]) 
{ 
    QApplication a(argc, argv); 
    SomeClass c; 

    return a.exec(); 
} 

//someclass.h 
#ifndef SOMECLASS_H 
#define SOMECLASS_H 

#include <QQuickView> 
#include <QQuickItem> 
#include <QObject> 

class SomeClass : public QObject 
{ 
    Q_OBJECT 
public: 
    SomeClass(); 

    void lock(); 

public slots: 
    void unlock(); 

private: 
    QQuickView view; 
    bool unlockSignalReceived; 
}; 

#endif // SOMECLASS_H 

//someclass.cpp 
#include "someclass.h" 

SomeClass::SomeClass() 
{ 
    view.setSource(QUrl("qrc:/QMLFile.qml")); 
    view.setGeometry(0,0,1000,1000); 
    view.show(); 
    unlockSignalReceived=1; 
    QObject::connect(view.rootObject(), SIGNAL(click()),this, SLOT(unlock())); 
    lock(); 
    QMetaObject::invokeMethod(view.rootObject(), "changeColor", Q_ARG(QVariant, "green")); 
} 

void SomeClass::lock() 
{ 
    unlockSignalReceived=0; 
    while (!unlockSignalReceived); 
} 

void SomeClass::unlock() 
{ 
    unlockSignalReceived=1; 
} 

//qmlfile.qml 
import QtQuick 2.5 

Item { 
    id: root 

    anchors.fill: parent 

    function changeColor(color) 
    { 
     rec.color = color; 
    } 

    signal click() 

    Rectangle{ 
     id: rec 

     anchors.fill: parent 

     color: "red" 
    } 
    MouseArea{ 
     id: mArea 

     anchors.fill: parent 

     onClicked: click() 
    } 
} 

を私はそれは、ユーザーがそれをクリックすると、赤い四角形を表示する必要があることだと思う、その色を変更します緑に。私が正しく覚えていれば、Qt GUIはC++ロジックスレッドとは別のスレッドで実行されるため、lock()の実行中にunlock()スロットを実行できるはずです。しかし、それが動作しない場合、おそらく私は完全に間違っています。さらに興味深いのは、view.setSource(QUrl)がlock()の前に呼び出されても、矩形は表示されません。誰かが説明することができます、なぜそれが動作しないとどのようにこの問題に対処する?

答えて

2

あなたはシングルスレッドアプリケーションであり、スレッドは決して終了しないループを実行します。

あなたはイベント駆動型システムにいることを覚えておいてください。 信号に反応してください。

Btwでは、QMLコードでC++の依存関係を作成することを避ける方がよいので、ルートオブジェクトを取得し、シグナルに接続して関数を呼び出すのではなく、C++オブジェクトを公開してQMLコードでC++論理。 を参照してくださいQQmlContext::setContextProperty(QString, QObject*)

+1

良いアドバイス:私たちは物事が非同期的に発生する世界に住んでおり、これはソフトウェアの仕組みにも反映されています。コードは、物事に反応し、それらを待たないでください。 –

関連する問題