Qt中的集合绑定

对于单对象中的属性的绑定,这里就不作介绍了。如果不了解的话,可以看看这篇文章Qt中的双向绑定_heater404的博客-CSDN博客

现在,我们有一组相同类型的对象需要绑定,该怎么处理呢?

例如我们有如下的类:

#ifndef VIEWMODEL_H
#define VIEWMODEL_H

#include <QObject>

class MyModel : public QObject
{
    Q_OBJECT
    Q_PROPERTY(QString name READ getName WRITE setName NOTIFY nameChanged)
    Q_PROPERTY(bool flag READ getFlag WRITE setFlag NOTIFY flagChanged)
public:
    explicit MyModel(QObject *parent = nullptr);
    MyModel(QString str,bool b);
    QString getName() const;
    void setName(const QString& name);

    bool getFlag() const;
    void setFlag(const bool& flag);

signals:
    QString nameChanged();
    bool flagChanged();

public slots:
    bool refresh(QString args);

private:
    QString name;
    bool flag;
};
#endif // VIEWMODEL_H
#include <stdio.h>
#include "MyModel.h"
#include "qdebug.h"

MyModel::MyModel(QObject *parent)
    : QObject{parent}
{

}

MyModel::MyModel(QString _name,bool _flag)
    :name(_name),flag(_flag)
{

}

QString MyModel::getName() const
{
    return name;
}

void MyModel::setName(const QString& _name)
{
    if(name!=_name)
    {
        name=_name;
        qDebug()<<"setName:"<<_name;
        emit nameChanged();
    }
}


bool MyModel::getFlag() const
{
    return flag;
}

void MyModel::setFlag(const bool& _flag)
{
    if(flag!=_flag)
    {
        flag=_flag;
        qDebug()<<"setFlag:"<<flag;
        emit flagChanged();
    }
}


bool MyModel::refresh(QString args)
{
    this->setFlag(!this->flag);
    return true;
}

对于数据模型,我们肯定需要一个集合,然后还有一些有关该集合的业务操作(增删改查),所以,我们需要再创建一个类,用来管理这个集合。

#ifndef MYVIEWMODEL_H
#define MYVIEWMODEL_H

#include "MyModel.h"
#include <QObject>

class MyViewModel : public QObject
{
    Q_OBJECT
    Q_PROPERTY(int index READ index WRITE setIndex NOTIFY indexChanged)
public:
    explicit MyViewModel(QObject *parent = nullptr);
    MyViewModel(int index);
    QObjectList getModels();
    void addOneModel(MyModel* model);
    void updateOneModel(QString name);
    MyModel* getCurrentModel();
    Q_INVOKABLE void onClicked(QString name);
    int index();
    void setIndex(const int& i);
signals:
   int indexChanged();

private:
   int m_index;
    QObjectList models;
    MyModel currentModel;
};

#endif // MYVIEWMODEL_H

#include "myviewmodel.h"
#include "qdebug.h"

MyViewModel::MyViewModel(QObject *parent)
    : QObject{parent}
{

}

MyViewModel::MyViewModel(int i)
    :m_index(i)
{

}

QObjectList MyViewModel::getModels()
{
    return this->models;
}


void MyViewModel::addOneModel(MyModel* model)
{
    this->models.append(model);
}

void MyViewModel::updateOneModel(QString name)
{
    QObject* model;
    foreach( model ,this->models)
    {

        MyModel* mm= (MyModel*)model;
        if(mm->getName()==name)
        mm->setFlag(!mm->getFlag());
    }
}

void MyViewModel::onClicked(QString name)
{
   this->updateOneModel(name);
}

MyModel* MyViewModel::getCurrentModel()
{
   return &this->currentModel;
}


int MyViewModel::index()
{
   return this->m_index;
}

void MyViewModel::setIndex(const int& i)
{
    if(m_index!=i)
    {
        this->m_index=i;
        emit indexChanged();
        qDebug()<<"currentIndex="<< m_index;
    }
}

对于这个类,我们需要传递给QML的数据有两种:

  • 这个类的集合
  • 这个类的单属性

所以,传递给QML中的也就是两个数据模型。

那么在QML中怎么使用呢?对于单属性,我们已经很熟悉了,对于集合呢?那就需要视图模型(ListView是其中一种)

Rectangle {
        id: root
        anchors.fill: parent
        ListView {
            currentIndex: viewModel.index
            onCurrentIndexChanged: viewModel.index = currentIndex
            id: listview
            snapMode: ListView.SnapToItem
            focus: true
            anchors.fill: parent
            model: models
            spacing: 5
            delegate: mydelegate
        }

        Component {
            id: mydelegate
            Row {
                id: row
                spacing: 5
                Text {
                    color: row.ListView.isCurrentItem ? "black" : "lightGreen"
                    verticalAlignment: Text.AlignVCenter
                    text: modelData.name
                    MouseArea {
                        anchors.fill: parent
                        onClicked: {
                            listview.currentIndex = index
                        }
                    }
                }
                Switch {
                    id: m_flag
                    checked: modelData.flag
                    onCheckedChanged: modelData.flag = m_flag.checked
                    Connections {
                        target: modelData
                        function onFlagChanged() {
                            m_flag.checked = modelData.flag
                            console.log("onFlagChanged")
                        }
                    }
                }
            }
        }

        Button {
            anchors.bottom: parent.bottom
            text: qsTr("button")
            onClicked: {
                viewModel.onClicked("Item1")
            }
        }
    }

ListView中的model属性用于接收从C++传递进来的集合数据。

delegate用于自定义视图组件,这个组件用于展示集合中的数据。组件中还添加了其他的一些功能。

但是,这种绑定只适用于改查业务增删业务暂时不支持。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值