2017-06-26 32 views
2

QMLオブジェクトとやり取りするQt C++コードを記述しようとしています。目標は、GUIのテキストログに追加されたTCPソケット上の文字列を受け取ることです。新しい文字列を受け取るたびにappendText()関数を実行します。 QWidgetsと.uiファイルを使用している現在、この実装の実装が1つあります。私は同一のQML実装を持つ必要があります。私のQWidgetの実装では、textBrowserと次のようなappend関数を使用します。 "theString"はプログラムの実行中に変更され、各変更が追加され、テキストログがいっぱいになります。QML textAreaが追加されないのはなぜですか?

//update the text log with data received on TCP socket 
void MainWindow::appendText() { 
    ui->textBrowser->append(theString); 

} 

これにより、希望の結果が得られ、各文字列が入力時にテキストボックスに追加されます。出力は次のようになります。

Control connection successful. 
Data connection successful. 
Control Packet Receieved: 
1 
Control Packet Receieved: 
2 
Control Packet Receieved: 
3 
Control Packet Receieved: 
4 
Control Packet Receieved: 
1 
Control Packet Receieved: 
2 
Control Packet Receieved: 
3 
Control Packet Receieved: 
4 

...私は次のコードでQMLのオブジェクトと同じ関数であると信じるもの

//update the text log with data received on TCP socket 
void MainWindow::appendText() { 
    QMetaObject::invokeMethod(textbox, "append", Qt::DirectConnection, Q_ARG(QVariant, theString)); 
    //QQmlProperty(textbox, "text").write(theString); 

} 
を行う場合しかし、それは唯一の最初の2つの文字列を付加していない、そしてそれを超え、それ以上。出力は代わりにこのようになります。

Control connection successful. 
Data connection successful. 

C++のQMLメソッドを広範囲に呼び出すためのドキュメントを見てきましたが、まだ運がなかったのです。どんな助けもありがとうございます。御時間ありがとうございます。

答えて

1

問題を再現できません。

解決策

import QtQuick.Controls 2.0を使用するための溶液であってもよいです。

QMetaObject::invokeMethod(textbox, "append", Qt::DirectConnection, Q_ARG(QString, theString)); 

ベター:エラーメッセージによって示唆されるように

QMetaObject::invokeMethod: No such method QQuickTextArea::append(QVariant) 
Candidates are: 
    append(QString) 

は、あなたがパラメータの型として代わりにQVariantの今QStringを使用する必要があります。その場合は

は、私は次のエラーメッセージを取得します代替

Qtで述べたように、avoid manipulating QML object from C++(深いオブジェクトツリーへ):

Warning: While it is possible to use C++ to access and manipulate QML objects deep into the object tree, we recommend that you do not take this approach outside of application testing and prototyping. One strength of QML and C++ integration is the ability to implement the QML user interface separately from the C++ logic and dataset backend, and this strategy breaks if the C++ side reaches deep into the QML components to manipulate them directly.

したがって、新たに受信したメッセージを発するとQML側から接続C++の信号を実装するより良い代替であってもよいです。このアプローチは、ユーザーインターフェイスとプログラミングロジックを明確に区別します。

例コード

次のコードはTextArea秒ごとに"test"追加作業。

main.cppに:

#include <QGuiApplication> 
#include <QQmlApplicationEngine> 
#include <QTimer> 
#include <QQuickItem> 

QObject *textbox; 

void onTimeout() 
{ 
    QMetaObject::invokeMethod(textbox, "append", Qt::DirectConnection, Q_ARG(QVariant, "test")); 
} 

int main(int argc, char *argv[]) 
{ 
    QGuiApplication app(argc, argv); 

    QQmlApplicationEngine engine; 
    engine.load(QUrl(QStringLiteral("qrc:/main.qml"))); 

    QTimer t; 
    QObject::connect(&t, &QTimer::timeout, &onTimeout); 
    textbox = engine.rootObjects().first()->children().first(); 

    t.start(1000); 

    return app.exec(); 
} 

メイン。QML:返信用

import QtQuick 2.0 
import QtQuick.Window 2.2 
import QtQuick.Controls 1.0 

Window 
{ 
    visible: true 
    width: 600 
    height: 600 

    TextArea 
    { 
     id: textbox 
     anchors.fill: parent 
    } 
} 
+1

感謝。私はQStringのを使用して修正をしようとすると、私はこのエラーが表示されます。 QMetaObject ::は、invokeMethod:いいえ、そのような方法TextArea_QMLTYPE_31 ::アペンド(QStringの) 候補者は次のとおりです。 APPEND(QVariant)... 私は、最初の2つのかなり確信しています私が持っているのappendText()関数は、私が実際にGUIには何を書くだけであるため、メッセージは、他の方法で印刷されません。その間に信号ベースのアプローチを試みます。あなたは – 9tm09

+0

使用しているのQt/QMLバージョン?あなたは 'TextArea'を使っていますか? C++で 'textbox'をどうやって取得しますか? 'MainWindow :: appendText'が正しく呼び出されていますか? – m7913d

+0

私はQtのCreatorを4.2.1を使用しています。 QMLファイルでTextAreaオブジェクトを使用しています。 TextAreaオブジェクトはgroupBoxオブジェクトの子オブジェクトです。テキストボックス= groupBox2-> findChild ( "networkStatus"); ..... また、QMetaObjectを使用しています:invokeMethod、TextAreaオブジェクトにappendというメソッドがあります。 – 9tm09

関連する問題