我在 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
中的属性绑定(bind)。
问题是 TabView.addTab
方法自己创建了 MyTab
的组件,我无法将 ConnectionManager
的具体实例注入(inject)到它的上下文中。此外,ConnectionManager 在创建新连接之前不存在,因此我无法通过 rootContext
在应用程序启动时添加它。如何在这个新创建的对象之间创建绑定(bind)?
这是我在 QML 中的第一个项目,所以也许有更好的“QML”方法来完成它。在这种情况下,显示“正确”方式的答案也是可以接受的。
最佳答案
正如 GrecKo 在评论中推荐的那样,我在 TabView
中使用了 Repeater
并为其定义了一个模型。
带有 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
(用于引用实例Repeater
的 delegate
中的 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();
对于每个新的 TCP 连接,程序都会创建一个新的 ConnectionManager
实例。之后它将调用将新记录插入模型的方法并插入新的 ConnectionManager
的引用。
我希望它对必须在 QML 中创建动态选项卡的人有所帮助。
关于c++ - 使用动态创建的选项卡元素在 C++ 和 QML 之间进行绑定(bind),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43522414/