对于单对象中的属性的绑定,这里就不作介绍了。如果不了解的话,可以看看这篇文章Qt中的双向绑定_heater404的博客-CSDN博客
现在,我们有一组相同类型的对象需要绑定,该怎么处理呢?
例如我们有如下的类:
#ifndef VIEWMODEL_H #define VIEWMODEL_H #includeclass 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#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:"< setFlag(!this->flag); return true; }
对于数据模型,我们肯定需要一个集合,然后还有一些有关该集合的业务操作(增删改查),所以,我们需要再创建一个类,用来管理这个集合。
#ifndef MYVIEWMODEL_H #define MYVIEWMODEL_H #include "MyModel.h" #includeclass 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用于自定义视图组件,这个组件用于展示集合中的数据。组件中还添加了其他的一些功能。
但是,这种绑定只适用于改查业务,增删业务暂时不支持。



