Orte (QML)

Das Places-Beispiel zeigt, wie man nach Places sucht und auf zugehörige Inhalte zugreift.

Das Places-Beispiel demonstriert, wie man nach Places sucht. Es zeigt insbesondere, wie weitere Informationen wie Bewertungen, Bilder und verwandte Inhalte abgerufen werden können.

Ausführen des Beispiels

Zum Ausführen des Beispiels von Qt Creatorzu starten, öffnen Sie den Modus Welcome und wählen Sie das Beispiel aus Examples. Weitere Informationen finden Sie unter Erstellen und Ausführen eines Beispiels.

Das Beispiel kann mit jedem der verfügbaren Geodienste-Plugins verwendet werden. Einige Plugins benötigen jedoch zusätzliche plugin parameters, um korrekt zu funktionieren. Plugin parameters kann in der Befehlszeile mit dem Argument --plugin übergeben werden, das die Form hat:

--plugin.<parameter name> <parameter value>

Welche Plugin-Parameter sie unterstützen, entnehmen Sie bitte der Dokumentation der einzelnen Geodienste-Plugins. Das in diesem Beispiel verwendete Standard-Plugin ist Qt Location Open Street Map Plugin, das keine Parameter benötigt.

Übersicht

Das Places-Beispiel zeigt ein Anwendungsfenster, in dem eine Karte angezeigt wird. Am oberen Rand des Fensters befindet sich ein Suchfeld, das zur Eingabe einer Suchanfrage nach einem Ort dient. Um nach einem Ort zu suchen, geben Sie einen Suchbegriff in das Textfeld ein und klicken Sie auf das Lupensymbol. Um einen Ort nach Kategorie zu suchen, klicken Sie auf das Kategoriesymbol, um die Liste der verfügbaren Kategorien anzuzeigen, und wählen Sie die gewünschte Kategorie aus. Bei der Ortssuche wird nach Orten gesucht, die sich in der Nähe des auf der Karte angezeigten aktuellen Standorts befinden.

Bei einigen Plugins liefert das Suchfeld Vorschläge für Suchbegriffe, wenn drei oder mehr Zeichen eingegeben werden. Wenn Sie einen der Vorschläge auswählen, wird eine Ortssuche mit dem ausgewählten Suchtext durchgeführt.

Wenn Sie auf ein Suchergebnis klicken, werden Details über den Ort angezeigt. Wenn ein Ort über umfangreiche Inhalte (Leitartikel, Bewertungen und Bilder) verfügt, können diese über die Schaltflächen auf der Detailseite aufgerufen werden. Um ähnliche Orte zu finden, klicken Sie auf die Schaltfläche "Ähnliche Orte finden".

Der Geodienstanbieter kann über das Menü "Anbieter" geändert werden.

Anzeige von Kategorien

Bevor eine Suche nach Kategorien durchgeführt werden kann, muss die Liste der verfügbaren Kategorien abgerufen werden. Dies wird durch die Erstellung einer CategoryModel erreicht.

CategoryModel {
    id: categoryModel
    hierarchical: true
}

Der Typ CategoryModel bietet ein Modell der verfügbaren Kategorien. Er kann entweder eine flache Liste oder ein hierarchisches Baummodell bereitstellen. In diesem Beispiel verwenden wir ein hierarchisches Baummodell, indem wir die Eigenschaft hierarchical auf true setzen. Die Eigenschaft plugin wird während der Installation des Beispiels festgelegt.

Als Nächstes erstellen wir eine ListView, um das Kategorienmodell anzuzeigen.

ListView {
    id: root
    property var categoryModel
    property var rootIndex

    signal searchCategory(var category)
    signal showSubcategories(var index)

    snapMode: ListView.SnapToItem

    model: DelegateModel {
        id: delegeteDataModel
        model: root.categoryModel
        rootIndex: root.rootIndex
        delegate: CategoryDelegate {
            width: ListView.view.width
            onSearchCategory: root.searchCategory(category);
            onShowSubcategories: root.showSubcategories(delegeteDataModel.modelIndex(index));
        }
    }
}

Da ein hierarchisches Modell verwendet wird, ist eine DelegateModel erforderlich, um Navigationsfunktionen bereitzustellen. Wenn ein flaches Listenmodell verwendet würde, könnte die Ansicht direkt die CategoryModel verwenden.

