qt-components-ubuntu を Gentoo Linux で動かしてみた
Blackberry 10 の Cascades で Qt が採用されたり、元 MeeGo の人たちが Jolla という会社を作って Seilfish というプラットフォームで Qt を使ったり、Digia が Qt 5 の Android、iOS、Windows 8 対応をコミットしたりと、2013年はさらに Qt は様々なところで活躍しそうな予感がします。
そんな中、Qt 5 を採用した Ubuntu for phones の発表がありました。
Qt 5 の QtQuick 2.0 でユーザーインターフェースができているだけあって、綺麗なデザインでスムーズに動作しているように見えます。
そんな中、
というつぶやきを見てしまったので、自分でも試してみることにしました。
ダウンロード
Launchpad の https://launchpad.net/~ui-toolkit/+archive/ppa/+packages でコードが公開されています。
ページ下部の Source にある「qt-components-ubuntu – 0.1.24~quantal1」をクリックすると様々な形式のダウンロードのリンクが表示されます。
.deb 形式のパッケージが一通りダウンロードできるようですが、Gentoo Linux 上で試したいので今回は「qt-components-ubuntu_0.1.24~quantal1.tar.gz (929.9 KiB)」というソースコードのアーカイブをダウンロード。
Ubuntu をお使いの方は http://blog.hermit4.info/2013/01/ubuntu-for-phone.html こちらを参考にするといいと思います。
ビルド
パッケージを展開すると trunk というディレクトリが現れるので、そこの下で
$ ~/org/qt-project/qt-5.0.0/5.0.0/gcc_64/bin/qmake $ nice make -j6
とするとビルドができます。
シャドウビルドは可能のようですが、インストールせずに実行することまでは考慮されてないので、簡単に試す場合はソースツリーのところでビルドする方がよさそうです。
デモの実行
launch_demos.sh を参考に、以下のコマンドで実行させてみました。
UITK_THEME_PATH=. ~/org/qt-project/qt-5.0.0/5.0.0/gcc_64/bin/qmlscene -I modules/ demos/PhoneComponentShowcase.qml &

実行すると上記のようなデモが動作します。Tabs というエレメントの動きが新鮮ですね。
ドキュメントは http://developer.ubuntu.com/api/ubuntu-12.10/qml/mobile/overview-ubuntu-sdk.html こちらです。
最後にメインのソースも記念に貼っておきます。デモなので綺麗なソースではないですが、上のスクリーンショットと比較して見ると分かりやすいと思います。
/*
 * Copyright 2012 Canonical Ltd.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation; version 3.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
import QtQuick 2.0
import Ubuntu.Components 0.1
import Ubuntu.Components.Popups 0.1
import Ubuntu.Components.ListItems 0.1 as ListItem
Rectangle {
    color: "lightgrey"
    width: units.gu(45)
    height: units.gu(80)
    Tabs {
        ItemStyle.class: "new-tabs"
        anchors.fill: parent
        Tab {
            title: "Components"
            page: Flickable {
                clip: true
                width: units.gu(45)
                height: units.gu(80)
                contentWidth: width
                contentHeight: background.height
                Rectangle {
                    id: background
                    width: parent.width
                    height: childrenRect.height
                    color: "#e6e6e6"
                    Column {
                        width: parent.width
                        height: childrenRect.height
                        ListItem.SingleControl {
                            control: Button {
                                anchors {
                                    margins: units.gu(1)
                                    fill: parent
                                }
                                text: i18n.tr("Button")
                            }
                        }
                        ListItem.Standard {
                            text: i18n.tr("Checkbox")
                            control: CheckBox { }
                        }
                        ListItem.Standard {
                            text: i18n.tr("Switch")
                            control: Switch { }
                        }
                        ListItem.Header { text: i18n.tr("Slider") }
                        ListItem.SingleControl {
                            control: Slider {
                                anchors {
                                    margins: units.gu(1)
                                    fill: parent
                                }
                                value: 50
                            }
                        }
                        ListItem.Empty {
                            highlightWhenPressed: false
                            Label {
                                anchors.left: parent.left
                                text: i18n.tr("Activity indicator")
                                anchors {
                                    verticalCenter: parent.verticalCenter
                                    margins: units.gu(1)
                                }
                            }
                            ActivityIndicator {
                                running: true
                                anchors {
                                    margins: units.gu(1)
                                    right: parent.right
                                    verticalCenter: parent.verticalCenter
                                }
                            }
                        }
                        ListItem.Header { text: i18n.tr("Progress bar") }
                        ListItem.Empty {
                            highlightWhenPressed: false
                            ProgressBar {
                                id: progress
                                anchors.centerIn: parent
                                value: progress.minimumValue
                                SequentialAnimation on value {
                                    loops: Animation.Infinite
                                    NumberAnimation {
                                        from: progress.minimumValue
                                        to: progress.maximumValue
                                        duration: 2000
                                    }
                                    PauseAnimation {duration: 1000}
                                    ScriptAction { script: progress.indeterminate = true; }
                                    PauseAnimation {duration: 2000}
                                    ScriptAction {
                                        script: {
                                            progress.indeterminate = false
                                            progress.value = progress.minimumValue
                                        }
                                    }
                                }
                            }
                        }
                        ListItem.Header {
                            text: "Old-style tabs"
                        }
                        ListItem.Empty {
                            height: units.gu(40)
                            highlightWhenPressed: false
                            Tabs {
                                anchors {
                                    fill: parent
                                    margins: units.gu(1)
                                }
                                Tab {
                                    title: i18n.tr("Tab") + " 1"
                                    page: Rectangle {
                                        anchors.fill: parent
                                        color: "#eeeeee"
                                        Label {
                                            anchors.centerIn: parent
                                            text: i18n.tr("This is the first tab.")
                                            color: "#757373"
                                        }
                                    }
                                }
                                Tab {
                                    iconSource: "call_icon.png"
                                    page: Rectangle {
                                        anchors.fill: parent
                                        color: "#e4e4e4"
                                        Label {
                                            anchors.centerIn: parent
                                            text: i18n.tr("This is the second tab.")
                                            color: "#757373"
                                        }
                                    }
                                }
                                Tab {
                                    title: i18n.tr("Tab") + " 3"
                                    iconSource: "call_icon.png"
                                    page: Qt.resolvedUrl("MyCustomPage.qml")
                                }
                            }
                        }
                        ListItem.Empty {
                            highlightWhenPressed: false
                            TextField {
                                anchors.centerIn: parent
                                placeholderText: i18n.tr("simple text field")
                            }
                        }
                    }
                }
            }
        }
        Tab {
            title: "Ubuntu shape"
            page: UbuntuShapes {
                showHeader: false
            }
        }
    }
}