ラベル Qt の投稿を表示しています。 すべての投稿を表示
ラベル Qt の投稿を表示しています。 すべての投稿を表示

2021/07/24

SailfishOS向けアプリのビルド

久しぶりに書いているけど、ネタとしては単なる備忘録。

実に3年ぶりにQayttamatonを更新した。
結構仕事が忙しかったし、あと少しこれができたらなーと思うところはあったけど最低限のところは動いてくれていたし、時間ができたらやろうやろうと思いつつ3年が経ってしまっていた・・・

きっかけは1通のメール。
なんか使ってくれてるヒトが居るらしく、要約するとこんな話。
新しい端末を買ったんだけどアーキテクチャに合ったパッケージがない。自力でビルドしようと思ったんだけど、ソースの公開先が既に息してない。どっか別にソースを公開してる?あるいは、新しいアーキテクチャ(恐らくaarch64)に対応したパッケージ出す予定ある?
おー、そうかそうかなるほど。

ってことで、@kenya888さんにお願いして日本Qtユーザ会で公開してた頃のソースを引っ張り出してもらってgitlabに公開してみた。

さて、話はここで終わらない。
実はちょっと前に気がついていたんだけど、半年以上前から「ログインできない」っていう情報がストアのコメントにあったんだよね・・・
原因はUNTAPPがCAPTCHA認証を導入したこと。

QayttamatonからUNTAPPDへのログイン(ユーザ認証)はそれ用のWebSiteにアクセスして行うんだけど、従来はアプリ内からSilicaWebViewでサイトを開いてログインしてたんだよね。(だってその方が簡単だったんだもん・・・)

ところが、現状SilicaWebViewで表示したサイトだとCAPTCHA認証がうまく操作できない。
画像の選択まではできるんだけど、なぜか認証のボタンが押せない・・・
デスクトップ(Qt 5.11辺り)でWebViewを使って試した時には問題なく認証できるので、どうやらSilicaWebView固有の問題っぽい?

という訳で、認証の操作自体は外部ブラウザでやるように変更することにした・・・

が、はっきり言って何をどうしていいのか分からない。そもそもそこまでのプログラミングテクニックなんて持ってない。ということでGoogleさんにお尋ねしたところ、参考になりそうな情報が・・・
ぱっと見これだけ見ても何をどうすればと思ったりはしたけど、昔のTwitter4QMLのコードとかいろいろ動いてるものを参考にしてどうにかこうにか動くものができた。
まぁ、ブラウザでのログインが完了したらフォーカスをアプリに戻したいとか、いろいろ足りないところはあるんだけど、とりあえずログインはできるようになったから良しとしよう。(7/21現在、なんかうまくいかない事例があるっぽい・・・調査中)

ということで、とりあえずarmv7hl版およびi486版については2021/07/21付けでストアに公開されている。めでたい。

が、最後の難関。aarch64版をどうするかという話。
実はわりと最近、Xperia 10を(中古で)入手してXperia Xを導入してたもんだから、これでaarch64周りもいけるだろうと思っていたんだけど・・・
結論としては、このXperia 10、OSとしては残念ながらaarch64ではないっぽい・・・これを書いている時点では、正式にaarch64なOSになっているのはXperia 10 IIのみということらしい。

正直、実機がないとテストはできないけど、実機がなくてもパッケージはビルドできるはずなんだよね・・・ということでいろいろ情報探したところ、Jollaがリリースしてるドキュメントがあった。
こーゆードキュメント類がちゃんとしてるのがJollaのいいところだよね。
そんなわけで、下のような手順でビルドしてみた。
今回はVirtualBox環境(最近はビルド環境にDocker版がある)での実行。
# mkdir build
# cd build
# ~/SailfishOS/bin/sfdk tools list
sfdk: [I] Starting the build engine…
SailfishOS-4.1.0.24              sdk-provided,latest
├── SailfishOS-4.1.0.24-aarch64  sdk-provided,latest
├── SailfishOS-4.1.0.24-armv7hl  sdk-provided,latest
└── SailfishOS-4.1.0.24-i486     sdk-provided,latest
# ~/SailfishOS/bin/sfdk config target=SailfishOS-4.1.0.24-aarch64
# ~/SailfishOS/bin/sfdk qmake ../harbour-qayttamaton _ID="client_id" _SECRET="client_secret" _URL="redirect_url" _FS_ID="foursquare_client_id" _FS_SECRET="foursquare_client_secret" _FS_VERSION="########"
# ~/SailfishOS/bin/sfdk make
# ~/SailfishOS/bin/sfdk make-install
# ~/SailfishOS/bin/sfdk package
# ~/SailfishOS/bin/sfdk misc stop-vms
これで build/RPMS にパッケージ類が完成しているはず。

単にビルドするだけなら"~/SailfishOS/bin/sfdk build ../harbour-qayttamaton"だけで行けるんだけど、ソース的に公開される部分にclient idやcliento secretを直接入れずに済むようにしている関係でqmakeにオプションを渡す必要があるので、ちょこっと工程を分解。

上の手順だと「sfdk tools list」を叩いた時点でBuild Engine(mersdk)が動き出す(その後のBuild工程でも動いている必要がある)ので、"misc stop-vms"で停止させないと動きっぱなしになる気がするので、ちゃんと止めておく。
(もちろん事前にVBoxManagerとかで起動しておいて、別で止めてもOK)

これでパッケージ自体はできる。
同じ方法で作成したarmv7hl版、i486版がちゃんと動いているから、多分大丈夫だろう。
テストもしてないパッケージを投げるのもどうかとは思ったけど、とりあえず今日QAに投げてみた。これまでの例からも、JollaのQAはそれなりにちゃんとテストしてくれるから、テストしてもらっちゃおうっと・・・

ということで、QAの結果が出たら追記する予定。

