2017-04-20 14 views
1

とC++とQMLとの結合、私はmain.qmlは、動的に作成タブ要素

TabView { 
    id: tabRoot 
    objectName: "tabRootObj" 
} 

でTabViewを持っている私のアプリケーションは、すべての新しい着信TCP接続上で新しいタブを作成します。次のコードは、要求に応じて新しいタブを作成します(この回答に基づいて、https://stackoverflow.com/a/27093137/3960195)。また、プロパティを介してアクセス可能ないくつかの統計情報が含まれているクラスConnectionManagerの新しいインスタンス(転送されたバイトの数など)を作成し、すべてのTCP接続で

void addTab(QQmlApplicationEngine& engine) { 
    root_tab = engine.rootObjects().first()->findChild<QQuickItem*>(QStringLiteral("tabRootObj")); 

    QVariant new_tab; 
    QQmlComponent component(&engine, QUrl("qrc:/MyTab.qml"); 
    QMetaObject::invokeMethod(root_tab, "addTab", 
     Q_RETURN_ARG(QVariant, new_tab), 
     Q_ARG(QVariant, QStringLiteral("Tab name")), 
     Q_ARG(QVariant, QVariant::fromValue(&component))); 
} 

//ConnectionManager.hpp 
class ConnectionManager : public QObject 
{ 
    Q_OBJECT 
public: 
    // ... 
    Q_PROPERTY(QString address READ address NOTIFY ipChanged) 
    Q_PROPERTY(int received READ received NOTIFY receivedChanged) 
    //... 
} 

//MyTab.qml 
Item { 
    property string ip 
    property int received 
    ... 
} 

私が必要とするものは、プロパティーを持つプロパティーをバインドすることです。MyTab.qml。 問題は方法TabView.addTabがそれ自身にMyTabのコンポーネントを作成し、私はそのコンテキストにConnectionManagerの具体的なインスタンスを注入することができないということです。また、新しい接続が作成されるまで、ConnectionManagerは存在しませんので、アプリケーションの開始時にrootContextまで追加することはできません。この新しく作成されたオブジェクト間にバインディングを作成するにはどうすればよいですか?

それはQMLで私の最初のプロジェクトはので、多分それを行うにはどのようにより良い「QML」方法があります。その場合、「正しい」方法を示す回答も受け入れられます。

+1

'ConnectionManager'をQML' addTab'関数に渡せませんか? また、C++とQMLの間の結合を制限するために、私はC++からタブを追加しません。私は、さまざまな接続のC++モデルを公開し、それをQMLに公開します。次に、私は代理人として 'MyTab'と一緒に' Repeater 'を使用します。 – GrecKo

+0

QML 'addTab'関数には、タブのタイトルと構築されたコンポーネントの2つのパラメータしかありません(http://doc.qt.io/qt-5/qml-qtquick-controls-tabview.html#addTab-method)。リピータのソリューションは本当に素晴らしいようです。私はあなたが 'TabView'の中で' Repeater 'を使うことができるのか分かりませんでした。 – Qeek

+0

* GrecKo *はおそらくあなた自身のC++機能について話していたでしょう:あなたがコンポーネントを作成する 'addTab(...)'。 – derM

答えて

0

コメントでGrecKoをお勧めしましたが、私はRepeaterTabViewの中に使用し、モデルとして定義しました。 Repeater

TabViewは次のようになります。

TabView { 
    id: tabRoot 
    Repeater { 
     model: ConnectionModel 
     delegate: Tab { 
      title: connection.name 
      Client { 
       address connection.address 
       received: connection.received 
      } 
     } 
    } 
} 

簡単にQtのdocumentationで見つけることができますどのようにモデルを作成します。 ConnectionModelというモデルクラス(QAbstractListModelから継承)があり、connectionRepeaterdelegateConnectionManagerのインスタンスを参照するために使用されています)が含まれているとします。私はRepeaterをモデルインスタンスに接続するためにQQmlApplicationEngine.rootContext()->setContextProperty()メソッドを使用しました。

QApplication app(argc, argv); 
QQmlApplicationEngine engine; 
// Create instace of ConnectionModel 
ConnectionModel model; 
// Assasign the model instance to the QML context property "ConnectionModel" 
engine.rootContext()->setContextProperty("ConnectionModel", &model); 
// ... 
engine.load(QUrl(QStringLiteral("qrc:/main.qml"))); 

return app.exec(); 

プログラムはConnectionManagerの新しいインスタンスを作成し、すべての新しいTCP接続の場合:以下の例では、接続を作成する方法を示しています。その後、新しいレコードをモデルに挿入するメソッドを呼び出し、新しいConnectionManagerの参照を挿入します。

QMLでダイナミックなタブを作成する必要がある人に役立つことを願っています。

関連する問題