在QML和C ++之间同步模型视图

时间:2017-03-14 11:05:06

标签: c++ qt qml

我正在学习QML以及QML和C ++代码之间的通信。 在此示例中,QML和C ++中的视图应通过一个通用模型进行同步。我已将模型导出到QML。 QML还显示正确的项目数。 不幸的是,在这个例子中,C ++和QML之间的checked属性不同步(实际上没有其他属性)。而连接到同一模型的C ++代码中的两个视图是同步的。

缺少什么?或者这是正常的行为,因为同步只是一种方式吗?

main.cpp中:

#include <QApplication>
#include <QQmlApplicationEngine>
#include <QStandardItemModel>
#include <QStandardItem>
#include <QQmlContext>
#include <QHash>
#include <QListView>

class CppModel :public QStandardItemModel{
  QHash<int, QByteArray> _roleNames;
  public:
  CppModel(QObject *p=0):QStandardItemModel(p)
  {
    _roleNames[Qt::DisplayRole] = "name";
    _roleNames[Qt::CheckStateRole] = "checked";
  }
  QHash<int, QByteArray> roleNames() const
  {
    return _roleNames;
  }
};

int main(int argc, char *argv[])
{
  QApplication app(argc, argv);

  CppModel m;

  QStandardItem *it = new QStandardItem();
  it->setCheckable(true);
  it->setData("S1",Qt::DisplayRole);
  m.appendRow(it);

  it = new QStandardItem();
  it->setCheckable(true);
  it->setData("S2",Qt::DisplayRole);
  m.appendRow(it);

  it = new QStandardItem();
  it->setCheckable(true);
  it->setData("S3",Qt::DisplayRole);
  m.appendRow(it);

  QListView *v1 = new QListView(0);
  v1->setModel(&m);
  v1->show();

  QListView *v2 = new QListView(0);
  v2->setModel(&m);
  v2->show();


  QQmlApplicationEngine engine;
  QQmlContext *ctxt = engine.rootContext();
  ctxt->setContextProperty("cppmodel", &m);
  engine.load(QUrl(QStringLiteral("qrc:/main.qml")));


  return app.exec();
}

main.qml:

import QtQuick 2.6
import QtQuick.Controls 1.5

ApplicationWindow {
    visible: true
    width: 640
    height: 480
    title: qsTr("Model Test")

    ListModel {
        // id :cppmodel // *(1)* If this line active, this QML model will shadow C++ model with same name and 
        //                       QML views will be synchron.
        //                       However, C++ views won't be updated
        //                       If this line is disabled, Checking items in C++ models will update QML items
        //                       but QML views don't react on mouse-clicks. Obviouly, set method dowsn't work with C++ models

        ListElement { name: "S1"; checked:0; }
        ListElement { name: "S2"; checked:0; }
        ListElement { name: "S3"; checked:0; }
    }



    Component {
        id: myDelegate

        Rectangle {
            color: "green" //ListView.isCurrentItem ? "black" : "red"
            width: 200
            height: 50

            Rectangle {
                color: checked ? "red" : "blue"
                width: 20
                height: 20
                x: 10
                y: 10


                MouseArea {
                    anchors.fill: parent
                    onClicked: {
                        cppmodel.set(index, {"checked":checked?0:1} ) //*(2)* This works with QML models but not with C++
                    }
                }
            }

            Text{
                x:40
                y: 10
                text: name
            }

        }


    }

    ListView {
        id: lv1
        width:220
        height: 400
        x: 0
        clip: true
        model: cppmodel
        delegate: myDelegate
        focus: true

    }

    ListView {
        id: lv2
        width:220
        height: 400
        x: 250
        clip: true
        model: cppmodel
        delegate: myDelegate
        focus: true

    }
}

编辑:更新了代码。在评论中添加了说明

0 个答案:

没有答案