2015/12/31

2015年もいよいよ終わり・・・

ついに2015年も今日が最後。

毎年恒例の「まったく役に立たない」大晦日エントリだ。

まぁ、今年も今年でいろいろあった・・・
妙に海外出張が多い年でもあったな。1月、7月、12月と3度も出るハメになった。来年は大きな再編があるはずだから、果たしておいらは何をしていることだろうか・・・

恒例の(?)今年のTweet数はなんと年間10000ツイートを越えてた・・・何やってんだおれ(笑)。11月ぐらいにものすごい数つぶやいてるけど、なんかあったかな??なんにしても今年もくだらないことを沢山吐き出したらしい。

買った端末はLumia 930のみ。だと思う。他に何か買った覚えがない。あ、でも購入手続き的にはJolla Tabletを買ったはずだけどまだとd(ry
小物的にはPebble Timeを手に入れた。なかなか便利に使えている。

去年QtDDに参加したのに引き続き、今年もQt Japan Summitに参加してきた。参加したというか、今年はブースのお手伝いをしたよ(笑) なんかすごいゲームを作った高校生やPepper君と出会えて、楽しいイベントだったな。
でも去年Jolla向けにQippisをリリースしたのに比べると、今年はそーゆーのは全然できなかったな。ダラダラしてしまった。まぁ、はりきる必要はないのでボチボチやればいいんだけど、来年はもうちょっと何かできるといいな。
まぁ、なぜか「宴会部長」と呼ばれるようになってしまったのでちゃんと(1回だけだけど)宴会を企画もしたし、Qt Advent Calendar 2015はなんとか2枠埋めたし(相変わらずヘボいエントリだけど)、結局勉強会には一度も行けなかったけど、来年もボチボチ続けられるといいねぇ(笑)

あと、なんか今年はよく「人に会った」年だったかな。
Twitter上で長いこと知ってたけどリアルに会ったことがない人達に次々とエンカウントしていった感じ。関東近辺に住むようになって20年近く経つけど、リアル環境では会社の同僚以外にほぼ知人友人が居ない状態がずーっと続いてたから、ここ2~3年の環境変化はめざましいものがある(ぉ
なんにしても、こののんだくれのおっさんの飲みに付き合ってくださった方々、誠にありがとうございましたなのです m(_ _)m

というワケで、例年通りの大晦日エントリなのだ。今年一年支えてくれたいろんな人達に感謝しつつ、いつも通りの言葉で締めくくろう。

今年も残りあと2時間ほど。

Twitterでフォローしてくれた方々も、この独り言にもなってない駄ブログを読んで下さってる方々も、今年一年ホントにありがとーございました。

2016年もまたはりきらない程度にやってくんで、よろしくお願いしますです。

2015/12/28

Jolla: 日本語のフリック入力

Jolla Phoneの日本語入力環境としてはかなり初期の頃から「Behold」さんがローマ字入力で実現されていて、OpenRepos.netでjolla-anthy-jpという名前でパッケージ配布している。
OpenReposで配布されているパッケージはWareHouse for SailfishOS経由でインストール&パッケージ管理できるってこともあって、ワリと簡単に導入できるワケなんだけど、特に電車の中とか片手で操作したい時にローマ字入力ってのはツラかったりするので、メールやSNS等で日本語テキストを入力するようなケースではやっぱり他の端末を使うケースが多かったりした。

そんな時、今年の夏ぐらいに「どうやら誰かフリック入力を実現させたらしいよ」という話をJolla Phone保持者が4名も集まった某所での飲みの席で知り、ちょこっと調べてみたところ「sleepsounds」さんという方が書かれたものであることを知った。Beholdさんはどこの人だかも知らないんだけど、sleepsoundsさんはどうやら日本の方らしいね。
残念ながらインストール可能なパッケージでの配布はされてないっぽいので、Githubのリポジトリからgit cloneするか上のリンク先の右上にある「Download ZIP」で落として来て、手作業でファイルをコピーするしかなさそう。

以下、簡単に中身を紹介してみるんだけど(まぁJolla Phone使ってるようなヒトには「釈迦に説法」だけど)自分で試す時は自己責任でよろしくね(はーと
  1. Beholdさんの"jolla-anthy-jp"を導入しておく。(WareHouse for SailfishOS経由でインストールするのが楽かな)
  2. githubのページからjolla-kbd-flick-jpをJollaのブラウザで直接ダウンロードするか、母艦のPCでZIPを落としてきてJollaにコピーする。
  3. デベロッパーモードで母艦からsshするか、Terminalアプリを立ち上げるかする。
  4. cd Download ※とか、とにかくzipファイルをコピーした場所にcdする。
  5. unzip jolla-kbd-flick-jp-master.zip
  6. cd jolla-kbd-flick-jp-master/src
  7. devel-su
  8. cp -R * /usr/share/maliit/plugins/com/jolla/
  9. cd /usr/share/maliit/plugins/com/jolla
  10. mv KeyboardBase.qml KeyboardBase_Original.qml
  11. ln -s KeyboardBase_Flick.qml KeyboardBase.qml
だいたいこんな感じだろうか。
要は、単純にコピーしてくるだけじゃなくて、KeyboardBase.qmlを置き換えなきゃいけないってのがポイントだ。
あとは「設定→テキスト入力→キーボード」から「日本語(フリック)」をアクティブにしておこう。
多分、再起動しなくてもイケたと思う。
ポップアップ表示はPopperを使っているので、ガイド的な表示ではなく単純にフリックした時に入力される文字が表示される(←SailfishOS 2.0になった時にPopperの仕様が変わったとの事で、2015/12/28時点ではここの文字は変化しなくなっている。が、既に@sleepsoundsさんの手元では修正済みらしく、そう遠くないうちに修正版が公開される模様)。

とりあえず5日間程使ってみたワケだけど、フリックの感度は悪くない気がする。キーレイアウトはWindowsPhoneを参考にしたとどこかで読んだ気がするけど、特に左にある英数の切り替えのところはまんま再現できていて、Lumiaと操作を往復するおいらにとっては非常にありがたい。
ただ、現状リアル端末上では左下の「日」をタップすると即qwertyに移動してしまうため、スペースを入力することができない・・・でもエミュレータで試すとちゃんと入力できるんだよねぇ・・・なぜじゃ??
もうちょいよく調べてみよう・・・

オリジナルのKeyboardBase.qmlを置き換えるのがちょっと難点という話ではあるけど、rpmパッケージ作ってインストール時に置き換え、アンインストール時に書き戻しって出来る気がするから、パッケージ化すると利用者増えるかな?←増えるっつったってそもそも日本のJolla Phoneユーザの数が知れてるだろ・・・

なんにしても、とてもありがたい感じだ。
Jollaを日本語でガシガシ使いたいなら、作者の@sleepsoundsさんに感謝しつつ入れてみるといいと思うよ。

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/12/08

オーストラリア


オーストラリア(メルボルン)に行ってきた!
・・・・・仕事で orz.....

南半球で季節が逆ってことだからいろいろ服装的な部分を心配したワケだけど、途中経由したブリスベンは結構蒸し暑かったのに、最終地点のメルボルンは・・・寒かった(゜Д゜)!!
ブリスベンからは国内線だったんだけど、空港は国内線ロビーと国際線ロビーが隣接しているので、プリペイドSIMを買うために国際線到着ロビーの方へ移動する・・・

・・・あった!OPTUSのショップ!
国際線のロビーって事であたりまえのように旅行客が沢山SIMを買いに来るワケで、それ用のプランが掲げてあるし店員さんもずいぶん手慣れてる。

基本的に通話も含めた短期のプリペイドのプランは、通話&SMS無制限、データ通信500MB/日で$2/日。なかなかお手頃でいいプランだね。

カウンターで「プリペイドSIMください」とお願いするとまず「何日間いるの?」と聞かれる。今回は4日間だったんだけど、最短(最安)のは5日分$10なので「じゃあコレね!」と言われる。
あとはパスポートの提示と宿泊先の住所を登録してもらって、無事購入完了。
SIMはこんな感じ。
ミニ、マイクロ、ナノの全サイズをカバーしてるSIM。

OPTUSは3G:B1,B8、LTE:B1,B3,B7,B28と使えるっぽいって話だったので、今回はJollaに挿しておいた。
4Gもバッチリね。テザリングもできてた。
500MB/日と結構余裕あるプランだったしJollaでのテザリングもできてたので、今回SIMはこれ一枚にしてLumia 930とNexus 7はWiFiテザリングで4日間を過ごした。
Nexus 7だけだったらBTテザリングで良かったかな・・・直接Lumiaに挿して運用しても良かったかもしれないけど、まぁ今回はコレで。

日本のプリペイドもこういうプランが欲しいよねぇ。
旅行者用にもそうだし、何かで1週間だけ携帯電話使いたい(与えたい)みたいなニーズってあるような気がしなくもないけど、どうなんだろう??

ま、とにかくOPTUSのプリぺSIMは安くて便利でした。ちゃんちゃん。