「QMLの基礎 - QMLとC++のバインディング」の版間の差分

ナビゲーションに移動 検索に移動
編集の要約なし
編集の要約なし
 
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]]

案内メニュー