2017-11-16 9 views
0

これは奇妙な設定のように思えるかもしれません。 QObjectから継承したC++オブジェクトは、簡単に「MasterGuiLogic」と呼ばれています。これは、 "MainEventBroker"と呼ばれる別のオブジェクトへのポインタで作成され、私のアプリケーションのすべてのイベントを処理すると推測されます。 MasterGuiLogicオブジェクトはqmlにコンテキストプロパティとして登録されているので、qmlのどこでもプロパティを使用できます。だから、main.cppには、次のようになります。Qt QmlはコンテキストプロパティのQObjectプロパティの信号に接続します

int main(int argc, char *argv[]) 
{ 
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); 
    QGuiApplication app(argc, argv); 

    MasterEventBroker *MainEventBroker = new MasterEventBroker(); 
    MasterGuiLogic *MainGuiLogic = new MasterGuiLogic(*MainEventBroker); 

    qmlRegisterUncreatableType<MasterGuiLogic>("GrblCom", 1, 0, "MasterGuiLogic", ""); 
    qmlRegisterUncreatableType<GuiLogic_SerialCom>("GrblCom", 1, 0, "GuiLogic_SerialCom", ""); 

    QQmlApplicationEngine engine; 
    QQmlContext* context = engine.rootContext(); 

    context->setContextProperty("MasterGuiLogic", &(*MainGuiLogic)); 

    engine.load(QUrl(QLatin1String("qrc:/QmlGui/main.qml"))); 
    if (engine.rootObjects().isEmpty()) 
     return -1; 

    return app.exec(); 
} 

MasterGuiLogicは、それがプロパティとパブリックスロットがMasterGuiLogicプロパティを介してQMLに到達することができますようにQ_PROPERTYとして設定されているSerialComと呼ばれる別のクラスのインスタンスを作成します。

MasterGuiLogic.h:

class MasterGuiLogic : public QObject 
{ 
    Q_OBJECT 
    Q_PROPERTY(GuiLogic_SerialCom* serialCom READ serialCom CONSTANT) 
public: 
    MasterEventBroker *eventBroker; 

    explicit MasterGuiLogic(MasterEventBroker &ev, QObject *parent = nullptr); 


    GuiLogic_SerialCom* serialCom() const { 
     return Gui_SerialCom; 
    } 

private: 

    GuiLogic_SerialCom *Gui_SerialCom; 

MasterGuiLogic.cpp:

MasterGuiLogic::MasterGuiLogic(MasterEventBroker &ev, QObject *parent) : QObject(parent) 
{ 
    this->eventBroker = &ev; 
    this->Gui_SerialCom = new GuiLogic_SerialCom(this); 
} 

SerialCom.h:

//Forward Declare our parent 
class MasterGuiLogic; 

class GuiLogic_SerialCom : public QObject 
{ 
    Q_OBJECT 
    Q_PROPERTY(QStringList portNames READ portNames NOTIFY portNamesChanged) 
    Q_PROPERTY(bool connectedToPort READ connectedToPort NOTIFY connectedToPortChanged) 
public: 

    MasterGuiLogic *parent; 
    explicit GuiLogic_SerialCom(MasterGuiLogic *parent = nullptr); 

    std::map<QString, QSerialPortInfo> portsMap; 


    QStringList portNames() { 
     return _portNames; 
    } 

    bool connectedToPort() { 
     return _connectedToPort; 
    } 

private: 

    QStringList _portNames; 
    bool _connectedToPort = false; 


signals: 

    void portNamesChanged(const QStringList &); 
    void connectedToPortChanged(const bool &); 

public slots: 

