Sur cette page

Lieux (QML)

L'exemple Lieux montre comment rechercher des lieux et accéder au contenu correspondant.

L'exemple Lieux montre comment rechercher des lieux. Il montre notamment comment récupérer des informations supplémentaires telles que des avis, des images et du contenu connexe.

Exécution de l'exemple

Pour exécuter l'exemple à partir de Qt Creatorouvrez le mode Welcome et sélectionnez l'exemple de Examples. Pour plus d'informations, voir Qt Creator: Tutoriel : Construire et exécuter.

L'exemple peut fonctionner avec tous les plugins de services géographiques disponibles. Toutefois, certains plugins peuvent nécessiter des éléments supplémentaires plugin parameters pour fonctionner correctement. Plugin parameters peut être transmis sur la ligne de commande à l'aide de l'argument --plugin, qui se présente sous la forme suivante :

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

Reportez-vous à la documentation de chacun des plugins de géoservices pour plus de détails sur les paramètres de plugin qu'ils prennent en charge. Le plugin par défaut utilisé dans cet exemple est Qt Location Open Street Map Plugin, qui ne nécessite aucun paramètre.

Vue d'ensemble

L'exemple Places présente une fenêtre d'application affichant une carte. En haut de la fenêtre se trouve un champ de recherche, qui permet de saisir une requête de recherche de lieu. Pour rechercher un lieu, saisissez un terme de recherche dans la zone de texte et cliquez sur l'icône de la loupe. Pour rechercher un lieu par catégorie, cliquez sur l'icône de catégorie pour afficher la liste des catégories disponibles et sélectionnez la catégorie souhaitée. La recherche de lieux portera sur les lieux situés à proximité de l'emplacement actuel indiqué sur la carte.

Pour certains plugins, la boîte de recherche propose des suggestions de termes de recherche lorsque trois caractères ou plus sont saisis. En sélectionnant l'une des suggestions, une recherche de lieu sera effectuée avec le texte de recherche sélectionné.

En cliquant sur un résultat de recherche, vous obtiendrez des informations détaillées sur le lieu en question. Si un lieu a un contenu riche (éditoriaux, critiques et images), il est possible d'y accéder à l'aide des boutons de la page des détails. Pour trouver des lieux similaires, cliquez sur le bouton "Trouver similaire".

Le fournisseur de services géographiques peut être modifié en accédant au menu "Fournisseur".

Affichage des catégories

Avant de pouvoir effectuer une recherche par catégorie, il faut récupérer la liste des catégories disponibles. Pour ce faire, il faut créer un site CategoryModel.

CategoryModel {
    id: categoryModel
    hierarchical: true
}

Le type CategoryModel fournit un modèle des catégories disponibles. Il peut fournir soit une liste plate, soit un modèle d'arbre hiérarchique. Dans cet exemple, nous utilisons un modèle d'arbre hiérarchique en fixant la propriété hierarchical à true. La propriété plugin est définie lors de l'intallation de l'exemple.

Ensuite, nous créons un site ListView pour afficher le modèle de catégorie.

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));
        }
    }
}

Étant donné qu'un modèle hiérarchique est utilisé, un DelegateModel est nécessaire pour fournir une fonctionnalité de navigation. Si un modèle de liste plate était utilisé, la vue pourrait utiliser directement le site CategoryModel.

La propriété rootIndex définit l'indice de la racine du site DelegateModel. Les catégories sont affichées par le CategoryDelegate, qui émet deux signaux. Le signal onShowSubcategories émet le signal showSubcategories() avec l'index racine à l'index actuel, ce qui entraîne l'affichage des sous-catégories de la catégorie sélectionnée. Le gestionnaire onSearchCategory émet le signal searchCategory() avec un paramètre de catégorie indiquant quelle catégorie spécifique a été choisie.

Le délégué de catégorie affiche le nom de la catégorie et émet le signal searchCategory() lorsque l'on clique sur le site Label:

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 des suggestions de recherche

Le type PlaceSearchSuggestionModel est utilisé pour récupérer des suggestions de recherche basées sur un terme de recherche partiellement saisi.

Une nouvelle recherche de suggestions est déclenchée chaque fois que le terme de recherche saisi est modifié.

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

Les suggestions ne sont recherchées que si la longueur du terme de recherche est de trois caractères ou plus.

Lorsque l'état du site PlaceSearchSuggestionModel change, les suggestions de recherche s'affichent.

PlaceSearchSuggestionModel {
    id: suggestionModel
    searchArea: searchRegion

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

L'objet principal dans l'état "SuggestionsShown" est le site ListView qui affiche les suggestions de recherche.

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)
        }
    }
}

Un objet Label est utilisé comme délégué pour afficher le texte de la suggestion. Le fait de cliquer sur le terme de recherche suggéré met à jour le terme de recherche et déclenche une recherche de lieu à l'aide de la suggestion de recherche.

Recherche de lieux

Le type PlaceSearchModel est utilisé pour rechercher des lieux.

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;
        }
    }
}

Tout d'abord, certaines propriétés du modèle sont définies, qui seront utilisées pour former la demande de recherche. La propriété searchArea est attribuée à l'objet searchRegion, qui est un geoCircle dont le centre est lié à l'emplacement actuel affiché sur le site Map.

Enfin, nous définissons trois fonctions d'aide searchForCategory(), searchForText() et searchForRecommendations() qui définissent les propriétés categories, searchTerm ou recommendationId et invoquent la méthode update() pour lancer la recherche de lieu. Les résultats de la recherche sont affichés dans une fenêtre ListView.

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
        }
    }
}

Le délégué utilisé dans ListView, SearchResultDelegate, est conçu pour gérer plusieurs types de résultats de recherche via un objet Loader. Pour les résultats de type PlaceResult, le délégué est :

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);
                }
            }
        }
    }
}

Affichage du contenu du lieu

Les lieux peuvent avoir un contenu riche supplémentaire, y compris des éditoriaux, des critiques et des images. L'accès au contenu riche se fait par l'intermédiaire d'un ensemble de modèles. Les modèles de contenu ne sont généralement pas créés directement par le développeur de l'application, mais sont obtenus à partir des propriétés editorialModel, reviewModel et imageModel du type Place.

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

Exemple de projet @ code.qt.io

© 2026 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.