从 C++ 更改 QML Listview 委托

Posted

技术标签:

【中文标题】从 C++ 更改 QML Listview 委托【英文标题】:Change QML Listview delegate from C++ 【发布时间】:2017-01-21 17:41:57 【问题描述】:

我正在尝试从 C++ 更改 qml listview 的委托,但目前我坚持如何更改代表委托属性的别名。

更新详情: 我在单独的 qml 文件中有多个委托,在我的应用程序中有很多屏幕,每个屏幕都有不同的列表视图 UI,我想要的是这样的:

将委托文件名传递给 C++ 函数 >>> C++ 函数设置 listView(或类似的东西)的委托属性 >>> listview 加载相应的委托。

我的 qml 文件如下所示:

Item 
    id: root
    property alias listViewDelegate: listView.delegate

    ListView
        id: listView
        delegate: MyDelegate // I have MyDelegate.qml file, it's working well
        model: listModel
    

    // List model
    MyListModel 
        id: listModel
    

我尝试使用 setProperty() 方法从 C++ 更改 listViewDelegate 别名,但没有成功(实际上是错误)。

qmlObj->setProperty("listViewDelegate", componentDelegate);

如何做到这一点?或者任何人都可以建议我更好的方法来实现它?谢谢!

【问题讨论】:

【参考方案1】:

我认为有更好的方法来做到这一点。

步骤:

1) 在c++端创建模型。

class Model : public QObject 
  Q_OBJECT
  Q_PROPERTY(qint32 status READ status WRITE setStatus NOTIFY statusChanged)
public:
  Model(QObject *parent = Q_NULLPTR);
  ...

2) 通过 setContextProperty 将模型对象传递给 qml

Model model;
engine.rootContext()->setContextProperty("model1", &model);

3) 在 Model.status 上绑定 ListView 的委托

ListView 
    id: listview
    anchors.fill: parent
    spacing: 20
    model: listmodel
    delegate: model1.status === 0 ? delegate1 : delegate2

4) 现在您可以在 c++ 端通过 setStaus() 更改委托。

model.setStatus(1);

【讨论】:

谢谢,但问题是我在单独的 qml 文件中有多个委托,在我的应用程序中有很多屏幕,每个屏幕都有不同的列表视图 UI,我想要的是:传递委托文件C++ 函数的名称 >>> C++ 函数设置 listView 的委托属性(或类似的东西) >>> listview 加载相应的委托。 记住:总是call setContextProperty BEFORE setSource,否则会报错listmodel is not defined【参考方案2】:

必须将属性listViewDelegate分配给ListView,这样当你修改ListViewDelegate属性时,ListView会收到通知并更新委托。

Item 
    id: root
    property Component listViewDelegate: myDelegate

    MyDelegate  
          id:  myDelegate
    

    ListView
        id: listView
        delegate: listViewDelegate
        model: listModel
    

    // List model
    MyListModel 
        id: listModel
    

【讨论】:

【参考方案3】:

谢谢大家,我刚刚想出了一个使用javascript的方法,看起来很复杂,但它确实有效。

我将此 javascript 函数添加到我的根项中

function loadListViewDelegate(file)
    var component = Qt.createComponent(file);
    if(component && (component.status === Component.Ready))
    
        listView.delegate = component;
        return file;
    
    return "";

然后我从 C++ 调用这个函数,参数是委托 qml 文件。它看起来像这样:

QMetaObject::invokeMethod(qmlObj, "loadListViewDelegate", Q_RETURN_ARG(QVariant, returnedValue), Q_ARG(QVariant, "delegate_screen_home.qml"));

How to invoke qml javascript method

【讨论】:

以上是关于从 C++ 更改 QML Listview 委托的主要内容,如果未能解决你的问题,请参考以下文章

如何从 QML 中的 GridView 或 ListView 获取实例化的委托组件

为什么QML ListView委托不立即对选择更改做出反应?

Qml c++ 不同的委托 qt mvc

从 QML ListView 委托调用 JavaScript 对象方法

QML 阻止 ListView 委托一直更新

如何在 QML 中创建动态委托?