Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/161.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/hadoop/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 型号为isn&x27;t已使用setContextProperty更新_C++_Qt_Model_Qml - Fatal编程技术网

C++ 型号为isn&x27;t已使用setContextProperty更新

C++ 型号为isn&x27;t已使用setContextProperty更新,c++,qt,model,qml,C++,Qt,Model,Qml,我对Qt非常陌生,在将模型传递到视图时遇到问题。 我的视图有一组按钮和一张地图,地图上有一些标记,这些标记的纬度/经度来自我的模型。 单击按钮应更新地图上的标记(删除一些和/或显示新标记) 问题是:当我的模型(QLIST)在C++侧得到更新时,QML侧没有。p> (我知道这类问题似乎已经被问过了,但在阅读了不同的答案后,我无法清楚地知道是否可以用更聪明的方式调用setContextProperty())或者,如果我必须使用诸如发射信号和绑定属性之类的东西,在阅读了一些文档之后,我也无法清楚地看到

我对Qt非常陌生,在将模型传递到视图时遇到问题。 我的视图有一组按钮和一张地图,地图上有一些标记,这些标记的纬度/经度来自我的模型。 单击按钮应更新地图上的标记(删除一些和/或显示新标记)

问题是:当我的模型(QLIST)在C++侧得到更新时,QML侧没有。p> (我知道这类问题似乎已经被问过了,但在阅读了不同的答案后,我无法清楚地知道是否可以用更聪明的方式调用setContextProperty())或者,如果我必须使用诸如发射信号和绑定属性之类的东西,在阅读了一些文档之后,我也无法清楚地看到这些东西)