    void connectToPort(const QString portName); 
    void disconnectFromPort(const QString portName); 

}; 

SerialCom.cpp:

GuiLogic_SerialCom::GuiLogic_SerialCom(MasterGuiLogic *parent) : QObject(qobject_cast<QObject *>(parent)) 
{ 
    this->parent = parent; 


    QList<QSerialPortInfo> allPorts = QSerialPortInfo::availablePorts(); 

    for (int i = 0; i < allPorts.size(); ++i) { 
     this->_portNames.append(allPorts.at(i).portName()); 
     this->portsMap[allPorts.at(i).portName()] = allPorts.at(i); 
    } 

    emit portNamesChanged(_portNames); 

} 

void GuiLogic_SerialCom::connectToPort(const QString portName) { 
    //TODO: Connect To Port Logic Here; 

    //Set Connected 
    this->_connectedToPort = true; 
    emit connectedToPortChanged(this->_connectedToPort); 

    qDebug() << portName; 
} 

void GuiLogic_SerialCom::disconnectFromPort(const QString portName) { 
    //TODO: DisConnect To Port Logic Here; 

    //Set DisConnected 
    this->_connectedToPort = false; 
    emit connectedToPortChanged(this->_connectedToPort); 

    qDebug() << portName; 
} 

だからQMLから、それはこれらのプロパティのいずれかを読んでも、例えば、C++

にQMLからの信号を送信するために非常に簡単です、これはうまく動作します:

connectCom.onClicked: { 
     if (MasterGuiLogic.serialCom.connectedToPort === false) { 
      MasterGuiLogic.serialCom.connectToPort(comPort.currentText); 
     } else { 
      MasterGuiLogic.serialCom.disconnectFromPort(comPort.currentText); 
     } 
    } 

問題は、私が見えることはできません、ですSerialComから発信される信号に接続する方法を見つけることができます。私はこのような何かを行うことができるだろうと思った:

Connections: { 
     target: MasterGuiLogic.serialCom; 
     onConnectedToPortChanged: { 
      if (MasterGuiLogic.serialCom.connectedToPort === false) { 
       connectCom.text = "Disconnect"; 
       comPort.enabled = false; 
      } else { 
       connectCom.text = "Connect"; 
       comPort.enabled = true; 
      } 
     } 
    } 

これを変更するSerialComのboolean型プロパティに耳を傾ける必要がありますが、私は次のエラーを取得する:

QQmlApplicationEngine failed to load component 
qrc:/QmlGui/main.qml:21 Type Page1 unavailable 
qrc:/QmlGui/Page1.qml:49 Invalid attached object assignment 

これだけではIを意味します上記のターゲット行を使用して "接続"できません。 ContextProperty内のQObject型のQ_PROPERTYからの信号に接続できる他の方法はありますか?

+0

笑...眠いながらプログラミングを試みることはありません...そこにコロン(:)であることを

Connections { target: MasterGuiLogic.serialCom; onConnectedToPortChanged: { ... } } 

を想定し間違った接続に関するエラーは表示されません。なぜエラー出力が 'Connections'に関係していると思いますか? – folibis

答えて

0

[OK]を、私は...の回答で問題を見つけ、他の理由のために実際に役立つ一方で、正解はありませんでした。 @Xplatformsによってコードの上に行くの後、私は私自身のコードでこれを見るまで差が....私がやっていたし、彼が何をやったの間であったかを把握できませんでした:

Connections: { 
     target: MasterGuiLogic.serialCom; 
     onConnectedToPortChanged: { 
      ... 
     } 
    } 

ありISN 「Tは `Page1`何ですか?

1

まずはどうすればよいですか&(*MainGuiLogic)MainGuiLogicを再度参照解除して参照していますか?どうして?

context->setContextProperty("MasterGuiLogic", MainGuiLogic);で十分です。

しかし、登録MasterGuiLogicタイプなどとQMLの世界でその人自身をオーバライドすることができますMasterGuiLogicという名前オブジェクトを追加します。

この動作を無効にするには、context->setContextProperty("MyGuiLogic", MainGuiLogic);のように設定します。

void connectedToPortChanged(**const bool &**);

はまたのようなC++とQML世界の間の参照を渡すことはありません。

アトミックタイプと値をそのまま使用してください。(const bool); とQMLでという名前の値としてそれを使用できるようにするには、それに名前を与える:

void connectedToPortChanged(bool connected)

をここでは、働くあなたのような構造を持つ例です。ウィンドウをクリックして出力コンソールを見るだけです。

TEST.H

#ifndef TEST_H 
#define TEST_H 

#include <QObject> 

class GuiLogic_SerialCom : public QObject 
{ 
    Q_OBJECT 
public: 
    GuiLogic_SerialCom(){} 

signals: 
    void connectedToPortChanged(bool connected); 

public slots: 
    void connectToPort(const QString & portName); 
}; 

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

    Q_PROPERTY(GuiLogic_SerialCom * serialCom READ serialCom CONSTANT) 
    GuiLogic_SerialCom* serialCom() const {return test;} 

    Q_INVOKABLE void generate_signal(); 

private: 
    GuiLogic_SerialCom * test; 
}; 

#endif // TEST_H 

TEST.CPP

#include "test.h" 
#include <QDebug> 

MasterGuiLogic::MasterGuiLogic() 
{ 
    this->test = new GuiLogic_SerialCom(); 
} 

void MasterGuiLogic::generate_signal() 
{ 
    qDebug() << __FUNCTION__ << "Calling serialcom to gen signal"; 
    this->test->connectToPort("88"); 
} 


void GuiLogic_SerialCom::connectToPort(const QString &portName) 
{ 
    qDebug() << __FUNCTION__ << "got signal" << portName; 
    emit this->connectedToPortChanged(true); 
} 

main.cppに

#include <QGuiApplication> 
#include <QQmlApplicationEngine> 
#include <QQmlContext> 
#include "test.h" 

int main(int argc, char *argv[]) 
{ 
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); 
    QGuiApplication app(argc, argv); 

    qmlRegisterUncreatableType<MasterGuiLogic>("GrblCom", 1, 0, "MasterGuiLogic", ""); 
    qmlRegisterUncreatableType<GuiLogic_SerialCom>("GrblCom", 1, 0, "GuiLogic_SerialCom", ""); 

    QQmlApplicationEngine engine; 

    engine.rootContext()->setContextProperty(QStringLiteral("Test"), new MasterGuiLogic()); 

    engine.load(QUrl(QLatin1String("qrc:/main.qml"))); 
    if (engine.rootObjects().isEmpty()) 
     return -1; 

    return app.exec(); 
} 

main.qml

import QtQuick 2.7 
import QtQuick.Controls 2.0 
import QtQuick.Layouts 1.3 

import GrblCom 1.0 

ApplicationWindow { 
    visible: true 
    width: 640 
    height: 480 
    title: qsTr("Hello World") 

    MouseArea 
    { 
     anchors.fill: parent 
     onClicked: 
     { 
      Test.generate_signal(); 
     } 
    } 

    Connections 
    { 
     target: Test.serialCom 
     onConnectedToPortChanged: 
     { 
      console.log("Got signal from SerialCom in QML. passed bool value is: " + connected); 
     } 
    } 
} 
+0

よろしくお願いします。逆参照と参照についてもう申し訳ありません。それは私がトラブルシューティングをしていた何かから残ったコードです。タイプを登録することが他の場所に推奨されました。私はそれが意味をなさないと思いました。私はこれを試して結果を返す。 –

関連する問題