Viadeo Twitter Google Bookmarks ! Facebook Digg del.icio.us MySpace Yahoo MyWeb Blinklist Netvouz Reddit Simpy StumbleUpon Bookmarks Windows Live Favorites 
Logo Documentation Qt ·  Page d'accueil  ·  Toutes les classes  ·  Classes principales  ·  Annotées  ·  Classes groupées  ·  Modules  ·  Fonctions  · 

Places (QML) Example

The Places example demonstrates how to search for Places and access related content.

Overview

The Places example presents an application window displaying a map. At the top of the window is a search box, which is used to enter a place search query. To search for a place enter a search term into the text box and click the magnifying glass icon. To search for a place by category, click the category icon to display the list of available categories and select the desired category. The place search query will be for places that are near the current location shown on the map.

The search box provides search term suggestions when three or more characters are entered. Selecting one of the suggestions will cause a place search to be performed with the selected search text.

Search results are available from the slide out tab on the left. Clicking on a search result will display details about the place. If a places has rich content (editorials, reviews and images), these can be accessed by the buttons on the details page. To find similar places click the "Find similar" button. If the current Geo service provider supports it, buttons to edit and remove a place will also be available.

The geo service provider can be changed by accessing the "Provider" menu at the bottom of the window. Depending on the features supported by the provider, the "New" menu allows creating new Places and Categories. To create a new place, select "Place" from the "New" menu and fill in the fields. Click "Go!" to save the place. To create a new category, select "Category" from the "New" menu and fill in the fields. Click "Go!" to save the category.

The Places example can work with any of the available geo services plugins. However, some plugins may require additional plugin parameters in order to function correctly. Plugin parameters can be passed on the command line using the --plugin argument, which takes the form:

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

Refer to the documentation for each of the geo services plugins for details on what plugin parameters they support. The Nokia services plugin supplied with Qt requires an app_id and token pair. See "Qt Location Nokia Plugin" for details.

Displaying Categories

Before search by category can be performed, the list of available categories needs to be retrieved. This is achieved by creating a CategoryModel.

 CategoryModel {
     id: categoryModel
     plugin: placesPlugin
     hierarchical: true
 }

The CategoryModel element provides a model of the available categories. It can provide either a flat list or a hierarchical tree model. In this example, we use a hierarchical tree model, by setting the hierarchical property to true. The plugin property is set to placesPlugin which is the identifier of the Plugin object used for place search throughout the example.

Next we create a view to display the category model.

 ListView {
     id: root

     property bool showSave: true
     property bool showRemove: true
     property bool showChildren: true

     signal categoryClicked(variant category)
     signal editClicked(variant category)

     header: IconButton {
         source: "../../resources/left.png"
         pressedSource: "../../resources/left_pressed.png"
         onClicked: categoryListModel.rootIndex = categoryListModel.parentModelIndex()
     }

     model: VisualDataModel {
         id: categoryListModel
         model: categoryModel
         delegate: CategoryDelegate {
             id: categoryDelegate

             showSave: root.showSave
             showRemove: root.showRemove
             showChildren: root.showChildren

             onClicked: root.categoryClicked(category);
             onArrowClicked: categoryListModel.rootIndex = categoryListModel.modelIndex(index)
             onCrossClicked: category.remove();
             onEditClicked: root.editClicked(category);
         }
     }
 }

Because a hierarchical model is being used, a VisualDataModel is needed to provide navigation functionality. If flat list model was being used the view could use the CategoryModel directly.

The view contains a header item that is used as a back button to navigate up the category tree. The onClicked handler sets the root index of the VisualDataModel to the parent of the current index. Categories are displayed by the CategoryDelegate, which provides four signals. The onArrowClicked handler sets the root index to the current index causing the sub categories of the selected category to be displayed. The onClicked handler emits the categoryClicked() signal with a category parameter indicating which specific category has been chosen. The onCrossClicked handler will invoke the categories remove() method. The onEditClicked handler invokes the editClicked() signal of the root item, this is used to notify which particular category is to be edited.

