c++ - 从 QML ListView 操作 QAbstractListModel 中的数据

标签 c++ qt qml qt4 qt4.8

我有一个 QML ListView,它使用 QAbstractListModel 子类作为模型。

ListView {
    id: myListView
    x: 208
    y: 19
    width: 110
    height: 160
    delegate: myListDelegate {}
    model: MyListModel
    opacity: 0
}

模型是 MyListItem 的列表。

class MyListModel : public QAbstractListModel
{
    Q_OBJECT
public:
    enum MyRoles {
        HeadingRole = Qt::UserRole + 1,
        DescriptionRole,
        QuantityRole
    };

    explicit MyListModel(QObject *parent = 0);

    void addMyListItem(const MyListItem &item);
    int rowCount(const QModelIndex & parent = QModelIndex()) const;
    QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const;
    void dropList();

private:
    QList<MyListItem> m_list;

};

在委托(delegate)中我有一个鼠标区域。

我如何拦截鼠标区域上的点击并从我的 QList 模型中选择 那个 MyListItem 并将它发送到应用程序的 C++ 部分内的某处?

最佳答案

评论提到从 data() 返回指向 MyListItem 的指针到 QML 并在 QML 中访问和修改它。这需要您的 MyListItem 继承自 QObject 并为您要在 QML 中访问的每个成员添加一个 Q_PROPERTY。它还需要密切关注对象所有权 (QQmlEngine::ObjectOwnership)。

还有一种方式:实现QAbstractListModel::setData()QAbstractListModel::roleNames(),模型内容可以从QML改变,比如model.roleName = foo.

下面的最小工作示例,每次单击委托(delegate)时数量都会加倍:

C++:

struct MyListItem
{
    QString heading;
    QString description;
    int quantity;
};

class MyListModel : public QAbstractListModel
{
    Q_OBJECT
    Q_ENUMS(MyRoles)
public:
    enum MyRoles {
        HeadingRole = Qt::UserRole + 1,
        DescriptionRole,
        QuantityRole
    };

    using QAbstractListModel::QAbstractListModel;

    QHash<int,QByteArray> roleNames() const override {
        return { { HeadingRole, "heading" },
            { DescriptionRole, "description" },
            { QuantityRole, "quantity" },
        };
    }
    int rowCount(const QModelIndex & parent = QModelIndex()) const override {
        if (parent.isValid())
            return 0;
        return m_list.size();
    }

    bool setData(const QModelIndex &index, const QVariant &value, int role) override
    {
        if (!hasIndex(index.row(), index.column(), index.parent()) || !value.isValid())
            return false;

        MyListItem &item = m_list[index.row()];
        if (role == DescriptionRole) item.description = value.toString();
        else if (role == HeadingRole) item.heading = value.toString();
        else if (role == QuantityRole) item.quantity = value.toInt();
        else return false;

        emit dataChanged(index, index, { role } );

        return true ;

    }

    QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const override {
        if (!hasIndex(index.row(), index.column(), index.parent()))
            return {};

        const MyListItem &item = m_list.at(index.row());
        if (role == DescriptionRole) return item.description;
        if (role == HeadingRole) return item.heading;
        if (role == QuantityRole) return item.quantity;

        return {};
    }

private:
    QVector<MyListItem> m_list = {
        { "heading 1", "description 1", 1 },
        { "heading 2", "description 2", 42 },
        { "heading 3", "description 3", 4711 }
    };
};

QML:

ListView {
    id: listView
    anchors.fill: parent
    model: MyListModel {}

    delegate: Item {
        implicitHeight: text.height
        width: listView.width
        Text {
            id: text
            text: model.heading + " " + model.description + " " + model.quantity
        }

        MouseArea {
            anchors.fill: text
            onClicked: {
                model.quantity *= 2;
            }
        }
    }
}

关于c++ - 从 QML ListView 操作 QAbstractListModel 中的数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44777999/

相关文章:

c++ - 链接错误 : construction vtable defined in a discarded section

c++ - CoCreateInstance 返回 E_INVALIDARG

qt - PyQT(也是 C++ QT 绑定(bind))嵌入式 urxvt 终端失去焦点

c++ - Qt ListView 不显示 C++ 模型内容

c++ - 从 C++ 向 QML 公开串口名称

android-ndk-profiler 对 monstartup 和 moncleanup 的 undefined reference

c++ - 为什么可以使用 std::ref 将成员函数用作可调用类型?

c++ - 带箭头的 Qt 工具提示

c++ - 添加新文件时需要更新 Qt .pro 和 Visual Studio .vcxproj

QT QmlMap 带点的折线