Taro3

View on GitHub

カスタムInputDialogから新しいアルバムを作成する

AlbumListPageには表示するためのデータが必要です。次のステップは、新しいアルバムを追加できるようにすることです。これを行うには、どこかの時点で QML から AlbumModel 関数を呼び出して、この新しいアルバムを追加する必要があります。UIを構築する前に、gallery-coreに小さな修正を加えなければなりません。

QML には既に AlbumModel 関数が用意されています。しかし、QML コードから AlbumModel::addAlbum(const Album& album) を直接呼び出すことはできません。QML エンジンはこの関数を認識せず、エラー TypeError をスローします。オブジェクト AlbumModel(…) のプロパティ ‘addAlbum’ は関数ではありません。これは、目的の関数を Q_INVOKABLE マクロで装飾するだけで修正できます(PictureModel::setAlbumId() で行ったように)。

しかし、ここでもう一つ問題があります。Album は C++ のクラスですが、QML では認識されていません。QML で Album に完全にアクセスできるようにするには、クラスに重要な変更を加えなければなりません。

クラスがQMLで大きく操作されている場合、これらの変更は完全に合理的です。私たちの使用例は非常に限定されています。私たちは新しいアルバムを作成したいだけです。アプリケーション全体を通して、我々はアルバムデータを表示するためにネイティブのModel/View APIに依存し、Albumに特化したものは何も使用されません。

これらの理由から、単純に AlbumModel にラッパー関数を追加します。

// In AlbumModel.h
...
QModelIndex addAlbum(const Album& album);
Q_INVOKABLE void addAlbumFromName(const QString& name);
...

// In AlbumModel.cpp
void AlbumModel::addAlbumFromName(const QString& name)
{
    addAlbum(Album(name));
}

これで、gallery-mobileプロジェクトのUIに戻ることができます。QMLのDialogを使ってこのアルバムを追加します。QtQuick は、ダイアログの様々なデフォルト実装を提供しています。

このリストの中に InputDialog があると思っていたでしょう (第 4 章「デスクトップ UI を制覇する」で QInputDialog ウィジェットを使用したので) が、Qt Quick にはありません。新しいQMLファイル(Qt Quick 2)を作成し、InputDialog.qmlという名前を付けます。内容は以下のようになるはずです。

import QtQuick 2.6
import QtQuick.Layouts 1.3
import Qt.labs.controls 1.0
import QtQuick.Dialogs 1.2
import QtQuick.Window 2.2
import "."

Dialog {
    property string label: "New item"
    property string hint: ""
    property alias editText : editTextItem

    standardButtons: StandardButton.Ok | StandardButton.Cancel
    onVisibleChanged: {
        editTextItem.focus = true
        editTextItem.selectAll()
    }
    onButtonClicked: {
        Qt.inputMethod.hide();
    }

    Rectangle {
        implicitWidth: parent.width
        implicitHeight: 100

        ColumnLayout {
            Text {
                id: labelItem
                text: label
                color: Style.text
            }

            TextInput {
                id: editTextItem
                inputMethodHints: Qt.ImhPreferUppercase
                text: hint
                color: Style.text
            }
        }
    }
}

このカスタムInputDialogでは、汎用のQt Quick Dialogを取り、ID editTextItemで参照されるTextInputアイテムを含むように変更します。また、期待される入力を記述するために、editTextItemのすぐ上にlabelItemを追加しました。このダイアログにはいくつかの注意点があります。

まず、このダイアログは汎用的なものにしたいので、設定可能でなければなりません。呼び出し元は、特定のデータを表示するためのパラメータを提供できるようにしなければなりません。これは Dialog 要素の先頭にある三つのプロパティで行います。

また、Dialog要素を設定することで、プラットフォームボタンを自動的に使用して、StandardButtonsを使用してダイアログの検証やキャンセルを行うようにしています。StandardButton。 Ok | StandardButton.Cancel構文です。

最後に、ダイアログをもう少しユーザーフレンドリーにするために、editTextItemはDialog要素が表示され、テキストが選択されたときにフォーカスを持っています。これら2つのステップは onVisibleChanged() コールバック関数で行われます。ダイアログが非表示になった場合(つまり、OkやCancelがクリックされた場合)、Qt.InputMethod.hide()を使って仮想キーボードを非表示にしています。

これでInputDialogが使えるようになりました! AlbumListPage.qmlを開き、以下のように修正します。

PageTheme {

    toolbarTitle: "Albums"
    toolbarButtons: ToolButton {
        background: Image {
            source: "qrc:/res/icons/album-add.svg"
        }
        onClicked: {
            newAlbumDialog.open()
        }
    }

    InputDialog {
        id: newAlbumDialog
        title: "New album"
        label: "Album name:"
        hint: "My Album"

        onAccepted: {
            albumModel.addAlbumFromName(editText.text)
        }
    }

PageTheme 要素の中に newAlbumDialog という ID の InputDialog を追加します。すべてのカスタムプロパティを定義します。title, label, hintです。ユーザーが Ok ボタンをクリックすると、onAccepted() 関数が呼び出されます。ここでは、入力されたテキストで AlbumModel 要素内のラッパー関数 addAlbumFromName() を呼び出すだけです。

このDialog要素はデフォルトでは表示されていないので、 toolbarButtonsにToolButtonを追加して開きます。このToolButtonは、PageTheme.qmlファイルで指定したように、ヘッダーの右端に追加されます。モバイルの標準に合わせるために、ボタンの中にはテキストではなくカスタムアイコンを使用しています。

ここでは、qrc:/res/icons/album-add.svgという構文で.qrcファイルに保存されている画像を参照することができることがわかります。スケーラブルなアイコンを持つためにSVGファイルを使用していますが、gallery-mobileアプリケーションのために独自のアイコンを使用するのは自由です。

ユーザーがツールボタンをクリックすると、onClicked() 関数が呼び出され、そこで newAlbumDialog が開きます。参照デバイスである Nexus 5X では、このようになっています。

image

ユーザーがOKボタンをクリックすると、全体のModel/Viewパイプラインが動作を開始します。この新しいアルバムは永続化され、AlbumModel 要素は正しいシグナルを発して ListView, albumList, 自体をリフレッシュするように通知します。私たちは gallery-core のパワーを活用し始めています。エンジンコードのかなりの部分を書き換えることなく、デスクトップアプリケーションやモバイルアプリケーションで使用することができます。


戻る