2016-12-29 4 views
1

私の目標は、(Windows)マシンで使用可能なシリアルポートをコンボボックスに入力することです。私はQSerialPortInfoのラッパーを作成しました。これはQMLルートコンテキストプロパティとして公開したいと思います。 QtQuick2アプリケーションテンプレートを出発点として使用しました。Qt5.7 QtQuick2アプリケーションテンプレートでQmlコンテキストプロパティを設定する

#include <QList> 
#include <QObject> 

class QuickSerialPortInformer : public QObject 
{ 
    Q_OBJECT 
    Q_PROPERTY(QList<QString> portselectionmodel READ portselectionmodel CONST) 

public: 
    static const QuickSerialPortInformer *getInstance(); 

    QList<QString> portselectionmodel() const; 

protected: 
    QuickSerialPortInformer(); 

private: 
    static const QuickSerialPortInformer *Instance; 
}; 

#endif // QUICKSERIALPORTINFORMER_H 

私はこのようなオブジェクトを登録します。

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

    QQmlApplicationEngine engine; 
    /* here */ engine.rootContext()->setContextProperty("serialPortInformer", QuickSerialPortInformer::getInstance()); 
    engine.load(QUrl(QLatin1String("qrc:/main.qml"))); 

    return app.exec(); 
} 

プロパティによって返さQList<QString>は、コンボボックスのモデルを務めます。私の推測では、QList<QString>は文字列のJavaScript arrayに変換され、ComboBoxのモデルプロパティのC++部分に必要なものに変換されています。結局、プロパティはJavaScriptで定義された文字列の配列を受け入れます。しかし、QuickSerialPortInformerのプロパティをComboBoxのに割り当てると、そのようなマーシャリングは行われないように思われる。コメントで指摘されているように、QtQuickビューのモデルとしては、一部のC++タイプしか使用できません。そのうちの1つは今私が使っているQStringListです。

ComboBox { 
    id: portSelector 
    model: serialPortInformer.portselectionmodel 
} 

私の問題は、SerialPortInformerがqmlコンテキストでは不明であるということです。オブジェクトを登録するために使用しているコンテキストが、engine.load()で実行しているスクリプトには表示されていないと思われます。私はload()setContextProperty()の順序を逆にしようとしました。私は何が欠けていますか?

コメントとドキュメントに示唆されているように、SerialPortInformerからserialPortInformerに名前を変更した後、別の問題が発生します。 serialPortInformerは、期待されるオブジェクトではなく、QMLの値truebooleanです。

私は、私のユースケースの動作を可能にした程度に "ブール値"ミステリーを解決することができました。答えは、SerialPortInformer::getInstance()constへのポインタを返していたことです。 const - 修飾子serialPortInformerはオブジェクトタイプであり、目的の属性が公開されました。私が最初にコンパイルした理由は、const QVariant &のメソッドのオーバーロードが、explicitコンストラクターを使用して代わりに呼び出されたという理由が考えられます。だから私のノートへの自己です:あなただけQStringListを読みたいのではちょうどQ_INVOKABLEメソッドの戻り値の型としてQStringListを行い、QMLコンテキスト

+1

小文字の名前を使用するとどうなりますか? 'serialPortInformer'? – Mitch

+0

私は前にこれが好きで、ただそれを再試行しました。まだ問題は残っています。 'serialPortInformer'がqmlデバッグウィンドウに表示されません。私はそれが 'mainWindow'と同じレベルになると期待します – everclear

+0

私はあなたが関係なく、小文字の名前を使うべきだと思います。http://doc.qt.io/qt-5/qtqml-syntax-objectattributes.html#the- id属性は小文字でなければならないと言います。また、http://doc.qt.io/qt-5/qqmlengine.html#qmlRegisterSingletonTypeを使用してオブジェクトを登録することもできます。そうすれば、大文字の構文を使用してシングルトンとして扱うことができます。 – Mitch

答えて

1

に一定のQObject Sへのポインタを登録することはありません。また、元のコードで作成している可能性のあるオブジェクトQuickSerialPortInformerを作成することはありません。以下のように(see documentationを)あなたのQ_PROPERTYを実装し、

#include <QList> 
#include <QObject> 

class QuickSerialPortInformer : public QObject 
{ 
    Q_OBJECT 
    Q_INVOKABLE QStringList portselectionmodel(); 
    .... 
}; 

main.cppに

int main(int argc, char *argv[]) 
{ 
    ... 
    QuickSerialPortInformer portInformer; 
    QQmlApplicationEngine engine; 
    engine.rootContext()->setContextProperty("serialPortInformer",&portInformer); 
    engine.load(QUrl(QLatin1String("qrc:/main.qml"))); 

    return app.exec(); 
} 
0

まず、このようなはずな何かあなたのコードをまとめるには:なぜわからない

Q_PROPERTY(QStringList portSelectionModel READ portSelectionModel WRITE setPortSelectionModel NOTIFY portSelectionModelChanged) 

をシングルトンは機能していませんが、次のように実装してください:

public: 
static QuickSerialPortInformer& Instance() 
{ 
    static QuickSerialPortInformer instance; 
    return instance; 
} 
~QuickSerialPortInformer()=default; 

private: 
QuickSerialPortInformer()=default; 
QuickSerialPortInformer(QuickSerialPortInformer const&)=delete; 
void operator = (QuickSerialPortInformer const&)=delete; 

あなたのメインで。CPP:あなたのQMLで

QQmlContext* quickSerialPortInformerCtx = engine.rootContext(); 
quickSerialPortInformerCtx->setContextProperty("quickserialportinformer", &QuickSerialPortInformer::Instance()); 

ComboBox { 
    model: quickserialportinformer.portSelectionModel 
} 

それは私が前にこの実装を使用しました、動作するはずです。

関連する問題