架构如下所示:

  • 具有QApplication实例化和MainWindow(MainWindow是自定义QMainWindow类)的主类。执行应用程序并显示窗口

  • 带有updateMap()方法的Mapwidget类(自定义QQuickWidget类),该方法:

    • 对用户界面上的按钮单击作出反应
    • 更新模型(QList)
    • 使用setContextProperty()方法将更新后的模型传递给 景色
  • MainWindow类具有Mapwidget属性

  • 到目前为止我已经尝试过的事情:

    • 在调用setSource()方法之前,在Mapwidget构造函数中调用setContextProperty()时,会考虑模型。因此,我用于将模型传递到视图中的语法应该是正确的。问题似乎是此后对setContextProperty()的任何调用(在本例中:在updateMap()方法中)都不会传递到QML文件

    • 在不同级别(Mapwidget类、MainWindow类)上调用setContextProperty(),结果是相同的,在应用程序首次启动后从未考虑过

    • 我已经测试了这个模型,并且知道它确实在updateMap()方法中得到了更新,只是看起来更新没有传输到QML文件

    QML文件:

    Item {
        width: 1200
        height: 1000
        visible: true
    
        Plugin {
            id: osmPlugin
            name: "osm"
        }
    
        Map {
            id: map
            anchors.fill: parent
            plugin: osmPlugin
            center: QtPositioning.coordinate(45.782074, 4.871263)
            zoomLevel: 5
    
            MapItemView {
                model : myModel
                delegate: MapQuickItem {
                    coordinate:QtPositioning.coordinate(
                         model.modelData.lat,model.modelData.lon)
                    sourceItem: Image {
                        id:image_1
                        source: <picturePath>
                    }
                    anchorPoint.x: image_1.width / 2
                    anchorPoint.y: image_1.height / 2
                }
    
            }
    }
    
    为什么视图即使在调用setContextProperty()之后也看不到更新的模型


    感谢您的帮助

    通过传递给您的名称是您传递的对象的别名,在绑定
    model:myModel的情况下,它是在对象之间进行的,在您传递具有相同别名的新对象的情况下,初始绑定不再有效,因为它们是不同的对象,这类似于:

    T*T=新的T;
    连接(t,&t::foo_信号,obj,&U::foo_插槽);
    t=新的t;
    
    尽管两个对象具有相同的别名(
    t
    ),但这并不意味着与第二个对象的连接仍然存在


    解决方案是使用通知QML更新的同一对象,在这种情况下,解决方案是实现自定义QAbstractListModel:

    协调模型类

    //coordinardemodel.h
    #ifndef协调模型H
    #定义协调模型
    #包括
    #包括
    类CoordinardeModel:PublicQAbstractListModel
    {
    Q_对象
    公众:
    枚举{
    PositionRole=Qt::UserRole+1000
    };
    显式协调模型(QObject*parent=nullptr);
    无效插入(整数索引、常量QGeoCoordination和坐标);
    void append(常量QGeoCoordination&坐标);
    无效清除();
    int rowCount(const QModelIndex&parent=QModelIndex())常量重写;
    QVariant数据(常量QModelIndex&index,int-role=Qt::DisplayRole)常量覆盖;
    QHash roleNames()常量重写;
    私人:
    QList m_坐标;
    };
    #endif//coordinardemodel_H
    //协调模型
    #包括“Coordinardemodel.h”
    CoordinateModel::CoordinateModel(QObject*父对象)
    :QAbstractListModel(父级)
    {
    }
    void coordinardemodel::insert(int索引、常量QGeoCoordinate和坐标){
    int i=指数;
    if(索引<0)//前置
    i=0;
    else if(index>=rowCount())//追加
    i=行计数();
    beginInsertRows(QModelIndex(),i,i);
    m_坐标。插入(i,坐标);
    endInsertRows();
    }
    void coordinardemodel::append(常量QGeoCoordinate&坐标){
    插入(rowCount(),坐标);
    }
    void coordinardemodel::clear(){
    beginResetModel();
    m_坐标。清除();
    endResetModel();
    }
    int coordinardemodel::行计数(常量QModelIndex&parent)常量{
    if(parent.isValid())
    返回0;
    返回m_坐标。count();
    }
    QVariant coordinardemodel::数据(常量QModelIndex&index,int角色)常量{
    如果(index.row()<0 | | index.row()>=m_坐标.count())
    返回QVariant();
    如果(!index.isValid())
    返回QVariant();
    常量QGeoCoordinate&coordinate=m_坐标[index.row()];
    如果(角色==位置角色)
    返回QVariant::fromValue(坐标);
    返回QVariant();
    }
    QHash CoordinateModel::roleNames()常量{
    QHash角色;
    角色[职位角色]=“职位”;
    返回角色;
    }
    
    MapWidget类

    //mapwidget.h
    #ifndef MAPU H
    #定义mapuh
    #包括
    类协调模型;
    类MapWidget:公共QQuickWidget
    {
    公众:
    MapWidget(QWidget*parent=nullptr);
    coordinardemodel*model()常量;
    私人:
    协调模型*m_模型;
    };
    #endif//MAPWIDGET_H
    //mapwidget.cpp
    #包括“Coordinardemodel.h”
    #包括“mapwidget.h”
    #包括
    MapWidget::MapWidget(QWidget*父项):
    QQuickWidget(父级),
    m_模型(新的协调模型{this})
    {
    rootContext()->setContextProperty(“myModel”,m_模型);
    setSource(QUrl(QStringLiteral(“qrc:/main.qml”));
    }
    CoordinardeModel*MapWidget::model()常量
    {
    返回m_模型;
    }
    
    然后您可以将其用作:

    mapw;
    w、 模型()->追加(QGeoCoordinate(45.782074,-6.871263));
    w、 模型()->追加(QGeoCoordination(50.782074,-1.871263));
    w、 模型()->追加(QGeoCoordinate(55.782074,4.871263));
    w、 m
    
    mapwidget::mapwidget(QWidget *parent) : QQuickWidget(parent)
    {
        this->setSource(QUrl(QStringLiteral("qrc:/main.qml")));
    }
    
    void mapwidget::updateMap(QList<QObject *> &data)
    {
        /**
         DO OPERATIONS TO UPDATE data 
         Each append has the following form :
         data.append(new DataObject(someLatitude, someLongitude))
        */
        this->rootContext()->setContextProperty("myModel", QVariant::fromValue(data));
    }
    
    class DataObject : public QObject
    {
        Q_OBJECT
    
        Q_PROPERTY(double lat READ lat WRITE setLat)
        Q_PROPERTY(double lon READ lon WRITE setLon)
    
    
    public:
        explicit DataObject(QObject *parent = nullptr);
        DataObject(double latitude, double longitude, QObject *parent = 
    nullptr);
    
        void setLat(double latitude);
        void setLon(double longitude);
        double lat() const;
        double lon() const;
    
        double d_lat;
        double d_lon;
    }
    
    import QtQuick 2.12
    import QtLocation 5.12
    import QtPositioning 5.12
    
    Item {
        width: 1200
        height: 1000
        visible: true
    
        Plugin {
            id: osmPlugin
            name: "osm"
        }
    
        Map {
            id: map
            anchors.fill: parent
            plugin: osmPlugin
            center: QtPositioning.coordinate(45.782074, 4.871263)
            zoomLevel: 5
    
            MapItemView {
                model : myModel
                delegate: MapQuickItem {
                    coordinate: model.position
                    sourceItem: Image {
                        id: image_1
                        source: "http://maps.gstatic.com/mapfiles/ridefinder-images/mm_20_red.png"
                    }
                    anchorPoint.x: image_1.width / 2
                    anchorPoint.y: image_1.height / 2
                }
            }
        }
    }