#2021/08/20 追記
aarch64なパッケージ付きの更新申請がQAと通ったので、多分OKなはず。
ただし、aarch64な端末のストアからちゃんとaarch64なパッケージをインストールできるのかはわからない(端末持ってないからなぁ・・・)

2019/09/13

今年も「9月10日はQtの日」を開催

そもそも「日本Qtユーザー会の宴会部長」とは!?って話もあるんだけど(笑)

たぶん、2015年のQt Japan Summit 2015の終了後場所探して打ち上げしたのが飲み会幹事やった最初で、たしかその時に「今年の9月10日こそイベント(飲み会)やろう」という話をして、で、2015年9月10日から翌年9月10日が土曜日になったのを除いて飲み会を開催してる。(2016年は「Qt勉強会#39 @ Tokyo 」としてイベント開催された)
そして今年2019年も無事開催するに至った。

去年は参加できなかった @task_jp さんが今年は決意を引っさげて華麗に(?)登場して、今年もまぁいろいろなQt絡みの話で盛り上がった2時間だった。


そしてなんだかわからないけどとりあえず宴会部長は続投らしい(笑)
(もっとも、それ以外に何ができるのかと言われるとなにもできないんだけどね。マトモなコード書けないし(笑))

というワケで来年もきっとやるのでQtユーザー会入ってるヒトだけでなく、入ってないけどQtに興味あるよって人もぜひ参加しておくれ!

日本Qtユーザー会の未来はきっと明るい!
はりきる必要はないので、みんな楽しもう!

2017/12/15

今年もQt Advent Calendarに参加してみた。

というエントリを去年も書いた
Qt Advent Calendar 2017
2014年以来一応毎年投稿はしている。まぁ、いつもたいしたネタではないのだけれど・・・
【12日目】ントリビューションしてみたよ!
【14日目】日本Qtユーザー会WebSiteのコンテンツについて
今年はみんな忙しそうで後半戦に入った12/15現在のユニーク参加数は12人。去年は20人に参加してもらえたんだけど・・・一昨年並の15人は越えて欲しいなぁ。

来年も開催できたらまた12月12日にエントリする予定。
今年もまだあと4日ほど枠が空いてるから、みんなエントリしてね!

2016/12/12

今年もQt Advent Calendarに参加してみた。

今年もQt Advent Calendarに参加してみた。
Qt Advent Calendar 2016
2014年、2015年は記事をこのブログに書いてたんだけど、今回はQiitaの方に投稿してみた。
正直「俺得」でしかない内容だからどっちにしようか迷ったんだけどね。
Windows 10 MobileでQtQuickアプリを動かしてみる。Part-II
今年3月ぐらいに書いた記事の続きみたいなもんだけど、前回と比べると格段に開発し易くなってる。やっぱりQt Creatorから直接エミュレータなり実機にDeployできると楽ちんだよねー(笑)

実はもう一つネタを用意してたんだけど、うれしいことに投稿者が増えたので今年は複数投稿しなくてもカレンダーが埋まったっぽい(笑)
カレンダーが埋まるのはなんとかなる感じだから、来年は投稿者が20人を越えて欲しいなー(笑)

ちなみに3年連続で12月12日にエントリしている。
一応「1212」で『一歩ずつ前え』って意味でね ;-)
(永遠の初心者っていう話もあるけどww)

さて、来年も12月12日にエントリできるように、また1年ネタを仕込むとしますか。
今年エントリを見送ったQt Developerのみなさんも、来年は参加よろしく!!

2015/12/17

【一夜漬け】Twitter4QMLを使ってみようか。

この投稿は"Qt Advent Calendar 2015 - Qiita"の17日目(12/17分)の記事だ。

みんながんばって(何人かの人は複数エントリ書いて)つなげているQt Advent Calendar 2015、あと一日ぽっかり空いていたので、とりあえず急造で書いてみる。
まぁ、12日目の記事だって急造だったワケだし、正直おいらみたいなヘッポコにクオリティの高いテクニカルなエントリを求めること自体も間違っているワケなので(ぉぃ)、身の丈っぽいヤツでなんとか一日埋めてみようという試みだ。

Twitter4QMLとは
2014年のQtチャンピオンであるたすくさんが多分2011年ぐらいに作った、QML/QtQuickで使えるTwitterAPIのWrapper・・・なのかな。Android界隈だとTwitter4Jってのがあるけど、アレのQt版みたいな感じと言えばいいのか。


○使うための準備(Linux)
まずソースコードを取り寄せる。ソースは日本Qtユーザー会のgitサーバで公開してあるので、そこからgitコマンドで取り寄せよう。あとは、まぁ、Qt使いのみなさんにとってはお馴染みのコマンドじゃないかな。
$ git clone git://git.qt-users.jp/codereview/twitter4qml.git
$ mkdir build
$ cd build
$ qmake -r ../twitter4qml
$ make
$ sudo make install
基本、Qt5系で使うのかなと思うけど、確か(まだ)Qt4系でもビルドできたんじゃなかったかな。
Windowsとかであれば理音伊織(あやねいおり)大先生の「艦娘メモリーズ」のビルド方法の記載を参考にすればいいはず。とりあえずインストールしてしまえばQtQuick/QMLのコードから"import TwitterAPI 1.1"すれば一通りの機能が使える。

あと、多分、基本的にはQMLで使うのが正しいんだと思うけど、もちろんC++なコードからも使える。使えるんだけどおいらには使い方がよく分からない。なぜなら基本的にC++なコードを書くスキルがないからだ。
というワケでC++から使ってみたいっていうヒトも、多分理音伊織大先生の「艦娘メモリーズ」のコードとかが参考になったりすると思う。


