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

©2024 The Qt Company Ltd. 本書に含まれるドキュメントの著作権は、それぞれの所有者に帰属します。 ここで提供されるドキュメントは、Free Software Foundation が発行したGNU Free Documentation License version 1.3に基づいてライセンスされています。 Qtおよびそれぞれのロゴは、フィンランドおよびその他の国におけるThe Qt Company Ltd.の 商標です。その他すべての商標は、それぞれの所有者に帰属します。