I'm creating a game and currently I've encountered a problem with QML. I need to make my C++ thread wait for user to make a decision which will be received by some QML component (for example MouseArea). To demonstrate the problem better, I've written some simple code that represents what I'm trying to do:
//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()
}
}
I think that it should show a red rectangle that, when the user clicks it, changes its color to green. If I remember correctly Qt GUI is run in different thread than C++ logic thread, so I guess that it should be able to execute unlock() slot during lock() execution. But if it doesn't work, then probably I'm totally wrong. What is even more interesting, the rectangle doesn't even show, albeit view.setSource(QUrl) is invoked before lock(). Could someone explain, why it doesn't work and how to deal with this problem?