○とりあえず使ってみる。
とりあえずいきなりタイムラインを表示するコードを書いてみる。
import QtQuick 2.3
import QtQuick.Window 2.2
import TwitterAPI 1.1

Window {
    visible: true

    width: 480
    height: 640

    OAuth {
        id: oauth
        consumer_key: 'hogehoge'
        consumer_secret: 'fugafuga'
        token: 'hogefuga'
        token_secret: 'fugahoge'
        user_id: 'xxxxxxxx'
        screen_name: 'zzzzzzzz'
    }

    StatusesHomeTimelineModel {
        id: model
    }

    ListView {
        id: view
        anchors.fill: parent
        model: model
        delegate: Rectangle {
            width: parent.width
            height: status_text.height < 64 ? 64 : status_text.height
            border.width: 1
            Row {
                anchors.fill: parent
                Image {
                    id: icon
                    width: 64
                    height: 64
                    source: model.user.profile_image_url
                }
                Column {
                    id: status_text
                    width: parent.width - 64
                    height: name.contentHeight + tweet.contentHeight
                    Text {
                        id: name
                        width: parent.width
                        text: "@%1".arg(model.user.screen_name)
                    }
                    Text {
                        id: tweet
                        width: parent.width
                        text: model.plain_text
                        wrapMode: Text.Wrap
                    }
                }
            }
        }
    }
}
簡単に見えるじゃん?
OAuth{}で認証情報渡して、StatusesHomeTimeline{}を定義しただけ。それだけでとりあえずタイムラインは取得できる。

StatusesHomeTimelineは見た通り"GET statuses/home_timeline"のAPIを叩くためのもので、他のエレメントも原則APIの名前をそのまま使っている。

例えば"GET statuses/mentions_timeline"でMentionのタイムラインを取得するのであればStatusesHomeTimeline{}をStatusesMentionsTimelineModel{}に変更すればいいって感じ。

もちろん、実際のクライアント作る時はもうちょい複雑な制御が必要(タイムラインの後進とか、過去のタイムラインを遡って取得するとか)だけど、その時も各APIで使うパラメータは基本そのままの名前でプロパティが定義してあるので、APIのドキュメントを読んでそのままコードに落とせる感じ。


○認証するには
Twitterの認証にはOAuthが必要なんだけど、これに対してOAuth{}ってのが用意されてる。
OAuth {
    id: oauth
    consumer_key: 'hogehoge'
    consumer_secret: 'fugafuga'
}
未認証状態だとoauth.stateが"0"になっている。多分、このステータスをトリガにして下の順番でコマンドを呼べば認証ができる。
  1. "oauth.state == 0"→oauth.request_token()を呼ぶと、デフォルトブラウザ経由でtwitter.comの認証画面が現れる。
  2. 認証して返ってきたpinをoauth.access_token(pin)の形で渡す。→oauth.statusに"2"がセットされる。
  3. "oauth.state == 2"→oauth.authorize()を呼ぶ。oauth.stateに"5"がセットされる。→認証完了
だいたいこんな感じだろうか。


○呟いてみる
最低限テキストを呟くコードはこうなる。
import QtQuick 2.3
import QtQuick.Controls 1.2
import TwitterAPI 1.1

ApplicationWindow {
    id: tweet

    Status { id: testStatus }

    Column {
        Text {
            text: oauth.screen_name
        }
        TextInput {
            id: tweet_text
            text: "Test"
        }
        Text {
            text: "OK"
            MouseArea {
                anchors.fill: parent
                onClicked: {
                    var parameter = {'status': tweet_text.text}
                    testStatus.statusesUpdate(parameter)
                }
            }
        }
    }

}
内部的には命名規則通り"POST statuses/update"にあたるStatusesUpdateが用意されてはいるんだけど、この辺りはクライアントからの取扱いを楽にするためにStatus{}というエレメントが用意されている。
ツイート関連のパラメータをリストにしてStatuses.statusesUpdate()に渡すんだけど、上のように"status"だけが設定されると"statuses/update"が、一緒に"media"を設定すると"statuses/update_with_media"が、Status内部で自動的に判定されて使用(ツイート)されるようになってる。


○という事で・・・
なんかダラダラとまとまりがなく、しかも文面は解りづらいっぽいんだけど、要はTwitter4QML便利だよって話になるのかな。

あと、Twitter4QML自体もそうだし、10日目のエントリ「Qtユーザ会のご紹介」のところでチラっと紹介されている"Silk"もそうなんだけど、これらはQtライブラリを活用して作られてるってこと。
もともとQtはGUIのためのフレームワーク(ってコトで合ってるよね?)なワケなんだけど、このGUIを支える部分のクラスにはGUIを使わないプログラムの開発においても便利なものが沢山含まれていることを示してる。

とゆーワケで、QtライブラリはGUIの分野以外でも活躍してる(できる)んだよという(カレンダーのエントリー的には)「釈迦に説法」っぽい一言を添えてヘッポコなエントリをクローズしたいと思うのだ。
時間がないのとか文章まとめるのが苦手とかで紹介しきれてないけど、どこかで余裕ができたらQMLのサンプルコードみたいなのをアップできるといいな。→できるのか?>おれ

2015/12/12

Jolla: 【一夜漬け】"QtPositioning"を使って現在地周辺地図を表示させてみた

この投稿は"Qt Advent Calendar 2015 - Qiita"の12日目(12/12分)の記事だ。