Die Eigenschaft rootIndex legt den Wurzelindex des DelegateModel fest. Kategorien werden durch das CategoryDelegate angezeigt, das zwei Signale bereitstellt. Das Signal onShowSubcategories () sendet das Signal showSubcategories() mit RootIndex auf den aktuellen Index, wodurch die Unterkategorien der ausgewählten Kategorie angezeigt werden. Der onSearchCategory-Handler sendet das Signal searchCategory() mit einem Kategorieparameter, der angibt, welche spezifische Kategorie ausgewählt wurde.

Der CategoryDelegate zeigt den Kategorienamen an und gibt das Signal searchCategory() aus, wenn die Seite Label angeklickt wird:

Label {
    id: labelItem
    text: category.name
    anchors.left: icon.right
    anchors.right: parent.right
    anchors.verticalCenter: parent.verticalCenter
}

TapHandler {
    id: tapHanlder
    onTapped: {
        if (model.hasModelChildren) {
            root.showSubcategories()
        } else {
            root.searchCategory()
        }
    }
}

Präsentation von Suchvorschlägen

Der Typ PlaceSearchSuggestionModel wird verwendet, um vorgeschlagene Suchbegriffe auf der Grundlage eines teilweise eingegebenen Suchbegriffs abzurufen.

Eine neue Vorschlagssuche wird immer dann ausgelöst, wenn der eingegebene Suchbegriff geändert wird.

SearchBar {
    id: searchBar
    onSearchTextChanged: function (searchText) {
        if (searchText.length >= 3 && suggestionModel != null) {
            suggestionModel.searchTerm = searchText;
            suggestionModel.update();
        }
    }
}

Vorschläge werden nur abgefragt, wenn die Länge des Suchbegriffs drei oder mehr Zeichen beträgt.

Wenn sich der Status der PlaceSearchSuggestionModel ändert, werden Suchvorschläge angezeigt.

PlaceSearchSuggestionModel {
    id: suggestionModel
    searchArea: searchRegion

    onStatusChanged: {
        if (status == PlaceSearchSuggestionModel.Ready)
            stackView.showSuggestions()
    }
}

Das Hauptobjekt im Zustand "SuggestionsShown" ist die ListView, die die Suchvorschläge anzeigt.

ListView {
    id: suggestionView
    property var suggestionModel
    signal suggestionSelected(string text)

    model: suggestionModel
    delegate: Item {
        width: ListView.view.width
        height: label.height * 1.5
        Label {
            id: label
            text: suggestion
        }
        MouseArea {
            anchors.fill: parent
            onClicked: suggestionSelected(suggestion)
        }
    }
}

Ein Label Objekt wird als Delegierter verwendet, um den Vorschlagstext anzuzeigen. Ein Klick auf den vorgeschlagenen Suchbegriff aktualisiert den Suchbegriff und löst eine Ortssuche unter Verwendung des Suchvorschlags aus.

Suche nach Orten

Der Typ PlaceSearchModel wird für die Suche nach Orten verwendet.

PlaceSearchModel {
    id: placeSearchModel
    searchArea: searchRegion

    function searchForCategory(category) {
        searchTerm = "";
        categories = category;
        recommendationId = "";
        searchArea = searchRegion
        limit = -1;
        update();
    }

    function searchForText(text) {
        searchTerm = text;
        categories = null;
        recommendationId = "";
        searchArea = searchRegion
        limit = -1;
        update();
    }

    function searchForRecommendations(placeId) {
        searchTerm = "";
        categories = null;
        recommendationId = placeId;
        searchArea = null;
        limit = -1;
        update();
    }

    onStatusChanged: {
        switch (status) {
        case PlaceSearchModel.Ready:
            if (count > 0)
                stackView.showPlaces()
            else
                stackView.showMessage(qsTr("Search Place Error"),qsTr("Place not found !"))
            break;
        case PlaceSearchModel.Error:
            stackView.showMessage(qsTr("Search Place Error"),errorString())
            break;
        }
    }
}

Zunächst werden einige der Eigenschaften des Modells festgelegt, die zur Erstellung der Suchanfrage verwendet werden. Die Eigenschaft searchArea wird auf das Objekt searchRegion gesetzt, das ein geocircle mit einem Zentrum ist, das mit dem aktuellen, auf Map angezeigten Ort verbunden ist.