The CategoryDelegate displays the category name and emits the clicked signal when the text is clicked:

 Text {
     id: name

     anchors.left: icon.right
     anchors.verticalCenter: parent.verticalCenter
     anchors.right: parent.right

     verticalAlignment: Text.AlignVCenter

     text: category.name
     elide: Text.ElideRight
 }

 MouseArea {
     anchors.fill: parent
     onClicked: root.clicked()
 }

The CategoryDelegate also displays icons for editing, removing and displaying child categories. These icons are shown as desired when the showSave and showRemove and showChildren properties are set and only then in cases where the function is supported.

 IconButton {
     id: edit

     anchors.right: cross.left
     anchors.verticalCenter: parent.verticalCenter

     visible: (placesPlugin.name != "" ? placesPlugin.supportsPlaces(Plugin.SaveCategoryFeature) : false)
              && showSave

     source: "../../resources/pencil.png"
     hoveredSource: "../../resources/pencil_hovered.png"
     pressedSource: "../../resources/pencil_pressed.png"

     onClicked: root.editClicked()
 }

 IconButton {
     id: cross

     anchors.right: arrow.left
     anchors.verticalCenter: parent.verticalCenter
     visible: (placesPlugin.name != "" ? placesPlugin.supportsPlaces(Plugin.RemoveCategoryFeature) : false)
              && showRemove

     source: "../../resources/cross.png"
     hoveredSource: "../../resources/cross_hovered.png"
     pressedSource: "../../resources/cross_pressed.png"

     onClicked: root.crossClicked()
 }

 IconButton {
     id: arrow

     anchors.right: parent.right
     anchors.verticalCenter: parent.verticalCenter
     visible: model.hasModelChildren && showChildren

     source: "../../resources/right.png"
     pressedSource: "../../resources/right_pressed.png"

     onClicked: root.arrowClicked()
 }

Presenting Search Suggestions

The PlaceSearchSuggestionModel element is used to fetch suggested search terms based on a partially entered search term.

A new suggestion search is triggered whenever the entered search term is changed.

 onTextChanged: {
     if (searchRectangle.suggestionsEnabled) {
         if (text.length >= 3) {
             if (suggestionModel != null) {
                 suggestionModel.searchTerm = text;
                 suggestionModel.update();
             }
         } else {
             searchRectangle.state = "";
         }
     }
 }

The suggestionsEnabled property is used to temporarily disable search suggestions when a suggestion is selected (selecting it updates the search term text). Suggestions are only queried if the length of the search term is three or more characters, otherwise the search boxes state is reset.

When the status of the PlaceSearchSuggestionModel changes, the state of the search box is changed to display the search suggestions.

 PlaceSearchSuggestionModel {
     id: suggestionModel
     plugin: placesPlugin
     searchArea: plugin.name === "nokia_places_jsondb" ? null : placeSearchModel.searchArea

     onStatusChanged: {
         if (status == PlaceSearchSuggestionModel.Ready)
             searchRectangle.state = "SuggestionsShown";
     }
 }

The main element in the "SuggestionsShown" state is the ListView showing the search suggestions.

 ListView {
     id: suggestionView

     model: suggestionModel
     delegate: Text {
         text: suggestion

         width: parent.width

         MouseArea {
             anchors.fill: parent
             onClicked: {
                 suggestionsEnabled = false;
                 searchBox.text = suggestion;
                 suggestionsEnabled = true;
                 placeSearchModel.searchForText(suggestion);
                 searchRectangle.state = "";
             }
         }
     }
 }

A Text element is used as the delegate to display the suggestion text. Clicking on the suggested search term updates the search term and triggers a place search using the search suggestion.

Searching for Places

The PlaceSearchModel element is used to search for places.

 PlaceSearchModel {
     id: placeSearchModel

     plugin: placesPlugin
     maximumCorrections: 5
     searchArea: searchRegion

     function searchForCategory(category) {
         searchTerm = "";
         categories = category;
         limit = -1;
         offset = 0;
         update();
     }

     function searchForText(text) {
         searchTerm = text;
         categories = null;
         limit = -1;
         offset = 0;
         update();
     }

     function previousPage() {
         if (limit === -1)
             limit = count;
         offset = Math.max(0, offset - limit);
         update();
     }

     function nextPage() {
         if (limit === -1)
             limit = count;
         offset += limit;
         update();
     }

     onStatusChanged: {
         if (status === PlaceSearchModel.Ready)
             searchResultView.showSearchResults();
     }
 }

