C ++和QML与动态创建的制表符元素之间的绑定

时间:2017-04-20 14:29:55

标签: c++ qt qml

我在main.qml

中有TabView
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的第一个项目,所以也许有一个更好的&#34; QML&#34;如何做到这一点。在这种情况下回答显示&#34;右&#34;方式也是可以接受的。

1 个答案:

答案 0 :(得分:0)

正如评论中推荐的GrecKo,我使用了Repeater TabView并为其定义了模型。

Repeater的TabView如下所示:

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

如何创建模型可以在Qt&#39; documentation中轻松找到。我们假设我有一个名为ConnectionModel的模型类(继承自QAbstractListModel)并且它包含一个角色connection(用于引用一个实例) ConnectionManager Repeater中的delegate。我已使用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();

每次新的TCP连接,程序都会创建ConnectionManager的新实例。之后,它将调用方法将新记录插入模型并插入新ConnectionManager的引用。

我希望有人必须在QML中创建动态标签页。