Schließlich definieren wir drei Hilfsfunktionen searchForCategory(), searchForText() und searchForRecommendations(), die entweder die Eigenschaften categories oder searchTerm oder recommendationId setzen und die Methode update() aufrufen, um die Ortssuche zu starten. Die Suchergebnisse werden in einem ListView angezeigt.

ListView {
    id: searchView

    property var placeSearchModel
    signal showPlaceDetails(var place, var distance)
    signal showMap()

    model: placeSearchModel
    delegate: SearchResultDelegate {
        width: ListView.view.width
        onShowPlaceDetails: function (place, distance) { searchView.showPlaceDetails(place, distance) }
        onSearchFor: function (query) { placeSearchModel.searchForText(query) }
    }

    footer: RowLayout {
        width: parent.width

        Button {
            text: qsTr("Previous")
            enabled: placeSearchModel.previousPagesAvailable
            onClicked: placeSearchModel.previousPage()
            Layout.alignment: Qt.AlignHCenter
        }

        Button {
            text: qsTr("Clear")
            onClicked: {
                placeSearchModel.reset()
                showMap()
            }
            Layout.alignment: Qt.AlignHCenter
        }

        Button {
            text: qsTr("Next")
            enabled: placeSearchModel.nextPagesAvailable
            onClicked: placeSearchModel.nextPage()
            Layout.alignment: Qt.AlignHCenter
        }
    }
}

Der Delegat, der in ListView verwendet wird, SearchResultDelegate, ist dafür ausgelegt, mehrere Suchergebnistypen über ein Loader Objekt zu behandeln. Für Ergebnisse vom Typ PlaceResult ist der Delegat:

Component {
    id: placeComponent
    Item {
        id: placeRoot
        width: root.width
        height: Math.max(icon.height, 3 * placeName.height)

        Rectangle {
            anchors.fill: parent
            color: "#44ffffff"
            visible: mouse.pressed
        }

        Rectangle {
            anchors.fill: parent
            color: "#dbffde"
            visible: model.sponsored !== undefined ? model.sponsored : false

            Label {
                text: qsTr("Sponsored result")
                horizontalAlignment: Text.AlignRight
                anchors.right: parent.right
                anchors.bottom: parent.bottom
                font.pixelSize: 8
                visible: model.sponsored !== undefined ? model.sponsored : false
            }
        }

        GridLayout {
            rows: 2
            columns: 2
            anchors.fill: parent
            anchors.leftMargin: 30
            flow: GridLayout.TopToBottom

            Image {
                // anchors.verticalCenter: parent.verticalCenter
                id:icon
                source: place.favorite ? Qt.resolvedUrl("../resources/star.png") : place.icon.url()
                Layout.rowSpan: 2
            }

            Label {
                id: placeName
                text: place.favorite ? place.favorite.name : place.name
                Layout.fillWidth: true
            }

            Label {
                id: distanceText
                font.italic: true
                text: Helper.formatDistance(distance)
                Layout.fillWidth: true
            }
        }

        Rectangle {
            anchors.left: parent.left
            anchors.right: parent.right
            anchors.margins: 15
            height: 1
            color: "#46a2da"
        }

        MouseArea {
            id: mouse
            anchors.fill: parent
            onClicked: {
                if (model.type === undefined || type === PlaceSearchModel.PlaceResult) {
                    if (!place.detailsFetched)
                        place.getDetails();
                    root.showPlaceDetails(model.place, model.distance);
                }
            }
        }
    }
}

Anzeige des Ortsinhalts

Orte können zusätzlichen Rich Content haben, einschließlich redaktioneller Beiträge, Bewertungen und Bilder. Der Zugriff auf Rich Content erfolgt über eine Reihe von Modellen. Inhaltsmodelle werden im Allgemeinen nicht direkt vom Anwendungsentwickler erstellt, sondern die Modelle werden aus den Eigenschaften editorialModel, reviewModel und imageModel des Typs Place bezogen.

ListView {
    id:view
    property Place place
    signal showEditorial(var editorial)
    model: place.editorialModel
    delegate: EditorialDelegate {
        width: ListView.view.width
        onShowEditorial: view.showEditorial(model)
    }
}

Beispielprojekt @ code.qt.io

© 2025 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.