First some of the model's properties are set, which will be used to form the search request. In this example we want a maximum of five search term corrections to be returned in the result set, so the maximumCorrections property is set accordingly. The searchArea property is set to the searchRegion object which is a BoundingCircle with a center that is linked to the current location displayed on the Map.

Finally, we define two helper functions searchForCategory() and searchForText(), which set either the categories or searchTerm properties and invokes the execute() method to start the place search. The search results are displayed in a ListView.

 ListView {
     id: searchView

     anchors.fill: parent

     spacing: 20

     model: placeSearchModel
     delegate: SearchResultDelegate {
         onDisplayPlaceDetails: showPlaceDetails(data)
         onSearchFor: placeSearchModel.searchForText(query);
     }

     footer: Item {
         width: searchView.width
         height: childrenRect.height

         Button {
             text: qsTr("Previous")
             onClicked: placeSearchModel.previousPage()

             anchors.left: parent.left
         }

         Button {
             text: qsTr("Clear")
             onClicked: placeSearchModel.reset()

             anchors.horizontalCenter: parent.horizontalCenter
         }

         Button {
             text: qsTr("Next")
             onClicked: placeSearchModel.nextPage()

             anchors.right: parent.right
         }
     }
 }

The delegate used in the ListView, SearchResultDelegate, is designed to handle multiple search result types via a Loader element. For results of type PlaceResult the delegate is:

 Component {
     id: placeComponent

     Item {
         id: placeRoot

         height: childrenRect.height
         width: parent.width

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

         Column {
             width: parent.width

             Row {
                 Image {
                     visible: (place.favorite != null)
                     source: "../../resources/star.png"
                     height: placeName.height
                     fillMode: Image.PreserveAspectFit
                 }

                 Text { id: placeName; text: place.favorite ? place.favorite.name : place.name }
             }
             Text { id: distanceText; text: PlacesUtils.prettyDistance(distance); font.italic: true }
             Text {
                 text: qsTr("Sponsored result")
                 horizontalAlignment: Text.AlignRight
                 font.pixelSize: 8
                 width: parent.width
                 visible: model.sponsored !== undefined ? model.sponsored : false
             }
         }

         MouseArea {
             anchors.fill: parent

             onPressed: placeRoot.state = "Pressed"
             onReleased: placeRoot.state = ""
             onCanceled: placeRoot.state = ""

             onClicked: {
                 if (model.type === undefined || type === PlaceSearchModel.PlaceResult) {
                     if (!place.detailsFetched)
                         place.getDetails();

                     root.displayPlaceDetails({
                                              distance: model.distance,
                                              place: model.place,
                 });
                 }
             }
         }

         states: [
             State {
                 name: ""
             },
             State {
                 name: "Pressed"
                 PropertyChanges { target: placeName; color: "#1C94FC"}
                 PropertyChanges { target: distanceText; color: "#1C94FC"}
             }
         ]
     }
 }

Recommending Similar Places

The PlaceRecommendationModel is used to find similar places to a given place. The model should be set up similarly to the PlaceSearchModel. Here we use a BoundingCircle with a center that is linked to the current location displayed on the Map. The search area may be different if the map is panned between when the place search and the place recommendation search are performed.

 PlaceRecommendationModel {
     id: recommendationModel
     plugin: placesPlugin

     searchArea: searchRegion
 }

The place recommendation search is performed by setting the placeId property of the model and invoking the execute() method. The search results are displayed in a ListView.

 ListView {
     id: similarView

     anchors.fill: parent

     spacing: 5

     visible: !searchView.visible
     model: recommendationModel
     delegate: SearchResultDelegate {
         onDisplayPlaceDetails: showPlaceDetails(data)
     }
 }

We reuse the same delegate that was used for displaying the results of the place search.

Displaying Place Content

Places can have additional rich content, including editorials, reviews and images. Rich content is accessed via a set of models. Content models are generally not created directly by the application developer, instead models are obtained from the editorialModel, reviewModel and imageModel properties of the Place element.

 ListView {
     anchors.fill: parent

     model: place.editorialModel

     delegate: EditorialDelegate { }
 }

