12,964
回編集
編集の要約なし |
|||
185行目: | 185行目: | ||
<br><br> | <br><br> | ||
== シグナルとスロット == | |||
以下の例では、QML側のボタン押下時にC++側へシグナルを出力してC++側のスロットで受信した後、C++側からQML側へシグナルを送出している。<br> | |||
<br> | |||
==== C++側でコネクトする ==== | |||
<u>C++側からのシグナルにおいて、引数を<code>QVariant</code>にする必要がある。</u><br> | |||
これを指定しない場合、QML側のスロットが認識されない。<br> | |||
<syntaxhighlight lang="qml"> | |||
// main.qmlファイル | |||
import QtQuick 2.5 | |||
import QtQuick.Window 2.2 | |||
import QtQuick.Controls 2.0 | |||
Window { | |||
signal qmlSignal(string msg); | |||
function qmlSlot(text) | |||
{ | |||
console.log("qmlSlot is called with the text: " + text) | |||
textField.text = text; | |||
} | |||
visible: true | |||
width: 640 | |||
height: 480 | |||
title: qsTr("Hello World") | |||
Text { | |||
id:textField | |||
text: qsTr("Hello World") | |||
anchors.centerIn: parent | |||
} | |||
Button { | |||
id:aButton | |||
text:"Emit Signal!" | |||
anchors.centerIn: parent | |||
anchors.verticalCenterOffset: 30 | |||
onClicked: qmlSignal("Hello from QML") | |||
} | |||
} | |||
</syntaxhighlight> | |||
<br> | |||
<syntaxhighlight lang="c++"> | |||
// main.cppファイル | |||
#include <QGuiApplication> | |||
#include <QQmlApplicationEngine> | |||
#include <QQmlContext> | |||
#include "CSignalSlot.h" | |||
int main(int argc, char *argv[]) | |||
{ | |||
QGuiApplication app(argc, argv); | |||
QQmlApplicationEngine engine; | |||
engine.load(QUrl(QStringLiteral("qrc:/main.qml"))); | |||
CSignalSlot SignalSlot; | |||
QObject *root = engine.rootObjects().first(); | |||
// Connect QML Signal to C++ Slot | |||
QObject::connect(root, SIGNAL(qmlSignal(QString)), &SignalSlot, SLOT(cppSlot(QString))); | |||
// Connect C++ Signal to QML Slot | |||
QObject::connect(&SignalSlot, SIGNAL(cppSignal(QVariant)), root, SLOT(qmlSlot(QVariant))); | |||
return app.exec(); | |||
} | |||
</syntaxhighlight> | |||
<br> | |||
<syntaxhighlight lang="c++"> | |||
// CSignalSlot.hファイル | |||
#ifndef CSIGNALSLOT_H | |||
#define CSIGNALSLOT_H | |||
#include <QObject> | |||
#include <QVariant> | |||
#include <QDebug> | |||
class CSignalSlot : public QObject | |||
{ | |||
Q_OBJECT | |||
public: | |||
explicit CSignalSlot(QObject *parent = 0) : QObject(parent) | |||
{ | |||
} | |||
signals: | |||
void cppSignal(QVariant text); | |||
public slots: | |||
void cppSlot(QString msg) | |||
{ | |||
qDebug() << "cppSlot is called with the message: " << msg; | |||
emit cppSignal("Hello from C++"); | |||
} | |||
}; | |||
#endif // CSIGNALSLOT_H | |||
</syntaxhighlight> | |||
<br> | |||
==== QML側でコネクトする ==== | |||
C++側からシグナル(cppSignalメソッド)を送出する時の動作をonCppSignalと記述する。<br> | |||
<u>これは、C++側はLower Camelで記述、QML側は"on" + Upper Camelで記述する必要がある。</u><br> | |||
<br> | |||
main.cppにおいて、ルートオブジェクト(<code>rootContext</code>クラス)のコンテキスト(<code>setContextProperty</code>メソッド)を設定する前にmain.qmlを読み込むと、<br> | |||
以下のエラーが出力されるため注意すること。<br> | |||
QML Connections: Cannot assign to non-existent property "OnCppSignal" | |||
ReferenceError: cppSignalSlot is not defined | |||
<br> | |||
<syntaxhighlight lang="qml"> | |||
// main.qmlファイル | |||
import QtQuick 2.5 | |||
import QtQuick.Window 2.2 | |||
import QtQuick.Controls 2.0 | |||
Window { | |||
visible: true | |||
width: 640 | |||
height: 480 | |||
title: qsTr("Hello World") | |||
Text { | |||
id: textField | |||
text: qsTr("Hello World") | |||
anchors.centerIn: parent | |||
} | |||
Button { | |||
text:"Emit Signal!" | |||
anchors.centerIn: parent | |||
anchors.verticalCenterOffset: 30 | |||
onClicked: cSignalSlot.cppSlot("Hello from QML") | |||
} | |||
Connections { | |||
target:cSignalSlot | |||
onCppSignal: { | |||
console.log("received cppSignal:" + text) | |||
textField.text = text; | |||
} | |||
} | |||
} | |||
</syntaxhighlight> | |||
<br> | |||
<syntaxhighlight lang="c++"> | |||
// main.cppファイル | |||
#include <QGuiApplication> | |||
#include <QQmlApplicationEngine> | |||
#include <QQmlContext> | |||
#include "CSignalSlot.h" | |||
int main(int argc, char *argv[]) | |||
{ | |||
QGuiApplication app(argc, argv); | |||
QQmlApplicationEngine engine; | |||
CSignalSlot SignalSlot; | |||
// Put this before lading qml file! | |||
engine.rootContext()->setContextProperty("CSignalSlot", &SignalSlot); | |||
engine.load(QUrl(QStringLiteral("qrc:/main.qml"))); | |||
return app.exec(); | |||
} | |||
</syntaxhighlight> | |||
<br> | |||
<syntaxhighlight lang="c++"> | |||
// CSignalSlot.hファイル | |||
#ifndef CSIGNALSLOT_H | |||
#define CSIGNALSLOT_H | |||
#include <QObject> | |||
#include <QDebug> | |||
class CSignalSlot : public QObject | |||
{ | |||
Q_OBJECT | |||
public: | |||
explicit CSignalSlot(QObject *parent = 0) : QObject(parent) | |||
{ | |||
} | |||
signals: | |||
void cppSignal(QString text); | |||
public slots: | |||
void cppSlot(QString text) | |||
{ | |||
qDebug() << "cppSlot is called with text: " + text; | |||
emit cppSignal(QString("Hello from C++")); | |||
} | |||
}; | |||
#endif // CSIGNALSLOT_H | |||
</syntaxhighlight> | |||
<br><br> | |||
__FORCETOC__ | __FORCETOC__ | ||
[[カテゴリ:Qt]] | [[カテゴリ:Qt]] |