【问题标题】:Is it possible to create binding proxy in qt qml?是否可以在 qt qml 中创建绑定代理?
【发布时间】:2022-11-08 10:34:23
【问题描述】:

我有一个包含这么多字段的 cpp 结构

struct CloudMusicSongList{ ... };

我想在 qml 中使用它,以便向它的实例输入一些信息,但我不想创建一个 qobject 派生类,并创建很多 qproperty ... 我在谷歌搜索并从blog 获取此代码片段

class ListItem : public QObject
{
 Q_OBJECT
public :
 ListItem(QObject *parent = 0) : QObject(parent) {}
 virtual ~ListItem() {}
 virtual int id() const = 0;
 virtual QVariant data(int role) const = 0;
 virtual QHash<int, QByteArray> roleNames() const = 0;
 virtual void triggerItemUpdate() {emit dataChanged();}
signals:
 void dataChanged();
};

我只是尝试以下代码但甚至不打印called data method

定义的.h


template <typename T>
class bindingProxy : public bindingProxyBase
{
  public:
    bindingProxy(QObject* parent = 0)
        : bindingProxyBase(parent)
    {
    }
    T tm;
    virtual ~bindingProxy()
    {
    }
    virtual QVariant data(int role)
    {
        qDebug() << "called data method";
        QVariant qv;
        auto fucs = Prism::Reflection::get_md<T>();
        if (role == Qt::DisplayRole)
            fucs[0].getFunc(tm, 0, qv);
        else
            fucs[role].getFunc(tm, role, qv);
        return qv;
    }
    QHash<int, QByteArray> roleNames() const
    {
        static QHash<int, QByteArray> roles{};
        if (roles.count() == 0)
        {
            for (Prism::Reflection::PrismMetaData<T>& item : Prism::Reflection::get_md<T>())
            {
                roles[item.offset] = item.name;
            }
        }
        return roles;
    }
    bool setData(QVariant& value, int role = Qt::EditRole)
    {
        Prism::Reflection::get_md<T>()[role].setFunc(tm, role, value);
        triggerItemUpdate();
        return true;
    }
};

bodyViewModel.cpp

#include ....
...
..

Q_DECLARE_METATYPE(bindingProxy<CloudMusicSongList>*);
class BodyViewModel : public QObject
{

    Q_PROPERTY(bindingProxy<CloudMusicSongList>* editSongListModel READ editSongListModel WRITE setEditSongListModel NOTIFY editSongListModelChanged)

...
...
...


使用.qml

 Button {
     id:btn_tst
     text: BodyViewModelCpp.editSongListModel.name + "hbb"
     onClicked: BodyViewModelCpp.editSongListModel.name = "3232"
 }


运行应用程序梯级后按钮看起来像这个图像

不知道是不是XY问题。
有人可以帮忙吗?谢谢

我想创建一个 bindingProxy 模板类,它可以在 qml 中双向绑定 我认为它应该等同于 wpf 中的dynamicObject

【问题讨论】:

  • 如果你不想要 Q_OBJECT,你考虑过 Q_GADGET 吗?
  • 不,我想使用纯 C++ 结构,没有宏
  • 但是 Q_GADGET 允许您向 QML 公开一个 c++ 结构。

标签: qt qml qt5


【解决方案1】:

基于CloudMusicSongList 我假设你拥有的是一个列表/数组。有很多方法可以将其暴露给 QML。

QQmlListProperty 是 QObject 的列表。它需要注册底层 QObject,但是,允许您创建/管理和遍历结果列表。该列表通常由另一个 QObject 拥有。例如我们可以有一个 QmlFile 对象,然后实现一个可以返回 QmlFiles 列表的 QmlFileSystem 对象。

QAbstactListModel 可用于需要模型的地方,例如列表显示。

QVariant、QVariantList 和 QVariantMap 是在 QML 中创建 Javascript 对象的最简单方法。优点是你不需要注册任何东西,但缺点是你没有智能感知。

QVariant getBooks() {
    QVariantList books;
    QVariantMap book1;
    book1["title"] = QString("Lord of the Rings");
    QVariantMap book2;
    book2["title"] = QString("The Hobbit");
    books.append(book2);
    return books;
    // results in QML/JS:
    // [ { "title": "Lord of the Rings" },
    //   { "title" : "The Hobbit" } ]
}

【讨论】:

    猜你喜欢
    • 2018-03-07
    • 2018-03-20
    • 1970-01-01
    • 1970-01-01
    • 2016-05-09
    • 2017-06-01
    • 1970-01-01
    • 2011-08-04
    • 2023-03-04
    相关资源
    最近更新 更多