QML Map with many items takes a long time to shut down



  • I am currently working on a small test application which uses QML Map to display a collection of paths. Each path is a list of coordinates. For each path, I create a MapPolyline with the coordinates as its path property, and then for each coordinate on the path, I create a MapQuickItem with that coordinate as its coordinate property. I am currently rendering 500 paths each containing 100 coordinates. The application starts up reasonably quickly but does not ever seem to finish shutting down on close. I am wondering if my approach is somehow unreasonably inefficient.

    mymap.qml:

    import QtQuick 2.0
    import QtPositioning 5.6
    import QtLocation 5.6
    import com.plexsys.fpscounter 1.0
    
    Map {
      id: myMap
    
      zoomLevel: 4
      center { latitude: 0; longitude: 0 }
    
      Plugin {
        id: myPlugin
        name: "itemsoverlay"
      }
    
      plugin: myPlugin
    
      MapPolyline {
        id: primeMeridian
        line.width: 3
        line.color: "green"
        path: [
          { latitude: -90, longitude: 0 },
          { latitude: 0, longitude: 0 },
          { latitude: 90, longitude: 0}
        ]
      }
    
      MapPolyline {
        id: equator
        line.width: 3
        line.color: "green"
        path: [
          { latitude: 0, longitude: -180 },
          { latitude: 0, longitude: -90 },
          { latitude: 0, longitude: 0 },
          { latitude: 0, longitude: 90 },
          { latitude: 0, longitude: 180 },
        ]
      }
    
      FpsCounter {
        id: fps_text
        x: 0
        y: 0
        z: parent.z + 1
        width: 50
        height: 25
        Text {
          anchors.centerIn: parent
          text: fps_text.fps.toFixed(2)
        }
      }
    
      Repeater {
        model: randomPathModel
    
        MapPolyline {
          line.width: 2
          line.color: "blue"
          path: randomPath.points
          Component.onCompleted: {
            myMap.addMapItem(this)
          }
        }
      }
    
      Repeater {
        model: randomPathModel
    
        Repeater {
          model: randomPath
    
          MapQuickItem {
            coordinate: randomPoint
            sourceItem: Rectangle {
              width: 16
              height: 16
              color: "red"
            }
            anchorPoint.x: sourceItem.width / 2
            anchorPoint.y: sourceItem.height / 2
            Component.onCompleted: {
              myMap.addMapItem(this)
            }
          }
        }
      }
    }
    

    QMLMapTester.cpp:

    #include <QtCore/QUrl>
    
    #include <QtWidgets/QApplication>
    #include <QtWidgets/QMainWindow>
    #include <QtWidgets/QHBoxLayout>
    
    #include <QtQuick/QQuickView>
    
    #include <QtQml/QQmlContext>
    
    #include "RandomPathModel.h"
    #include "FpsCounter.h"
    
    ////////////////////////////////////////////////////////////////////////////////
    
    class MyMainWindow : public QMainWindow
    {
    public:
      MyMainWindow(QWidget* parent = nullptr) : QMainWindow(parent)
      {
        QWidget* mainWidget = new QWidget(this);
        setCentralWidget(mainWidget);
        QHBoxLayout* layout = new QHBoxLayout(mainWidget);
    
        m_view = new QQuickView;
        m_view->setResizeMode(QQuickView::SizeRootObjectToView);
        
        QWidget* container = QWidget::createWindowContainer(m_view, this);
        layout->addWidget(container);
      }
    
      QQuickView* getView() { return m_view; }
    
    private:
      QQuickView* m_view;
    };
    
    ////////////////////////////////////////////////////////////////////////////////
    
    int main(int argc, char** argv)
    {
      qmlRegisterType<FpsCounter>("com.plexsys.fpscounter", 1, 0, "FpsCounter");
    
      QApplication app(argc, argv);
      
      MyMainWindow mainWindow;
    
      RandomPathModel rpm;
      rpm.addPaths(500, 100);
    
      QQuickView* view = mainWindow.getView();
      QQmlContext* context = view->rootContext();
      context->setContextProperty("randomPathModel", &rpm);
      view->setSource(QUrl("mymap.qml"));
    
      mainWindow.show();
    
      return app.exec();
    }
    

    RandomPathModel.h:

    #ifndef _QMLMAPTESTER_RANDOMPATHMODEL_H
    #define _QMLMAPTESTER_RANDOMPATHMODEL_H
    ////////////////////////////////////////////////////////////////////////////////
    
    #include "RandomPointModel.h"
    #include <QtCore/QSharedPointer>
    
    ////////////////////////////////////////////////////////////////////////////////
    
    class RandomPathModel : public QAbstractListModel
    {
      Q_OBJECT
    
    public:
      RandomPathModel(QObject* parent = nullptr);
      ~RandomPathModel();
    
      Q_PROPERTY(int length READ length CONSTANT)
    
      enum Roles
      {
        PathRole = Qt::UserRole + 1
      };
    
      int rowCount(const QModelIndex& parent) const override;
    
      int length() const;
    
      QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
    
      void addPaths(int iNumPaths, int iNumPoints);
    
    protected:
      QHash<int, QByteArray> roleNames() const override;
    
    private:
      typedef QSharedPointer<RandomPointModel> RandomPointModelSharedPointer;
      typedef QList<RandomPointModelSharedPointer> PathList;
      PathList m_paths;
    };
    
    ////////////////////////////////////////////////////////////////////////////////
    #endif // _QMLMAPTESTER_RANDOMPATHMODEL_H
    

    RandomPointModel.h:

    #ifndef _QMLMAPTESTER_RANDOMPOINTMODEL_H
    #define _QMLMAPTESTER_RANDOMPOINTMODEL_H
    ////////////////////////////////////////////////////////////////////////////////
    
    #include <QtCore/QAbstractListModel>
    #include <QtCore/QList>
    #include <QtCore/QVariantList>
    #include <QtPositioning/QGeoCoordinate>
    
    ////////////////////////////////////////////////////////////////////////////////
    
    class RandomPointModel : public QAbstractListModel
    {
      Q_OBJECT
    
    public:
      RandomPointModel(QObject* parent = nullptr);
      ~RandomPointModel();
    
      enum Roles
      {
        PointRole = Qt::UserRole + 1
      };
    
      int rowCount(const QModelIndex& parent) const override;
    
      QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
    
      void addPoints(int iNumPoints);
    
      Q_PROPERTY(QVariantList points READ points NOTIFY pointsChanged);
    
      const QVariantList& points() const;
    
    signals:
      void pointsChanged(const QVariantList&);
    
    protected:
      QHash<int, QByteArray> roleNames() const override;
    
    private:
      QVariantList m_points;
    };
    
    ////////////////////////////////////////////////////////////////////////////////
    #endif // _QMLMAPTESTER_RANDOMPOINTMODEL_H
    

    The model implementations are fairly obvious but I can include them if they matter.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.