Place and Category Creation

Some backends may support creation and saving of new places and categories. Plugin support can be checked an run-time by testing the Plugin::supportedPlacesFeatures property for the Plugin::SavePlaceFeature and Plugin::SaveCategoryFeature flags.

To save a new place, first create a new Place object, using the Qt.createQmlObject() method. Assign the appropriate plugin and place properties and invoke the save() method.

         locationPlace.plugin = placesPlugin;

         locationPlace.name = dataFieldsModel.get(0).inputText;
         locationPlace.location.address.street = dataFieldsModel.get(1).inputText;
         locationPlace.location.address.district = dataFieldsModel.get(2).inputText;
         locationPlace.location.address.city = dataFieldsModel.get(3).inputText;
         locationPlace.location.address.county = dataFieldsModel.get(4).inputText;
         locationPlace.location.address.state = dataFieldsModel.get(5).inputText;
         locationPlace.location.address.countryCode = dataFieldsModel.get(6).inputText;
         locationPlace.location.address.country = dataFieldsModel.get(7).inputText;
         locationPlace.location.address.postalCode = dataFieldsModel.get(8).inputText;

         locationPlace.location.coordinate.latitude = parseFloat(dataFieldsModel.get(9).inputText);
         locationPlace.location.coordinate.longitude = parseFloat(dataFieldsModel.get(10).inputText);

         var phone = Qt.createQmlObject('import QtLocation 5.0; ContactDetail { }', locationPlace);
         phone.label = "Phone";
         phone.value = dataFieldsModel.get(11).inputText;
         locationPlace.contactDetails.phone = phone;

         var fax = Qt.createQmlObject('import QtLocation 5.0; ContactDetail { }', locationPlace);
         fax.label = "Fax";
         fax.value = dataFieldsModel.get(12).inputText;
         locationPlace.contactDetails.fax = fax;

         var email = Qt.createQmlObject('import QtLocation 5.0; ContactDetail { }', locationPlace);
         email.label = "Email";
         email.value = dataFieldsModel.get(13).inputText;
         locationPlace.contactDetails.email = email;

         var website = Qt.createQmlObject('import QtLocation 5.0; ContactDetail { }', locationPlace);
         website.label = "Website";
         website.value = dataFieldsModel.get(14).inputText;
         locationPlace.contactDetails.website = website;

         locationPlace.categories = __categories;
         locationPlace.statusChanged.connect(processStatus);
         locationPlace.save();

Category creation is similar:

 onGoButtonClicked: {
     console.log("Go clicked!");
     var modifiedCategory = category ? category : Qt.createQmlObject('import QtLocation 5.0; Category { }', page);
     modifiedCategory.plugin = placesPlugin;

     modifiedCategory.name = dialogModel.get(0).inputText;

     category = modifiedCategory;

     category.save();
 }

Support for place and category removal can be checked at run-time by using the Plugin::supportsPlaces method, passing in a Plugin::PlacesFeatures flag and getting back true if the feature is supported. For example one would invoke supportsPlaces(Plugin.RemovePlaceFeature) to check if the Plugin.RemovePlaceFeature is supported.

To remove a place, invoke its remove() method. To remove a category, invoke its remove() method.

Running the Example

The example detects which plugins are available and has an option to show them in the via the Provider button.

The JsonDb plugin in particular acts as a data store for user defined favorites which can be saved and removed. In order to use the JsonDb plugin however the JsonDb daemon must be running in the background.

 jsondb & //run jsondb daemon in the background

Files:

Cette page est une traduction d'une page de la documentation de Qt, écrite par Nokia Corporation and/or its subsidiary(-ies). Les éventuels problèmes résultant d'une mauvaise traduction ne sont pas imputables à Nokia. Qt 5.0-snapshot
Copyright © 2012 Developpez LLC. Tous droits réservés Developpez LLC. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon, vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts. Cette page est déposée à la SACD.
Vous avez déniché une erreur ? Un bug ? Une redirection cassée ? Ou tout autre problème, quel qu'il soit ? Ou bien vous désirez participer à ce projet de traduction ? N'hésitez pas à nous contacter ou par MP !
 
 
 
 
Partenaires

Hébergement Web