なんか他のメンバの記事のレベルが去年にも増して高くて、正直こんなネタの記事を混ぜていいもんか不安になるレベルだけど、逆に記事書くのを躊躇してたけどコレ見て「あぁ、こんなんで許されるんだ」と思ったヒトが居たら、ぜひ空いてる日にエントリして参戦して欲しい。Qtユーザ会宴会部長(名義)からのお願いだ(何

正直相変わらずQtの話ってよりJollaの話っなんだけど、まぁ気にしないで欲しい。

今年はコードを書くという面においてはほとんど何もアウトプットが出せていないのでギリギリまでネタに悩んだんだけど、とりあえず「一夜漬け」でQtPositioningを使ってJollaに現在地周辺の地図を表示させるという、ただそれだけのサンプルを書いてみることにした。

QtPositioningはその名の通りデバイスの位置情報を扱うもので、Android、iOS、Linux(GeoClue)、WinRT(Windows Mobile ?)でサポートされているらしい。もちろん、Jollaで使える。

というコトで早速コードを書いてみる。
import QtQuick 2.0
import Sailfish.Silica 1.0
import QtPositioning 5.3
import QtWebKit 3.0

Page {
    id: page

    PageHeader {
        title: "QtPositioning"
    }

    PositionSource {
        id: posSource
        updateInterval: 30000
        active: true
        onPositionChanged: {
            var pos = posSource.position.coordinate
            webView.url = "https://www.google.co.jp/maps/@%1,%2,17z".arg(pos.latitude).arg(pos.longitude)
            posData.text = "Latitude: %1\nLongitude: %2".arg(pos.latitude).arg(pos.longitude)
        }
    }

    WebView {
        id: webView
        width: 480
        height: 640
        anchors.centerIn: parent
    }

    Text {
        id: posData
        anchors.bottom: parent.bottom
        anchors.bottomMargin: 20
        color: Theme.secondaryHighlightColor
        font.pixelSize: Theme.fontSizeExtraLarge
    }

    Connections {
        target: Qt.application
        onActiveChanged: Qt.application.active ? posSource.active = true : posSource.active = false
    }
}
だいたいこんな感じ。雑なコードだけど、相変わらず恐ろしく簡単に使えるQtQuick/Qmlすごい。
基本的には「QtPositioning」をimportしてPositionSource{}を定義しておくだけ。
最低限、updateIntervalを設定し、activeをtrueにするぐらいで緯度と経度が取得できる。
厳密にはGPSベースの測位を優先するかどうか(preferredPositioningMethods)等の設定ができるけど、概ねデフォルトのままで使える。
positionが変わったら新たに取得した緯度・経度をGoogle MapのURLにしてWebView{}に渡す。と、そのpositionを中心にしたマップが表示される。今回のサンプルアプリはAPIを介したアクセスではなくページごと取得しなおしてるので、高頻度な更新を避けるためupdateIntervalを30秒(30000mSec)にしてみた。

一番下のConnections{}は前回Qippisにカメラ機能を追加した時にも活躍した「おまじない」。Jollaがスリープした時にGPSを動かしっぱなしにして電池消耗させないためのもの。なんだけど、method見る限りこれはstart()/stop()を使うべきなのかな・・・?

ちなみにAndroidだとこんな感じ。
import QtQuick 2.3
import QtQuick.Window 2.2
import QtPositioning 5.3
import QtWebView 1.0

Window {
    visible: true

    PositionSource {
        id: posSource
        updateInterval: 30000
        active: true
        onPositionChanged: {
            var pos = posSource.position.coordinate
            webView.url = "https://www.google.co.jp/maps/@%1,%2,17z".arg(pos.latitude).arg(pos.longitude)
            posData.text = "Latitude: %1\nLongitude: %2".arg(pos.latitude).arg(pos.longitude)
        }
    }

    WebView {
        id: webView
        width: 480
        height: 640
        anchors.centerIn: parent
    }

    Text {
        id: posData
        anchors.bottom: parent.bottom
        anchors.bottomMargin: 20
        color: Theme.secondaryHighlightColor
        font.pixelSize: Theme.fontSizeExtraLarge
    }

    Connections {
        target: Qt.application
        onActiveChanged: Qt.application.active ? posSource.active = true : posSource.active = false
    }
}
変えたのは以下の通り。

  • "Sailfish.Silica" → "QtQuick.Window"
  • "QtWebKit 3.0"→"QtWebView 1.0"
  • "Page{}" → "Window{}"
  • "visible: true"を追加
  • PageHeader{}を削除

たったこれだけの変更でとりあえず動く。
地図のサイズが小っちゃくなっちゃってるけど、これはWebViewのサイズを画面サイズとの相対値にしておけば労せず同じような見栄えにできるはず。すばらしいね!


もちろん、実際コレで何かアプリを作るならばこの取得した位置情報で何をするのかってコトの方が重要なワケだけど、すくなくとも位置情報の取得のためにアレコレ細かいコード書かなくてすむQtQuick/Qmlサイコー。

ってコトで、去年のカメラにしても今年の位置情報にしてもそれ自体を使うためのコードは最低限で済むワケなので、みんないっぱいQtでアプリ書いてみるといいと思うよ。

2015/05/27

Qt Japan Summit 2015 に行ってきた! #qtjs #qtjp

去年の「Qt Developer Day in Tokyo 2014」に引き続いて今年もQtのイベントがあるってコトで、とりあえず行ってきた。
去年はNokiaからQt事業を買い取ったDigiaが主催してたんだけど、今年はDigiaからQt開発に特化するために分社化した"The Qt Company"が主催している。

今回受付でもらったのはコレ↓
あっ!Qtの新しいロゴのステッカーじゃないかっ!!
ってことで早速X1 Carbonの天板に貼ったのだ。

今年のイベントでは、Qtユーザー会の出番がLightinig Talkに留まらず、イベント冒頭のあいさつに始まり午後には2コマのセッションをこなすという活躍ぶりってこともあり、主要メンバはバタバタだったので今回おいらはブースの対応とかに専念した感じ。
ってことで、セッションはほとんど見て(聴いて)ないので、中身の話は他のヒトに任せよう。うん。


まず、Qtは今年で20歳になったらしい。
Wikipediaの記事によると開発開始自体は1991年に遡られるようだけど、Lars Knoll氏のブログエントリによると「(おそらく正式な、ってことかな)最初のバージョンである0.90」がリリースされたのが1995年5月20日だったという事で、まさに今月二十歳になったばかり!

ってことで、日本Qtユーザー会おやつ部より素敵なバースデーケーキをプレゼント!
@task_jpさんの進行の下、檀上に上がったLars氏にお披露目し、会場の前から3列目ぐらいまでに居たヒトに協力してもらってお祝いのクラッカーを鳴らし、後でLars氏にケーキカットしてもらって記念撮影!
かなり細かく作りこまれたケーキ上のオブジェに、Lars氏も「イイね!」っていう反応だった。


さて、日本Qtユーザー会の展示ブースはこんな感じ。午前中の展示ブースを撮り忘れちゃって、下は午後の様子。
さて、上を見てお分かりの通り、今年のユーザー会ブースは「目玉展示」が二つあった。

まずはコレ!!
そう、言わずと知れたPepper君!!
直前のQt勉強会のブログにもある通り、Pepper君の開発環境はQtベースのツールなんだって!
基本動作はあまりコードを書かなくてもビジュアル的にモジュールを配置して配線していくだけでOKなんだって!
動画の動作は展示した会場でサクっとプログラミングしてもらったんだけど、多分5分ぐらいであっという間に作られた。慣れもあるんだろうけど、結構スゴい。
ユーザー会ブースはとにかくPepper君見て寄ってくる人がすごく多く、またこの開発環境ネタはLTでも発表されたこともあり、ものすごく注目度が高かった。
Aldebaran Roboticsさん、来年は正式にスポンサーになってPepper&NAOで1ブース作っては如何ですかね?(笑)

でも今回ハンドキャリーで持ちこんで下さったらしく、来る時も帰る時もこんな感じだった。
この状態で街中を引っ張って来られたのかと思うと、ちょっとシュールな感じ(笑)


次はコッチ。
なんと高校生が作った"jubeat"のクローン!!
詳細は下のブログエントリ("Qt Advent Calendar 2014"の20日目のエントリ)に詳しい。
qt quickでjubeat自作した
すごく良くできてる。
データベースとアクセスするためのインターフェイス部分でチョコっとC++を使ってるだけで、基本的にはQML/QtQcuik+Javascriptだけでできているらしい。
これを高校生が、1ヶ月ちょっと(?)で、QtQcuikの本をボロボロになるまで読みながら作り上げたってんだからスゴいよね!
ハードも手作りで、透明な板(アクリルかな?)の各辺の下にスイッチが付いていて、これをArduino互換ボードに入れて、USB経由でキーイベントとしてPCに入力してるらしい。(つまりプレイ自体はキーボードからでも可能)。
お昼の時間にLTで発表するとその後はかなり展示にヒトが集まって、カレはいろんなデベロッパーサイドのヒト達から名刺を渡されまくっていた。将来が楽しみな若手Qtデベロッパーの誕生に、みんな注目しきりだった!


プラスアルファで、「RapidCopy」の展示も合流して頂いた。
"RapidCopy" - MacOSX用 高速「ベリファイコピー」アプリ
午後のブースでは何やら熱心に質問されてる方もいて、なかなか盛況だった。


肝心のユーザー会の展示物はと言えば、まぁPepper君に引き寄せられてそれなりに盛況だった。ユーザー会のパンフレットを持って行く人、展示書籍をチラチラと読んで行く人といった感じである程度具体的にユーザー会の情報に接触していったヒトがそれなりに居たかな。ほとんどは黙って書籍見てパンフ取って流れて行ったけど、書籍・勉強会情報について具体的に声をかけてきたのは最終的に10~20人程度だったろうか。
大半は、@IoriAYANEさんの書いた「薄い本」はどうやったら手に入るのかっていう質問だった(笑)
 
というワケで、この2冊は下のURLから買えるのだ。
理ろぐ(BOOTH出張所): https://relog.booth.pm/
上のURLを紹介するマテリアルを準備してなかったので、PCでサイトを見せてURLをメモってもらったりとかっていう対応になってしまった。
ユーザー会のパンフはあるから、ユーザー会のページに「関連書籍」みたいなのを作ってもらって、次回からはパンフ渡して「このURLから辿ってね(はーと)」って言えるようにしよう。そうしよう。

イベントは若干時間オーバー気味にはなったものの、19:00過ぎには無事撤収も終了。

去年のイベントでは、セッションでの質問とかも「そもそも今(まだ)Qt使ってはいないんですが~」みたいな方が結構居たという印象が強かったんだけど、今年はブースに来た人達だけ見てても知ってるよ!使ってるよ!的な人が増えた感じがして、なかなか良かった気がした。

でもなんとなくブースに来たヒトを見てると(あるいは話を聞くと)、まだまだ使ってるヒトも使いたいヒトも「情報に飢えてる」感じがあるのかなーって感じがしたかな。
そーゆー意味でも、今後の日本Qtユーザー会の活躍が期待されるのかもしれない!


っつーワケで、主催者のヒト達もスポンサーのヒト達も準備やセッションに協力したユーザー会のヒト達もホント―におつかれさまでした m(_ _)m
去年、今年と来たから、また来年もあるんだろうか?
楽しみだねぃ(^_^)



ちなみに、なんかとりあえずこの間勉強会の懇親会に出て以来「宴会部長」ってことになってるっぽいので、とりあえず終了後に集まった8名程で、適当にお店をチョイスして席を押さえてなだれ込んでみた。
某氏の悪辣な(?)陰謀により若い衆が何故か年齢順に「ロシアンルーレット的料理」の「アタリ」を引き当ててしまう等ちょっとしたハプニングはあったものの、楽しい話で大いに盛り上がり、概ね2時間程で解散とあいなった。

おいらはその後Qt Championとちょこっと二次会やって、全行程を終了。

家に帰り着いた後、もう一本缶ビールを飲んでから寝たのはここだけの秘密だ(ぉ

2014/12/12

Jolla: Jolla向けアプリ「Qippis」に簡易カメラ機能を追加してみた。

この投稿は"Qt Advent Calendar 2014 - Qiita"の12日目(12/12分)の記事だ。

なんか他のメンバの記事のレベルが高くてアレだけど、とりあえず素人なりに素人っぽいものを書いてみる。Qtの話ってよりJollaの話っぽい感じがするけど、まぁ気にしない。


おいらはホビーヘッポコプログラマだけど、Jolla向けにQippisっていうアプリを作ってみた。
はりきらないひと: Jolla向けのアプリを作ってみた。
簡単に言うと、ビールデータベース"BreweryDB.com"のビューア。
ちゃんとストアで公開してるよ。
ソースはこの辺で公開してある。
http://git.qtquick.me/?p=sailfishos/qippis.git;a=tree
JollaはMeeGo由来の「SailfishOS」で動いていて、全面的にQtが採用されてて、UI周りや標準アプリの大部分がQtQuickで書かれている。あとUI作りを簡便化および一貫化するために"Sailfish Silica"っていうライブラリが用意されていて開発者向けにオープンにされている。

ここで告白すると、おいらはC++なプログラムが書けない(←威張って言うな!ww)。ということでQippisもsubmoduleのtwitter4qmlとそのつなぎ部分を除けば、ほぼQtQuickのみで書かれている。(twitter4qmlはおいらが作ったワケではないからノーカウントw)

ビバ QtQuick !

って事で、今回はQippisに新しい機能を付けた件について書いてみる。

○とりあえずJollaでカメラを使う

Qippisはビール情報をTwitterでシェアできるんだけど、飲んでるビール等の写真を添付するにはギャラリーから写真を選択するしかなかったので、撮影にはカメラアプリを別に起動する必要があった。

ホントはこーゆーのはQippisからカメラアプリを呼び出して・・・みたいな形が望ましいワケだけど、importできるモジュールに限りがあったりしてなかなか難しい(単なる勉強不足とも言う)。そんな中よく見たらQtMultimediaが使ってもいいモジュールのリストに入っていたので、自力で簡易的な撮影→投稿の機能を追加してみることにした。

まず、QtMultimediaを使ってカメラで写真を撮る時の基本的なコードは概ねこれだけ。
import QtQuick 2.0
import Sailfish.Silica 1.0
import QtMultimedia 5.0

Page {
    id: page

    Camera {
        id: camera
    }

    VideoOutput {
        anchors.fill: parent
        source: camera
        focus: visible
        MouseArea {
            anchors.fill: parent
            onClicked: camera.imageCapture.capture()
        }
    }
}
・・・たったこんだけ。
非常にシンプルでわかりやすい。ビューファインダーをタップすると写真が撮れる。撮った写真は端末のデフォルトの保存場所に落ちる。
Androidの場合はSailfish.Silicaの代わりにQtQuick.WindowをimportしてPage{}の代わりにWindow{}を使えばOK(あ、"visible: true"を入れないとダメかな)。WindowsPhone8.1は・・・今のところうまく動かせてない。5.4がリリースされたばかりなので、これからゆっくり確認してみるつもり。

ともあれQippisへの機能追加は、これをベースにした写真撮影用のページを一つ作り、保存された画像ファイルのパスをツイートのパラメータに取り込めば完了。

Σ(゜Д゜) スゲー簡単ジャン!!!

・・・とココまではサクサクだったのに、この後しばらく悩むことになる。

― 悩みその1:『保存される画像の向き』

Jollaのカメラのセンサーは端末の右側を上にして配置されてるっぽい。
つまり端末を左に90度回転させた横向きで写真を撮ると、ファインダーで見た通りの画像が保存される。

端末は基本縦持ちだし、アプリも縦画面のUIしか持ってないし、なによりビールの缶・ボトル・グラス・ジョッキは基本縦長なので、縦向きに撮影・保存したいのに、どうやっても向きが変わらない。

最初はカメラ側の機能で回転させて保存するんだとばかり思っていたから、あーでもないこーでもないといろいろ悩んでたんだけど、結局「画像を回転させて保存する」のではなく、『どっちが上か(撮影方向)の情報を画像ファイルに付与する』のが正解らしい。即ち、
camera.imageCapture.setMetadata("Orientation", 270)
ってな形でメタデータをセットしておけばいいらしい。

ホントは端末の向きに応じてメタデータをセットするのが正しいけど、今回qippisは縦持ち決め打ちすることにしたので、撮影用のページを呼び出した時点で270度に固定するよう設定した。

ちなみにSailfish.SilicaのOrientationは0-4の数値で管理してるっぽいけど、QtMultimediaのは90の倍数(0,90,180,270)で管理してるので、Silicaで得られる値をそのまま突っ込んではいけない。はず。

― 悩みその2:Jolla特有の問題(1)「onImageCapturedがCallされない」

Qtのドキュメントにあるサンプルコードの挙動がJollaとAndroidで違ったのでしばらく悩んでたんだけど、どうやらJollaではCamera.imageCapture.capture()を呼んでもonImageCapturedがうまくCallされない問題があるらしいことがわかった。そのせいでpreviewプロパティもちゃんとセットされないので、サンプルコードのようにpreviewをImage.sourceにツッコむこともできない。

ということで、撮影時にその場で撮ったものを確認するような機能を実装する時は、onImageSavedを使って保存済みの画像ファイルをImage.sourceに持ってく様にするといいっぽい(ってか、それしか手段がなさそうに見える)。
で、qippisはそういう風に実装したんだけど、ここで次の問題に遭遇する。

― 悩みその3:Jolla特有の問題(2)「Image{}でMetadetaのOrientationが反映されない?」

縦持ちで撮影して、ギャラリーで確認する時はちゃんと縦画像になっていて、Twitterに投稿した画像もちゃんと縦画像になっているにも関わらず、Image{}で表示させると横になってしまう・・・
・・・なんでやねん。

いろいろググってみたけど、「(Jollaで)そういう問題がある」ってことしか今のところ判らない。で、今回は上にも書いた通り縦画像で決め打ちだから、Image{}にrotation: 90を指定して無理やり回転させている。本当はメタデータを読みだして、データに合わせて回転させないとダメだけどさ。

― 悩みその4:実装上の問題「High Power Consumption」

とりあえずやりたいことはできるようになったのでJolla HarbourのQAにアプリを投げたら、「High Power Consumptionで受容不可」とのこと。どうやら撮影用のページを開いたままで端末がスリープに入るとmm-qcamera-daemonがアイドル状態にならず、結果としてqippisがActiveの状態を維持してしまうようで、「これだとバッテリのもちに影響しちゃう」ってことらしい。
JollaのQAのヒトはすごく親切で、状態の説明、確認方法(彼/彼女らがテストした方法)を詳しく解説してくれた上で、「I believe releasing the camera in this case can be a good solution to fix this issue.」というアドバイスをくれた。

なんとなく「スリープした時にcamera.stop()、復帰した時にcamera.start()」を呼べばいいというところまではピンと来たけど、肝心の「端末がスリープしてるかどうか」を知る方法が判らない・・・

悩んだ末、JollaのQRコードリーダーである"CodeReader"のソースを参考にさせてもらい、多分この辺だろうと思しきコードを貼り付けてみた。
Connections {
    target: Qt.application
    onActiveChanged: Qt.application.active ? camera.start() : camera.stop()
}
一応、回避できたっぽい感じだったので改めてsubmitしたところ、どうやらこれでOKっぽかった。
Jollaは意外にバッテリの持ちがいい印象なんだけど、こうやってアプリの電力的な挙動も一通り確認してあるんだね。

○そしてできたもの。

ってな感じで、最終的にできたのがコレ。


これを下のようにして呼び出して、tweet用のデータに組み込んでる。
var cameraPicker = pageStack.push(Qt.resolvedUrl("Camera.qml"));
cameraPicker.tookPictureChanged.connect(function() {
    _image = cameraPicker.tookPicture;
    media.push(_image);
});

正直なところ良く言えば「割り切って」、悪く言えば「手を抜いて」って感じではあるんだけど、今回はカメラアプリを作りたかったワケじゃないので、「キレイな写真が撮りたければカメラアプリ使ってね」ってことでOKにしてほしい(笑)

とりあえず「カメラで写真撮って画像ファイルを取得する」のに、へっぽこスキルでも80行強というわずかなコード量で書けているので、これはやはりQtQuickすごいよね(笑)

とゆーことで、Jolla用アプリにカメラ機能を追加してみた話はこれでおしまい。

○最後に

ま、コードの方は見る人が見れば「おまえそれはないだろう」的なものが多いだろうとは思うんだけど、「何かやってみたいけど素人だからなかなか手が出ない」ってヒトにとっては「この程度のスキルでもこのぐらいはやれる」っていういいサンプルになるんじゃなかろーか(ぉぃ

フレームワーク自体が便利なだけじゃなくてQtCreatorっていう強力なIDEもあるし、Qtのコミュニティはこんなレベルでもちゃんと歓迎してくれる温かい人たちで溢れているので、「これからプログラミングはじめます」ってヒトは是非とっかかりにQtを使う&日本Qtユーザー会に参加することおススメするのである。←それっぽく宣伝してみる

さて、肝心のアプリ、ホントなら「みなさんもちょっと試してみてね」って言いたいところなんだけど、残念ながらものすごくマイナーな環境なので簡単にはお試し頂けない。
大半のところはSailfishOS SDKでエミュレータを使えば体験できるけど、今回のカメラのところは実機じゃないと・・・
ってことで、Jollaのスマートフォンは今はかなり値下がりしてるし、来年5月にはタブレットも出るし、なによりQtでアプリを作りやすいから、みなさん1台ずつどうっすかね(笑)


2014/05/20

Qt Developer Day in Tokyo 2014 に行ってきた!

「Qt」っていうフレームワークは、Zaurus SL-B500を手に入れた頃からの付き合いではあるんだけど、基本的にはそのアウトプットを利用する側の人間なんで、あんま自分でこれ自体をどうこうとは思ってなかったってのが正直なとこなんだよね。

でも、まぁ、Nokia N9を手に入れた後、Qtベースのオープンソースなアプリがたくさんあって、そこからの縁で自分でも少しいじってみよーかなー・・・って感じで、多少なりともそーゆーコミュニティの人達と知り合って、んでもってまぁJollaも買ったことだしと・・・

そんな流れの中で、2年半振り(?)なんだそうだけど、"Qt Developer Day"が日本で開催されるってことになったそうなので、とりあえずプログラマでもなんでもないけど行ってみるだけ行ってみた(笑)
会場が開くか開かないかっていうタイミングで入口に着いて、どーしよーかなーと思っていたら@task_jpさんに遭遇して、「じゃあ行きましょう」と・・・(笑)
入口で受付やってたんだけど、なんかね、「名刺を2枚頂戴致します」って言われて渡したら、登録者の一覧を打ち出した紙みて、一生懸命探すのね・・・そこは、ほら、そーゆー集まりなんだから、もちょっと何とかしようよwww
実は結局その場では名前が見つけられなかったんだけど、後ろが閊えてたから「探しときます」的な状態になって先に通してもらったんだよねwww

で、受付でパンフとプログラム、そして記念品の「Tシャツ」をもらった。
思ったよりも地味な感じだけど、それだけに普段着ててもあんま問題なさそうな感じ(ぇ

で、とりあえず「会場の準備が整うまで展示ブース見ててね」みたいな話だったのでウロウロしてたら・・・一番奥にありました。
今後のために用意したというテーブルクロスの緑が眩しい!

他にもDigia含め数社が展示をしてた。ある会社のパネルを見ると、明らかに病院にある「患者モニタ」の画面が移ったプロダクトの写真が・・・QtでUIを組んだ医療機器があるってことなのかなぁ。まぁ、ありそうではあるけど、実際には「Qtで作ってるよ」ってのはまだ見たことがない・・・

上に書いた通りの受付対応だから、開始時刻の10:00をちょい回ったところで「始まりの時間なんだけどレジストレーションに手間取ってるから、もう少し待ってね」みたいな案内が・・・ま、でもそんなに遅れずにプログラムスタート。

午前中はいわゆる「キーノート」。
写真は客が入りきる前のものなので結構開いてるように見えるけど、実はもっと盛況だった。
まぁ、基本的には「Qtのこれまでとこれから」みたいなところがテーマになった話なんだけど、たぶんこのイベントのためにそうしたんだと思うんだけど、今日付けでQt 5.3がリリースされたらしい。
んで、まぁ、オーバービューとして「5.3にはこんなんが加わったんだよ!みんな一緒にQtで開発してハッピーになろうよ!」的な話がされてたように思う。「Qtはみんなの開発を助けるために作られたし、これからもみんなの開発を助けるために発展し続けるよ!」と。

ちなみに、海外からのスピーカーはみんな英語でプレゼンやる訳だけど、なんとちゃんと同時通訳がついてた!すげーな!!
これが同時通訳用のレシーバ。

で、とりあえず昼食。
このミーティング自体は参加料は無料だったんだけど、なんとお昼はお弁当付きだった!
お弁当を食べながら、この時間を使って日本Qtユーザ会主催のLT大会があった。
4名程の方々が今やっていること、Qtについて言いたいことなどを発表してくださってた。ちなみに写真は@hermit4さんの「Qtおやつ部活動報告」の発表風景。

で、午後のセッションはテーマ毎に分かれてのテクニカルトラック。おいらは一番初心者向けの「エッセンシャル1」に参加してみた。
写真は、今回「これだけは聴こう」と心に決めていた@takumiasakiさんの「Qt Quickの紹介」。
全体的には、ツール(QtCreator)の紹介から始まって「こんなに簡単に、こんなに便利に、いろんな開発ができますよー」みたいな感じの話。
実際、QtCreatorはIDEとしては強力な統合環境で、コード書くところからコンパイル、デプロイ、デバッグまでをかなり便利にこなすことができる。そしてUIデザイン部分のコーディングのハードルを下げるために作られた(って理解したんだけど)QtQuickは、単純にUIだけじゃなくてデータを取り扱うための「Model」とかも持ってて、簡単なアプリならこれだけで書けちゃうんじゃないの?ってぐらい強力なツールに見える。特に最後のセッションで紹介されたQtQuick Control辺りまで来ると、本当にそう思えてくる。

思えてくるんだけど・・・ライブコーディングでどんどん組まれていくプログラムを眺めつつ、やっぱこりゃ本当に何かを作りたいならC++書けないとダメだなっていうのも、つくづく感じた。やっぱQtQuickはあくまでもUI側を強力にサポートするツールなんであって、きちんとバックエンド作れないとダメだよなー・・・と・・・

まぁ、どのみち大したスキルがある訳でもないおっさんの「ハードルが高いなぁ」という嘆きはともかくとして、それでもある意味魔法のようにサラサラっと書いたものが目に見えて動くみたいなのはなかなか面白いものではあったよ。うん。

で、おいらみたいな堕落したおっさんにはやっぱ相応にハードル高いと思わせる部分があるにせよ、Qtのパワーみたいなものは感じたし、もっともっと使う人が増えてくれるといいなぁと思った次第。

ちなみに、上でちょっと触れた「Qtおやつ部」は、なんと発表だけでなく成果物もちゃんと配布していた!
ちゃっかり頂いてきましたよ!
うまかった(笑)

おいらは特に貢献できそうなものはなかったけど、とりあえずユーザ会の展示ブースにこっそり(?)Jolla端末を置いてみた。それなりに興味をもった人は居たっぽい。
あ、あと戦利品(?)として、FireAlpacaのパンフ、ステッカー、缶バッジの3点セットを頂いた。缶バッジはラスイチだったんだけど、もらってよかったのかなぁ・・・←いまさら

ま、とゆー訳で、なんとなく楽しい一日だった。
これまでTwitter上でしか知らなかった日本Qtユーザー会の人達の一部を生で見ることもできたし、時間とかの関係で懇親会までは出なかったけど、そのうち飲みにでも行けるといいなぁ。

ちなみに一番下になっちゃったけど、日本Qtユーザー会は日本のQtのコミュニティで、今回QtDDが日本で開催されるに至った経緯においても「日本にはすばらしいQtコミュニティがある」と言わしめた団体だ。

日本Qtユーザー会

関東地区は毎月「勉強会」を開催してるし、関西や名古屋でも「勉強会」が開催されてる。
初心者も歓迎ということらしいので、これからプログラミングを勉強したいとかなんかとにかくやってみたいみたいな人は、上のリンクから情報を辿って勉強会とかに出てみるといい。
おやつ目当てでもいいらしいけど、その辺りはどうなんだろうか(笑)

なにがともあれ、一日無事に終了して、めでたしめでたし。次はいつ日本に来るのかしら。

みなさん、おつかれさまでした!!!