Places (QML)

Placesの例では、Placesを検索し、関連するコンテンツにアクセスする方法を示します。

Placesの例では、Placesを検索する方法を示します。特に、レビューや画像、関連するコンテンツなどの情報を取得する方法を示しています。

例の実行

から例を実行するには Qt Creatorからサンプルを実行するには、Welcome モードを開き、Examples からサンプルを選択します。詳細については、Building and Running an Exampleを参照してください。

このサンプルは、利用可能なジオサービスプラグインのどれでも動作します。ただし、プラグインによっては、正しく機能するためにplugin parameters を追加する必要があります。Plugin parameters は、--plugin 引数を使用してコマンドラインで渡すことができます。 引数は次のような形式をとります:

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

ジオサービスプラグインがサポートするプラグインパラメータの詳細については、各ジオサービスプラグインのドキュメントを参照してください。この例で使用するデフォルトのプラグインはQt Location Open Street Map Plugin で、パラメータを必要としない。

概要

Placesの例では、地図を表示するアプリケーションウィンドウが表示されます。ウィンドウの上部には検索ボックスがあり、場所の検索クエリを入力するのに使用します。場所を検索するには、テキストボックスに検索語を入力し、虫眼鏡アイコンをクリックします。カテゴリー別に場所を検索するには、カテゴリーアイコンをクリックして利用可能なカテゴリーのリストを表示し、希望のカテゴリーを選択します。場所の検索クエリは、地図上に表示されている現在地の近くにある場所を検索します。

一部のプラグインでは、3文字以上入力すると、検索ボックスに検索語の候補が表示されます。候補の1つを選択すると、選択された検索テキストで場所検索が実行されます。

検索結果をクリックすると、その場所の詳細が表示されます。リッチコンテンツ(論説、レビュー、画像)がある場合は、詳細ページのボタンからアクセスできます。類似の場所を検索するには、「類似の場所を検索」ボタンをクリックしてください。

ジオサービスプロバイダーは "プロバイダー "メニューで変更できます。

カテゴリーの表示

カテゴリーによる検索を実行する前に、利用可能なカテゴリーのリストを取得する必要があります。このためには、CategoryModel

CategoryModel {
    id: categoryModel
    hierarchical: true
}

CategoryModel タイプは、利用可能なカテゴリのモデルを提供する。これは、フラット・リストまたは階層ツリー・モデルのいずれかを提供できます。この例では、hierarchical プロパティをtrue に設定することで、階層ツリー・モデルを使用します。plugin プロパティは、例のイン タライズ時に設定されます。

次に、カテゴリ・モデルを表示するListView を作成します。

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

階層モデルを使用しているため、ナビゲーション機能を提供するためにDelegateModel 。もしフラットリストモデルが使われていれば、ビューはCategoryModel を直接使うことができます。

rootIndexプロパティは、DelegateModel のルートインデックスを設定します。カテゴリーは、CategoryDelegateによって表示され、2つのシグナルを提供します。onShowSubcategoriesはshowSubcategories()シグナルを発信し、ルート・インデックスを現在のインデックスに設定します。onSearchCategoryハンドラは、どの特定のカテゴリが選択されたかを示すcategoryパラメータを持つsearchCategory()シグナルを発する。

CategoryDelegateはLabel がクリックされると、カテゴリー名を表示し、searchCategory()シグナルを発する:

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

検索候補の提示

PlaceSearchSuggestionModel 型は部分的に入力された検索語に基づいて検索語の候補を取得するために使われます。

入力された検索用語が変更されるたびに、新しいサジェスト検索がトリガーされます。

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

サジェスト検索は、検索語の長さが3文字以上の場合にのみ行われます。

PlaceSearchSuggestionModel のステータスが変更されると、検索候補が表示されます。

PlaceSearchSuggestionModel {
    id: suggestionModel
    searchArea: searchRegion

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

SuggestionsShown」状態のメイン・オブジェクトは、検索候補を表示するListView

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

Label オブジェクトがサジェストテキストを表示するデリゲートとして使用されます。サジェストされた検索語句をクリックすると、検索語句が更新され、検索サジェストを使用した場所検索がトリガーされます。

場所の検索

PlaceSearchModel 、場所の検索に使用されます。

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

まず、モデルのいくつかのプロパティが設定され、検索リクエストを形成するために使用される。searchArea プロパティは、searchRegionオブジェクトに設定される。searchRegionオブジェクトは、Map に表示されている現在地とリンクしている中心を持つgeocircle である。

最後に、searchForCategory()searchForText()searchForRecommendations()の3つのヘルパー関数を定義し、categoriessearchTermrecommendationId のいずれかのプロパティを設定し、update()メソッドを呼び出して場所の検索を開始する。検索結果は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
        }
    }
}

ListView で使用されるデリゲートSearchResultDelegate は、Loader オブジェクトを介して複数の検索結果タイプを扱うように設計されています。PlaceResult型の結果に対して、デリゲートは次のようになります:

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

場所の内容の表示

プレイスには、論説、レビュー、画像などのリッチコンテンツを追加することができます。リッチコンテンツは、一連のモデルを介してアクセスされます。コンテンツモデルは通常、アプリケーション開発者が直接作成するのではなく、Place 型のeditorialModelreviewModelimageModel プロパティから取得します。

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

プロジェクト例 @ 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.