2017-04-20 44 views
1

我有TabView的在main.qml℃之間++和QML綁定與動態創建的選項卡元素

TabView { 
    id: tabRoot 
    objectName: "tabRootObj" 
} 

我的應用程序創建的每個新的傳入TCP連接上新的選項卡。以下代碼根據需求創建新選項卡(基於此回答https://stackoverflow.com/a/27093137/3960195)。

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))); 
} 

隨着每一個TCP連接,它還創建ConnectionManager新的類實例其中包含了一些統計數據(傳輸的字節數如)通過屬性訪問。

//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'函數只有兩個參數,它們是選項卡的標題和構造組件(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),它包含一個角色connection(用於在Repeaterdelegate中引用ConnectionManager的實例)。我用QQmlApplicationEngine.rootContext()->setContextProperty()方法連接Repeater和我的模型實例。下面的例子說明如何進行連接:

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中創建動態標籤的人有所幫助。

相關問題