为什么会出现“error: Expected token ';'”?

Why do I get "error: Expected token ';'"?

提问人:Babloo Kumar 提问时间:11/9/2023 最后编辑:Abderrahmene Rayene MihoubBabloo Kumar 更新时间:11/12/2023 访问量:46

问:

main.qml

import QtQuick 2.14
import QtQuick.Window 2.12
import QtQuick.Controls 2.12
import QtLocation 5.12
import QtPositioning 5.12
import OsmDataParser 1.0

ApplicationWindow {
    visible: true
    width: 800
    height: 600

    OsmDataParser {
        id: osmParser

        onOsmDataLoaded: {
            // Use the parsed coordinates to create map elements (e.g., markers)
            for (var i = 0; i < coordinates.length; i++) {
                var coordinate = coordinates[i];
                // Create MapQuickItem and assign it to a variable
                var marker = MapQuickItem {
                    coordinate: QtPositioning.coordinate(coordinate.latitude, coordinate.longitude)
                    sourceItem: Item {
                        width: 32
                        height: 32
                        Image {
                            source: "marker.png" // Your custom marker image
                        }
                    }
                };

                // Add the MapQuickItem to the map
                map.addMapItem(marker);
            }
        }
    }

    // Create a Map with OpenStreetMap as the map provider
    Map {
        id: map
        anchors.fill: parent
        plugin: Plugin { name: "osm" }
    }

    PositionSource {
        active: true
        onPositionChanged: {
            // Center the map on the user's location (optional)
            map.center = position.coordinate;
        }
    }

    Component.onCompleted: {
        // Load and parse the OSM XML data file
        osmParser.parseOsmXml("india_osm.xml"); // Replace with your XML file path
    }
}

main.cpp

#include <QtQml>
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include "qosmdataparser.h"

int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);

    QGuiApplication app(argc, argv);

    QQmlApplicationEngine engine;

    qmlRegisterType<OsmDataParser>("OsmDataParser", 1, 0, "OsmDataParser");

    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));

    return app.exec();
}

qosmdataparser.h

#ifndef OSMDATAPARSER_H
#define OSMDATAPARSER_H

#include <QObject>
#include <QQmlApplicationEngine>
#include <QFile>
#include <QXmlStreamReader>
#include <QGeoCoordinate>
#include <QList>

class OsmDataParser : public QObject
{
    Q_OBJECT

public:
    explicit OsmDataParser(QObject* parent = nullptr);

    Q_INVOKABLE void parseOsmXml(const QString& xmlFilePath);

signals:
    void osmDataLoaded(const QList<QGeoCoordinate>& coordinates);

private:
    QList<QGeoCoordinate> coordinateList;
};


#endif // OSMDATAPARSER_H

qosmdataparser.cpp

#include "qosmdataparser.h"

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

void OsmDataParser::parseOsmXml(const QString& xmlFilePath)
{
    QFile file(xmlFilePath);
    if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
    {
        // Handle file open error
        return;
    }

    QXmlStreamReader xmlReader(&file);

    while (!xmlReader.atEnd())
    {
        xmlReader.readNext();
        if (xmlReader.isStartElement() && xmlReader.name() == "node")
        {
            double lat = xmlReader.attributes().value("lat").toDouble();
            double lon = xmlReader.attributes().value("lon").toDouble();
            QGeoCoordinate coordinate(lat, lon);
            coordinateList.append(coordinate);
        }
    }

    if (xmlReader.hasError())
    {
        // Handle XML parsing error
        return;
    }

    emit osmDataLoaded(coordinateList);
}

错误:

/home/babloo/Qt_workspace/MapDemo/main.qml:21:错误:预期标记 ';“'

如何解决此问题?

QT QML QT5.12

评论


答:

2赞 JarMan 11/9/2023 #1

我认为这个错误在这里具有误导性。看起来您正在尝试在 javascript 代码中动态创建 QML 对象 (MapQuickItem) 的实例。但你做错了。参见Qt Docs:从JavaScript创建动态QML对象

我的建议是创建一个组件,然后用于生成实例,如下所示:createObject

Component {
    id: mapItem

    MapQuickItem {
        sourceItem: Item {
            width: 32
            height: 32
            Image {
                source: "marker.png" // Your custom marker image
            }
        }
    }
}

OsmDataParser {
    id: osmParser

    onOsmDataLoaded: {
        for (var i = 0; i < coordinates.length; i++) {
            var coordinate = coordinates[i];
            var marker = mapItem.createObject(map, { coordinate: QtPositioning.coordinate(coordinate.latitude, coordinate.longitude) }

            // Add the MapQuickItem to the map
            map.addMapItem(marker);
        }
    }
}

更新:

不过,您可能会发现 MapItemView 是一种更简单的地图填充方式。我不是这方面的专家,但它可能看起来像这样:

MapItemView {
    model: coordinates
    delegate: MapQuickItem {
        sourceItem: Item {
            width: 32
            height: 32
            coordinate: modelData
            Image {
                source: "marker.png" // Your custom marker image
            }
        }
    }
}

评论

0赞 GrecKo 11/10/2023
使用 MapItemView 会比手动创建对象更好(也更简单)。例如,如果多次加载数据,则示例不起作用。
0赞 JarMan 11/11/2023
是的,你很可能是对的。老实说,我没有使用映射 API 的经验。我只是指出 OP 试图创建对象的方式是错误的。不过,我会把它添加到我的答案中。