アプリの開発をしていると、実行時に必要なファイルがでてくると思います。dllとかsoとかdylibとか......、いえ、今回の記事では何でも良いのですけどね。何か設定的なことを書いたテキストでもリソース的なファイルでも何でも。
 大抵、シャドウビルドで開発をするのでそれらのファイルは通常、手でコピーしなければなりません。シャドウビルドで作られたフォルダに都合良く勝手にコピーはされませんから。
 で、数日前の「Qtからお手軽にZIPファイルを扱えるQuaZIPの紹介」でも、サラッとdllをコピーする方法を紹介したのですが、若干使い勝手が悪いです。
 複数のファイルをコピーしたい場合にこの方法だと冗長になってしまうので、イマイチです。
 なので、少しは楽にならないかなーと考えた方法を紹介します。もっと、良い方法があったら誰か教えてください! 凄い人!

/// ポイント ///
 繰り返しもありますが

置換関数を作る
 結局のところ、パスを作るところが冗長なので置換関数でなんとかします。なんとも普通な発想です。もう少し、qmakeっぽいやり方ないものかと思いますが......。
 結局、QMAKE_EXTRA_TARGETSに登録するところは、頑張って書かないといけないのが現状の難点です。つまり、プロジェクト設定でMakeの引数をいっぱい書かないといけないって事です。

コピーコマンドは「$(COPY_DIR)」で書く
 これはMakefileへ「$(COPY_DIR)」がそのまま出力されるので、Makefileで定義されるコピーコマンドが使えます。環境にproファイルで何とかする必要がありません。

Windowsはパスの区切り文字を「\」に統一
 proファイル内は、「/」で統一して書いて良い(Makefileを出力するときにqmakeがなんとかしてくれる)のですが、QMAKE_EXTRA_TARGETSのcommandsはそのままMakefileに出力されるので環境に合わせたパスの表記をしなければなりません。


では、こんな感じです。

/// hoge.pro ///
# 置換関数の宣言(使うところより前)
defineReplace(makeCopyCommand){
    DEPEND_FILE = $$1
    win32:{
        CONFIG(debug,debug|release){
            APP_BUILD_DIR=$$shadowed($${PWD})/debug
        }else{
            APP_BUILD_DIR=$$shadowed($${PWD})/release
        }
        DEPEND_FILE ~= s|/|\|gi
        APP_BUILD_DIR ~= s|/|\|gi
    }else{
        APP_BUILD_DIR=$$shadowed($${PWD})
    }
    return($(COPY_DIR) $$DEPEND_FILE $$APP_BUILD_DIR)
}
# なんかのファイル1個目
copyfile1.commands += $$makeCopyCommand($${PWD}/hoge.txt)
QMAKE_EXTRA_TARGETS += copyfile1
# なんかのファイル2個目
copyfile2.commands += $$makeCopyCommand($${PWD}/../fuga/fuga.dll)
QMAKE_EXTRA_TARGETS += copyfile2
(※proファイルに日本語を書くと化けます。説明用にあえて日本語を書いているだけなのでご注意ください)

/// プロジェクト設定 ///
 以下の画像のようにビルドステップを追加してMakeの引数を設定します。
 qmake_project_setting_build_step.JPG
 (※プロジェクトのパスは今回の例と関係ないので気にしないでください)

 リリースとデバッグの両方で設定してください。ビルド設定を切り替えて「アレ?コピーされない?」となりますので。
 何はともあれ、これでいちいちビルドフォルダへコピーする煩わしさから解放されます。

 

/// 宣伝 ///
 proファイルの詳しいことを知りたい方は、緑野翁さんの著書「qmake入門」を参照してください。BOOK☆WALKERか今冬のコミケC91(2016/12/29 ビックサイト)のスペース「西み32b」で入手できます。
  BOOK☆WALKER:qmake入門

冬コミ(C91)新刊情報「雨の贈り物」

 冬コミの新刊情報です!
 本作も「小説家になろう」に投稿している作品「雨の贈り物」の書籍化です。
 いろいろ、加筆修正している感じです。
 そして、今回も表紙と挿絵が入ります! 風都ふうちさんに相談させてもらって、いろいろとこだわって描いていただいたので、ぜひ、現物を手にしてください。表紙と挿絵で連動しているところも、見所です。
 当日、スペースにてお待ちしております。

表紙_修正_販促用M.jpg

/// 情報 ///
サークル名:理ろぐ
場所:金曜日 西ひ02b
ページ数:132ページ
予価:500円
著者:あやねいおり
イラスト:風都ふうち(pixiv)

/// 内容 ///
 ある日の高校の帰り道、閉店してしまったお店の前で少女は子犬と出会う。
 それは、思わぬ再会へと繋がり、過去を思い出すきっかけとなる。
 これは、子犬を中心に始まる、ちょっと不思議な出会いの話。




/// その他 ///
 既刊も2種類持っていきます。
 こちらのイラストは、ましろ.あー。さんです。
 ・ワールド・アドミニストレーター
  販促用(表紙のみ).jpg
 ・君の中の魔法少女
  MagicalGirlInYourHeart_Topp.jpg 

Qtからお手軽にZIPファイルを扱えるQuaZIPの紹介

 この投稿は、Qt Advent Calendar 2016の22日目の投稿です。
 毎年、この日を確保しております。理由は、簡単、冬コミの原稿が終わっているはずだから!
 そして、過去2回はCalendarエレメントがらみの記事を投稿していたので、今年もそうしようかなーと思っていたのですが、変更しました。
 QuaZIPについての日本語の情報ってサラッと探した感じだとないのですが、非常にお手軽なので別にって感じなのかもですけれども、あえて書いてみる事にしました。
 むしろ、QuaZIPのライブラリを使うためのqmakeの設定(*.pro)の方がもしかしたら慣れてない人にはありがたい内容かもしれない、と思った次第です。ガンガンに使っている人にとっては、基礎だと思いますが。

 と言うわけで、QtでいわゆるZIPファイルを「簡単」に扱うにはQuaZIPというライブラリが非常に便利です。

  公式サイト:QuaZIP - Qt/C++ wrapper for ZIP/UNZIP package

 このライブラリ自体がQtで作られているわけなので、使わなくてもZIPファイルを扱えますが、折角のライブラリを使わない手はありません。プロジェクトの事情でも無い限り使いたいところです。
 というわけで、QuaZIP自体のビルドからお手軽な使用方法までを紹介します。
 ちなみに、LGPL 2.1です。


/// 環境 ///
 今回紹介するに当たっての環境は以下の通りです。
 ・QuaZIP 0.7.2
 ・Windows 10(64bit)
 ・Qt 5.7.0
 ・Visual Studio 2015

 試しては居ませんが、Qt4系にも対応しているようです。


/// 準備 ///
 公式サイトからソースコードのアーカイブを入手します。
 それをお好きな作業フォルダに解凍します。
 以下のフォルダ構成で作業を進めることを想定しています。

 作業フォルダ:C:\QtProjects
 解凍フォルダ:C:\QtProjects\quazip-0.7.2


/// ビルド方法 ///
 ビルドはビルド用のフォルダを作るシャドウビルドで行います。
 32bit版もビルドする前提でフォルダ名などをつけていますので、適宜読み替えてください。
 qmakeするときにzlib.h用にインクルードパスを追加する必要があります。この辺りは公式にも環境に合わせて適宜やってねって書いてありますけども。
 PREFIXに指定するパスは、カレントからではなくquazip.proからの相対パスです。

 >"c:\Program Files\Microsoft Visual Studio 14.0\vc\vcvarsall.bat" x86_amd64
 >PATH=%PATH%;C:\Qt\5.7\msvc2015_64\bin

 >mkdir build-quazip-x64
 >cd build-quazip-x64

 >qmake -r ..\quazip-0.7.2\quazip\quazip.pro "PREFIX=..\..\quazip\x64" "INCLUDEPATH+=$$[QT_INSTALL_PREFIX]/include/QtZlib"
 >nmake all
 >nmake release-install debug-install

 以下のファイルができていればOKです。
 .\quazip\x64\lib\quazip.dll
 .\quazip\x64\lib\quazip.lib
 .\quazip\x64\lib\quazipd.dll
 .\quazip\x64\lib\quazipd.lib
 .\quazip\x64\lib\quazipd.pdb
 .\quazip\x64\include\quazip\* h

 Macの場合は、INCLUDEPATHの代わりに「LIBS+=-lz」を追加します。


/// アプリケーションに組み込み ///
 適当なアプリケーションプロジェクトを作成します。
 今回は特にUIどうこう気にしないので、ボタンを押したらテストコードが実行できる感じでいきますので、Qtウィジェットのプロジェクトが簡単で良いと思います。
 プロジェクト名「QuazipExample」で進めます。
 まず、ライブラリを追加する設定を記述するファイルを作成します。

quazip.pri
# for quazip
QUAZIP_DIR = $${PWD}/../quazip
win32:{
    TARGET_PLATROM = $$(PLATFORM)
    equals(TARGET_PLATROM, "X64"):{
        # 64bit
        QUAZIP_DIR = $$QUAZIP_DIR/x64
    }else{
        # 32bit
        QUAZIP_DIR = $$QUAZIP_DIR/x86
    }
}
INCLUDEPATH += $$QUAZIP_DIR/include
CONFIG(debug,debug|release){
    win32: LIBS += $$QUAZIP_DIR/lib/quazipd.lib
}else{
    win32: LIBS += $$QUAZIP_DIR/lib/quazip.lib
}
unix: LIBS += -L$$QUAZIP_DIR/lib/ -lquazip

# for zlib
win32: INCLUDEPATH += $$[QT_INSTALL_PREFIX]/include/QtZlib


# copy library file
win32:{
    CONFIG(debug,debug|release){
        QUAZIP_LIB_PATH=$$QUAZIP_DIR/lib/quazipd.dll
        APP_BUILD_DIR=$$shadowed($${PWD})/debug
    }else{
        win32:QUAZIP_LIB_PATH=$$QUAZIP_DIR/lib/quazip.dll
        APP_BUILD_DIR=$$shadowed($${PWD})/release
    }
    QUAZIP_LIB_PATH ~= s|/|\|gi
    APP_BUILD_DIR ~= s|/|\|gi
}else{
    QUAZIP_LIB_PATH=$$QUAZIP_DIR/lib/libquazip.so.*
    APP_BUILD_DIR=$$shadowed($${PWD})
}
copyquazip.commands = $(COPY_DIR) $$QUAZIP_LIB_PATH $$APP_BUILD_DIR
QMAKE_EXTRA_TARGETS += copyquazip
 後半でカスタムターゲットとして「copyquazip」を作成します。これをプロジェクトの設定のビルドステップに追加すると自動でdllがコピーされるようになります。
 カスタムターゲットのコマンドの「$(COPY_DIR)」はMakefileにこのまま出力されます。そして、Makefileの中でWindowsだとxcopyを使うように設定されていますので、proファイルでプラットフォームごとの設定を書かなくてもすみます。
 この処理は、実はMacは必要ないです。macdeployqtを実行すると勝手にコピーしてくれるのでズルいですw

 続いて、上記のファイルをプロジェクトファイルから読み込まれるようにします。
QuazipExample.pro
    include(quazip.pri)
 プロジェクトの設定は、「ビルドステップ」→「ビルドステップを追加」で「Make」を選択し、「Makeの引数」に「copyquazip」と入力します。
 つまり、
 >make copyquazip
 をやってくれるようにするわけです。

 Qt Creatorからビルドするときや、Qtをインストールしたときに作られるコマンドプロンプトのショートカット「Qt 5.7 64-bit for Desktop (MSVC 2015)」などを使用すると64bit環境のときだけ環境変数として「PLATFORM=X64」が定義されています。これを利用して使用するライブラリのパスを切り替えられるようにしています。
 このファイルの設定について詳しいことを知りたい方は、緑野翁さんの著書「qmake入門」を参照してください。BOOK☆WALKERか今冬のコミケC91(2016/12/29 ビックサイト)のスペース「西み32b」で入手できます。
  BOOK☆WALKER:qmake入門


/// お手軽な圧縮と解凍 ///
 QuaZIPには、簡単お手軽機能をまとめた「JlCompress」クラスがあります。
 特定のファイルを圧縮したり、解凍したりがお手軽ポンです。
 紹介する関数は全てstaticです。

 リファレンス:JlCompress Class Reference

 正直、ここを見れば説明不要って感じですが、一応めげずに紹介します。

bool JlCompress::compressFile(QString fileCompressed,
                              QString file)
fileに指定されているファイルを圧縮します。

bool JlCompress::compressFiles(QString fileCompressed,
                               QStringList files)
filesに登録してあるファイルを圧縮します。
色々な場所に散らばったファイルを選んで圧縮する場合などに使えそうですね。


bool JlCompress::compressDir(QString fileCompressed,
                             QString dir = QString(), 
                             bool recursive = true)
dirに指定したフォルダの中身を圧縮します。
recursiveをfalseにするとサブフォルダの中は無視されます。もちろんフォルダ自体も無視されます。
dirを省略すると、カレントフォルダの中身を圧縮します。
隠しファイルは無視されます。


bool JlCompress::compressDir(QString fileCompressed,
                             QString dir, bool recursive,
                             QDir::Filters  filters)
これもフォルダごと圧縮します。
基本は同じですが、filtersが指定できるので隠しファイルを含められます。
QDir::Hiddenを指定すると隠しも含めて保存されます。
QDir::Filesなどを指定すると空っぽの結果になります。なぜだろう......。


 ここまでが圧縮系(compressHoge)の関数です。これらは、圧縮後のパスに既存のファイルを指定すると上書きします。追加ではありません。
 フォルダは無圧縮でファイルは必ず圧縮されます。一般のアーカイブソフトなどですと何らかの条件で圧縮したりしなかったりしているみたいですが、QuaZIPでは一律圧縮です。


QStringList JlCompress::getFileList(QString fileCompressed)
圧縮されているファイルの一覧を取得します。
この後紹介するファイルを個別で解凍するときに必要になります。

QString JlCompress::extractFile(QString fileCompressed,
                                QString fileName,
                                QString fileDest = QString() 
                                )
fileNameで指定したファイルのみを解凍します。
ZIPファイルの中にフォルダがあれば、それも含めて指定します。getFileListで取得したリストの中から選べばOKです。
解凍先を省略するとカレントフォルダに、解凍されます。
指定するとフォルダ構成を無視して指定したファイル名(パス)で解凍されます。

QStringList JlCompress::extractFiles(QString fileCompressed,
                                     QStringList files,
                                     QString dir = QString() 
                                     )
filesに指定したファイルをZIPファイルの中から解凍します。
dirに指定したフォルダに解凍します。指定したフォルダが存在しないと自動で作成されます。
dirを省略するとカレントフォルダに解凍されます。

QStringList JlCompress::extractDir(QString fileCompressed,
                                   QString dir = QString() 
                                   )
dirに指定したフォルダに解凍します。
無ければ作成されます。

 以上です。簡単ですね。
 今回紹介した関数はすべて圧縮ファイルのパスを文字列で与えていますが、中にはQIODeviceを使用して解凍できる関数もあります。
 何となくご理解いただいていると思いますが、今回紹介したクラスはお手軽なのですが、できることが大味です。個別のファイル単位で圧縮したり無圧縮でパッキングだけしたり、と処理を変えたりするには別のクラスを使用しなければなりません。圧縮したけどかえってサイズが大きくなったとかあるので、理想を言えばいろいろ頑張る必要があります。結局のところケースバイケースなのでご要求に合わせて考えてみてください。なので、細かい話はまた別の機会にしたいと思います。  結局、ライブラリを紹介したいのか、*.proファイルの設定を紹介したいのか謎な感じになりましたが、参考になれば何よりです。

冬コミC91に参加します

 サークル「理ろぐ」は、コミックマーケット91にも参加です。
 今回も創作系のエリアで、「金曜日 西地区 "ひ" 02b」です。

 Webカタログでもサークル情報を公開してます。
  https://webcatalog.circle.ms/Circle/13015363/

 今回は西館でサークルが配置されるのは、西1だけなのでなんだか隔離部屋扱いされているようです。
 何となくまったりした雰囲気になりそうですが、企業エリアへ行った帰りにでも寄ってください(西2~4が企業です)。

 本の内容ですが、女子高生と女子高生の犬を通じたちょっと不思議な出会いのお話の予定!
 小説家になろうにアップしている前半と、これからアップする(予定)の後半に表紙と挿絵を付ける感じです。
  ・雨降りの再会
  ・雨降りの発見

 表紙絵をイラストレーターさんにお願いしてしまった手前、書ききらねばなりません(自ら追い込んだ)。
 毎度、自由気ままに書いている本ですが、なにとぞ。
 スペースに遊びにくてくれるだけでも嬉しいので、まだまだ先のようなあっという間な年末にお会いしましょう!

 あと、
 当日は、新刊と既刊の小説を2種類持っていきます。
 既刊(もう無くなってしまったQt本とか)は、BOOTH(https://relog.booth.pm/)で販売していますのでよろしくお願いします。

Qt World Summit 2016に参加してきたよ(旅編)

 The Qt Companyの主催で「Qt World Summit 2016」が10/18~20にサンフランシスコで行われましたので、参加してきました。
 この投稿は、カンファレンス本編以外の旅行に関する部分についてです。つまり、ただの旅行日記的なものです。

 カンファレンス自体の雰囲気レポは「Qt World Summit 2016に参加してきたよ(本編)」を参照ください。

 本編の方でもさらっと触れましたが、基本ぼっち移動のち、現地でSRAのお二人と合流しての行動でした。
 偶然ですが、ホテルもすぐ側で助かりました。


/// 出発~成田空港~サンフランシスコ空港 ///


 帰りの時間の都合もあって成田からの直行便にしました。なので、初めて成田エクスプレスを使いました。意外と快適だった。でも、可能なら羽田が楽で良いなーと思うところ。
 飛行機は、ユナイテッド航空を使ってみました(ANAだと予算オーバー過ぎだったので)。日本との直行便(往復とも)は機内のアナウンスは日本語でもしてくれるし、CAさんに日本語でOKと案内してました。日本人のCAさんは日本語で話しかけてきますが、さすがに外国の方の場合は英語で話しかけてきました。トラブルでも無い限り機内では「飲み物何がいい?」と「食事は○か×のどっちにする?」くらいしか聞かれないので平気ですね。中国語で話しかけられたこともあったような気がする。通じてないと思ったか英語になったけど。CAさんも国際色豊かな感じでした。
 機内では、スナック(あられ)と夕食(アイス付き)と朝食がでました。唐揚げ弁当的なのと、親子丼でしたが、2回ともご飯が底で焦げ付いてたのが、少々残念でした。
 IMAG0250.jpg IMAG0255.jpg
 
 世界の車窓
 IMAG0256.jpg IMAG0263.jpg
 2枚目はサンフランシスコ市街の上空からで、橋はサンフランシスコ-オークランドベイブリッジ、少し横にアルカトラズがかろうじて見えますが、ゴールデンゲートブリッジを写真に入れることは出来ませんでした(市街が見えているの気づくの遅れた^^;)。
 今回乗った飛行機(B747-400)のエコノミーには個別のモニターはなくて、機内WiFiに繋いでユナイテッド航空アプリでコンテンツを好きに見てねってスタイルでした。
 screenshotshare_20161017_175601.png
 
 

/// サンフランシスコ空港~市街 ///


 BARTという電車(地下鉄?)を使いました。
 Clipperカードという日本で言うSuicaっぽいのが便利なの知ってたのですが、BARTの自販機では買うことができず、市街までは普通の切符を買ってしまいました。
 こんなカード
 IMAG0496.jpg
 自分はとある理由でパウエル駅でBARTを降りたのですが、MUNIという市内の交通網(名古屋市交通局的なの)の地下鉄の駅とくっついてて、そちらの自販機でClipperカードが買えます。適当にチャージして使いましょう。
 MUNIのバスとかでも使えるのですけど、チャージできる場所が良く分からなくて自販機だけに頼ろうとすると地下鉄の駅でしかチャージできなくなるのである程度計画的にです。
 なお、バス(路面電車込み)は$2.25で90分間乗れるので、時間内なら何回乗り継いでも$2.25で便利です。
 で、パウエル駅で降りた理由に戻ると、飛行機の到着が午前中でホテルのチェックインまで時間が余っていたので観光したいけどスーツケースが邪魔なので預けるためでした(自分のホテルはフィッシャーマンズワーフのそばだったので、パウエル駅からもう1つ先の駅まで行った方が乗り継ぎ的には本当は便利なのです)。
 預け先は、日航ホテルにあるJCBプラザ(ホテルの壁に埋め込まれている看板はJGAデスクだった気がする。部屋の前にはJCBプラザって書いてあります)です。ここはJCBカードを持ってると荷物の一時預かりとか観光案内をしてもらえます。前回、Google I/Oで行ったときに利用して知っていたので利用させていただきました。
 ただ、JCBプラザの場所がわかりにくいw。ホテルのロビーよりも下の階のこの先関係者のみじゃないの?って雰囲気の廊下の奥にあります。しかも、そこが車で来たときの入り口になっててベルボーイさんが親切に「フロントはエスカレーター昇ってね」って案内してくれちゃうもんだから、気まずいw。


/// 市街観光 ///


 JCBプラザのおねーさんから軽く情報を仕入れつつ、割引券(結局使わなかったけど)とか観光パンフをもらって出かけました。
 行き先は、フェリー乗り場付近。
 
 ここは、ちょっとしたショッピングモールになっていて中に色々なお店が入ってました。
 IMG_4962.JPG
 中にはワインバーとかあって、飲める人だったらここだけで時間つぶせただろうなーって感じでした。ワインの種類もあったのですが、チーズもたくさんの種類から選べたようです。チーズは食べてみたかったけど、ワイン飲んだら身動き取れなくなりそうだったので止めました。
 他には雑貨屋さんとか、いろいろあって、おしゃれっぽいレストランで牡蠣を食べてる人もいました。
 お昼には、メキシコ料理屋さんに入ってタコス(ポーク)を頼んでみたのですが、想像と全然違うものが出てきてビビりました。ひたすら肉でした。
 IMAG0265.jpg
 もたれたお腹を消費するべく、埠頭のあたりをしてみました。
 IMAG0277.jpg IMAG0278.jpg
 IMAG0279.jpg IMAG0280.jpg
 お昼が微妙になってしまったので、再びフェリー乗り場に戻ってきて可愛らしいお嬢さん方店員さんで流行っぽいアイス屋さんでかって口直しをしました(結局なにか口に入れてしまう)。
 IMAG0284.jpg
 思ってたよりは重くなくて普通に食べられました。ケーキくらいの温度感だったらヤバい?


/// ホテルへ~夕食 ///


 街をぷらぷら歩いて、預けていた荷物を受け取ってからホテルへ移動しました。
 IMG_4982.JPG
 ホテルへの移動には路面電車を利用しました。
 IMG_4987.JPG
 使ったMUNIのF路線とE路線のみで使われているっぽい古めかしい車両で中はこんな感じ。
 IMAG0289.jpg IMAG0290.jpg
 右側の写真をよく見てもらうと分かるのですが、ペダルが付いてます。アクセルとブレーキがペダルでした。路面電車という表現をしてしまうとどうしても日本の電車のイメージなので、少し驚きました。分岐のところでは、ボタンを押して方向を決めているようでした。台車を無理矢理、左右のどっちかに振ってるんだろーなーと想像してました。

 ホテルは「Zephyr」というところでした。初めてトリバゴ使って値段比較して調べたよ。
 IMAG0377.jpg
 
 ピア39とかめっちゃ目の前です(海は見えない部屋でしたけどね)。
 中庭がこんな感じになってるハイカラなホテルでした。
 IMAG0380-PANO.jpg

 無事にチェックインを済ませて、SRAのお二方が空港に到着する頃だったので連絡を取って夕食をご一緒させていただく約束をして、だらけてました。
 その後、無事にお二人と合流して近くのレストラン「The Franciscan Crab Restaurant」で夕食でした。
 
 IMAG0297.jpg IMAG0295.jpg
 メニューを見てて、「clam chowder」と「crab chowder」がダジャレだなーとか思ってしまいました。アサリとカニなんですけどね。

 ポケモンGoを少しだけ起動してみたのですが、「ポケストップの近くにいるポケモン」機能が使えました。へぇ~って眺めた程度ですが。
 Screenshot_20161018-230354.png


/// ピア39~ゴールデンゲートブリッジ~デ・ヤング美術館 ///


 2日目は、SRAのお二方はQt World Summitのトレーニングに参加するということで、再びぼっち観光でした。
 とりあえず、朝食は近所のレストラン「Beach Street Grill Organic Restaurant」で朝食。
 
 IMAG0300.jpg

 食後は、少しフィッシャーマンズワーフとピア39のあたりを散歩しました。
 IMAG0302.jpg
 IMAG0306-PANO.jpg

 その後、MUNIバスの90分ルールを使って乗り継ぎをしてゴールデンゲートブリッジへ行きました。
 
 途中、高速っぽいところを使うので20分くらいで到着しました。早いです。橋の手前の展望台?のあるところのバス停で降りて歩いて近づきます。
 橋に歩道もあるので、歩いて渡ることも出来ます。自分は、1本目の橋脚のところまでで引き返しました。レンタルサイクルで反対側まで行く人も居ますし、そもそも市街から自転車で来ている人も居るようです。
 IMAG0328-PANO (2).jpg
 IMAG0333.jpg IMAG0365.jpg

 このあと、バスに乗ってゴールデン・ゲート・パーク内にある、デ・ヤング美術館へ行って来ました。美術館ってぼっちにこそ行くべきところですね。複数人で行くとどうしても見るペースに気を使ってしまうので、安心して見られます。気になった作品があればじっくり見れるし、疲れたら休憩も自由。
 

 美術館を見ていたら、程よい時間になってしまったのでホテルへ引き返しました。
 トレーニングに参加していたSRAのお二方にも連絡を取ってみたところ、ホテルに戻って休憩していたところだったので夕食へ出かけました。
 IMAG0379.jpg IMAG0378.jpg


/// Qt World Summit 2016の1日目の後に少し寄り道 ///


 会場から帰り道にピア39があるので、少し寄り道しました。
 乗ってないですけど、奥にメリーゴーランドがあるんですよね。夜はキラキラです。
 IMAG0439.jpg IMAG0438.jpg
 夜だと見えないよなーと思ってのぞいてみたアザラシゾーンからの夜景。
 IMAG0443.jpg


/// Qt World Summit 2016の2日目の後に少し寄り道 ///


 1日目と違ってパーティがないので2日目は普通に夕方の暗くなる前に終わったので、SRAのお二方からのリクエストもあり夕焼けのゴールデンゲートブリッジを見に行こうとなり行ってきました。
 IMAG0461-PANO.jpg
 IMAG0475.jpg

 その後、有名らしいカニのお店「Crustacean」に行きました。
 
 お店の特製ヌードル(太いラーメンのようなうどんのような?)をカニのゆで汁につけて食べると、めちゃうまいらしいです。
 IMAG0483.jpg


/// ホテル~サンフランシスコ空港 ///


 最終日は朝から空港へ移動して帰るだけでした。
 ホテルのそばの駅(バス停?)から路面電車に乗って、BARTに乗り換えました。ただ、空港方面は途中までしか行かない路線や、惜しいけどちょっと方向がそれる路線があるので、ちょっとだけ気をつけましょう。間違えてもリカバリー簡単ですけどね。電光掲示板見ればすぐ分かります。


/// サンフランシスコ空港~成田空港~自宅 ///


 帰りの飛行機は、エコノミーで3列埋まってたので窮屈でした(行きは3列独り占め)。
 機内食は、焦げてなかったけど、お米の種類が日本のじゃなくて少しパサパサでした。デザートのアイスとか、添えられているパンも出発地の製品のようなので、そのからみでしょう。行きのアイスはグリコだったけど、帰りは知らないところ。
 IMAG0489.jpg IMAG0491.jpg

 成田からは、成田エクスプレスの切符売りが激混みだったのでスカイライナーを使いました。
 IMAG0493.jpg

 新幹線が博多行きだったけど、寝過ごすことなくちゃんと名古屋駅で乗り換えて無事に帰宅できました。

 本編のQt World Summit 2016の方をもう少し身があると良いのですけど、全体としては楽しかったので良しとしたいと思います。
 最後に、SRAのお二方のおかげで、完全ぼっちを回避して楽しい旅行ができました。本当にありがとうございます。

Qt World Summit 2016に参加してきたよ(本編)

 The Qt Companyの主催で「Qt World Summit 2016」が10/18~20にサンフランシスコで行われましたので、参加してきました。
 雰囲気など様子を紹介したいと思います(英語が不自由なので)。
 今回は、一応去年Qt Championということで、参加費を無料にしていただきました。ありがとうございます。

 当初、The Qt Companyの鈴木さんと「一緒に行きましょー」と話していたのですが、鈴木さんは(たぶん)大人の事情で行けなくなってしまったので、基本ぼっちで行ってきました。
 幸いにもSRAさんから参加するお二方と現地でご一緒することができたので、完全ぼっちは回避できたので助かりました。ありがとうございます。

/// 会場 ///

 会場は、サンフランシスコの第27埠頭にある「James R. Herman Cruise Terminal」で行われました。  IMG_5050.JPG  フィッシャーマンズワーフやお買い物で有名なピア39から海沿いを歩いて10分くらいのところです。  地図的にはココです。  

 2階建ての建物で、1階は「企業の製品展示」「打ち合わせブース」「休憩所」で、2階が「セッション部屋」でした。
 1階の休憩所では3日間の開催期間中、朝食や軽食が用意されていました。
 
 セッション部屋は、広い部屋(というか建物のほとんどがずどーんと広い感じ)をカーテンで仕切って小部屋を作ってました。
 セッション部屋はそれぞれにThe Qt Companyの支店のある都市の名前が付けられていました。
 中サイズ部屋はこんな感じ(看板に部屋名とスケジュールがありました)。
 IMAG0405.jpg IMAG0406.jpg
 小サイズ部屋はこんな感じ。
 IMAG0415.jpg
 一番でかくてキーノートが行われたHelsinki部屋はこんな感じ(パノラマ)。
 IMAG0398-PANO.jpg

 カーテンで仕切られているだけなので、ぶっちゃけ隣の部屋の声が聞こえました。
 自分の部屋のスピーカーさんの声が小さめで隣の人が大きめだと、ちょっと聞き取りにくいこともあったのかもしれません。


/// トレーニングデー(0日目) ///


 10/18は、トレーニングデーとして8種類のテーマでQtについて学ぶことができる日でした。
 自分は、参加していないので詳細は不明ですが、グループでディスカッションして発表する形式だったところもあったようです。


/// カンファレンスデー(1日目) ///


 10/19は、 キーノートの各種セッションの日です(スケジュール)。
 キーノートで印象に残っている内容をいくつか紹介します。
 - How the OneDrive Mobile Team uses Qt
  Microsoftの人のお話。事前にタイトルは出ていなかった(と思う)ですがキーノートで話すってことが公表されている時点で気づく事のできる内容ではあるのですが、Qt使われてたんだーと思いました。
  ありがちな要求ですが、UIはそれぞれのプラットフォーム(WindowsMobile/Android/iOS)のネイティブを使ってコアになる部分は共通化したい、かつライブラリが抱負であるというところでQtが選ばれたようです。

 - Multi Screen Sharing on LG Displays using Qt
  LG製品のお話。特にテレビ(サイネージ)とか時計とかwebOSを使っている製品や車の表示系製品についての紹介でした。
  どれも、複数のモニターを連動させて動かせる製品で、サイネージについては16x16のパネルをシンクロさせて動かせるそうです。製品としては「VIDEO WALLS」この辺りとかでしょうか。

 - Rimac Automobili Ltd.の車
  EVの車を作っている会社で、過去にコンセプトカーを作ってモーターショーにも出していたそうです。
  BMW M3 E30をEV化してゼロヨン(11.850秒)でFiA公認記録を取ったそうです(2015年にTesla Model S P85Dが11.6秒でEVの中で世界記録らしいので凄いですね)。
  キーノートではサラッとでしたけど、同じ人が別セッション(Qt Inside the World's First Fully Electric Supercar)でパイクスピーク(山を登るレース)で有名なモンスター田嶋さんの車も作ったよと紹介されてました(レースレポート)。紹介の中でレーシングカーのテレメトリーの画面を少し見せてくれてました。オンボード映像と4輪のトラクション(とブレーキ)のかかり具合も見れて「ほら、曲がるときに右側のタイヤにしかブレーキかかってないときあるでしょ?これで上手に曲がるんだよ」ってQt関係ない話しもありました(そのセッションは車の紹介でほぼ関係ない話しだった気がするけど)。

 各セッションは、以下の分類がされていました。
 - Built with Qt(11件)
 - 0 to 1(5件)
 - Automotive(8件)
 - Future proof(6件)
 - Advanced(4件)
 事例ベースのお話だったり、今後の話しだったり、盛りだくさんでした。
 「Built with Qt」はある意味「その他」的な分類と思われるので数が多いのは当然として、件数を見てもらうと分かりますが「Automotive(自動車関係)」が多めでした。他にはVR系のセッションも人気があったそうです。

 車関係だと「Qt Automotive Suite」は良いぞってのもありました。車のメーターとかセンターコンソールとか作るときに便利よって感じでQMLを使うとこんな感じでアプリケーションを起動できるとか紹介してました。
 他の車系のセッションでは、メーターのアナログ計(スピードとか回転)は60fpsないと滑らかに表示できないし3D表示もあるから低コストに使用とすると大変だったよって話しもありました(i.MX6DL・DDR3(32bit)・LCD(1920x720)でメモリバスの転送が大変だったそうです)。で、60fpsで描画するところと逐次で更新するところを分けて工夫したりで何とかしたそうです。あとは、起動速度の話とかいろいろ。
 いろいろなツールを使って効率化をしているよって話とか。

 昼食は、裏の海沿いの場所に屋台的な車(市内でもときどき見かける)が4台くらい来ていて好きなのを食べてねって感じでした。
 休憩中にSRAの方と話していたら凄い流暢な日本語でベトナム人の方に話しかけられました。7年くらい日本に居て、今は同じ会社のアメリカの支店にいるらしいです。
 
 夜は1階の軽食を出していたところを使って、立食パーティーでした。
 建物の裏というか海側が解放されていて、結構寒いのですが、外でずっと話している人たちもいました。日本人は朝晩は寒くて上着を着ているのに西洋人すごいよ(笑。
 パーティー中に、東京で働いているというパキスタンの人に話しかけられFacebookで友達になったり、日本に興味があるという中国の人と話したりとミラクルがありました。というか、日本語で積極的に話しかけてくるの凄いです。
 
 会場裏から見えるサンフランシスコ-オークランドベイブリッジの夜景
 IMAG0425-PANO.jpg


/// カンファレンスデー(2日目) ///


 10/20は、1日目に引き続いてキーノートとセッションの日です(スケジュール)。
 
 二日目のキーノートはThe Qt CampanyのCTOのLars Knoll氏が最初でした。
 特に気になったところをピックアップです。
 - オープンソース版・商用版のどっちでも動く製品への対応(ChartとかオープンソースになったのもあるけどGPLだから気をつけて)(これはちょっと誤解があるかも)
 - C++の新しいバージョンにも対応していくよ(現在はC++11で14/17と続いていく)
 - OSサポート(macOSやiOSの最新版、tvOS/watchOSへの対応)
 - 通信系の対応強化
   HTTP/2をQt Networkで対応
   Qt Serial BusでCAN
   Qt Network Autentication module(TP)でOAuth 1&2に対応(これ嬉しい)
 - QMLのJIT on WinRTと64bit ARM対応
 - Qt Quick COntrols 2でパフォーマンスアップ(これは前から言われてるけどね)
  MaterialとUniversalスタイルに対応して個別のデスクトップスタイルは無しになった
 - Qt Webengine(印刷、ドラッグ&ドロップ、DRMメディア用プラグイン(widevine plugin)対応)
 - Qt Liteの目標(小さいフットプリント、速い起動、OpenGL無しなど)
 - Web関連(C++コードをブラウザで動くようにコンパイルできるようになるらしい。開発中で今、alpha版くらい)(この辺りの話しかと「Qt for Native Client (and emscripten)」)
 - リモートディスプレイ関連(Qt 5.8でVNC対応)

 2日目の各セッションは以下のように分類わけされてました。
 - Success(10件)
 - Performance Optimizations(5件)
 - Qt Roadmap Today(6件)
 - Qt Roadmap Tomorrow(5件)
 - Qt Tips & Tricks(5件)

 
 通常セッションでQt Liteについて2コマで概要とツール関連がありました。
 こちらも気になったところを箇条書きにします。
 - 冒頭の振り返り的なところでEmbeddedで使われたQtとしてZaurusの写真が!(箇条書きの中にNokia N9もあったけど)
 - これくらいのスペックで~という話し(ARMv7 ~300MHzとか、QMLでモダンなUXだけどOpenGLなしとか)。
 - 容量を60%は小さくするよ
 - Qt Liteの設定ツールの目標(自由度を上げる・管理を簡単にするなど)
 - qmakeを使う
 - 設定にJSONの対応
 - 新しくGUIツール作る
 - QML Samegameを例にすると
   5.6 dynamic 25MB弱
   5.6 static 14MBくらい
   5.8 dynamic 25MB弱
   5.8 static 10MB弱
   5.8 Lite 5MB

 Qt Quickの描画エンジンでDirect 3D 12の対応もしている話もあり。Vulkanの対応?まだよ。もしかしたらQVulkanWindowとかかなって話題とか。
 Qt Creatorの導入ってセッションもあったので、某氏が本を書いているのでネタを少しくらい拾えるかなーと思って参加してみました。主に便利なショートカット覚えようぜがメインだったのですが、セッション機能とか、Q_PROPERTY(~)からメンバ各種を生成できる機能を初めてしって衝撃を受けてました。
 WindowsのUWP関連の話としては、前半は「Status Update on Qt for WinRT / UWP」に書いてある内容なのかなーと思いつつ、(ちゃんと読んでなかったので)Hololensやxboxも対応するんだーと見てました。5.8の対応としてD3D12バックエンド対応などと、5.9での対応として印刷やFile I/O v2(ってなんだ)など上げられてました)。あとは、ストアについてとか。アプリへSDKバージョンを設定方法(Windows 10の細かいバージョンの違いに合わせて適切に設定する方法)とか。
 Qt Quick Control 2の紹介してくれているセッションはスライドの字が小さすぎてツラかった。でも、スライドの中に動くUIが埋まってました(どうやって実現しているのかはサラッとしゃべってたのか・・・・・・)。


/// 展示など ///


 展示は、こんな感じでした。
 この写真の反対側(という左の方)に自動車関係が多くメーターパネルを展示しているところがずらっとありました。
 IMAG0452.jpg
 一角では、LTスペースもありました。 
 IMAG0451.jpg

 日本から来て展示している企業さんもいました。「sdtech」さんで唯一まともに話ができました(そりゃそうなんですが)。
 デザイナーさんと技術屋さんとの橋渡しとして、Illustratorで作ったモックをQMLに変換して、Photoshopで取り込んで画像を作って再出力、そしてQt Creatorで読み込んで実行という流れができるAdobe系のプラグインをデモされてました。凄いなーと思いましたよ。


/// まとめ ///


 基本的に画面関係はQt Quick前提でした。そーいう流れだってのは聞いてましたが、実感できました。
 特に車関係のところでQMLで画面を作って~って感じの話が聞けたので、UIは実際にQMLへ移行していってるんだなーという印象です。
 日本で話していると、なかなか移行できずにいるのを感じていた(耳に入る範囲なのでごく一部ですが)ので、最先端は違うなと思いました。
 それでも、ここ最近は徐々にQML使ってるよって話しも増えているので、皆さん恐れず使って欲しいですね。

 もっとちゃんと英語で説明されている内容を聞いてまとめられると良いのですけど、雰囲気だけでも感じていただければと思います。
 (その割に、以外と写真を撮り忘れてて、ダメダメですね。書いていて受付の写真忘れたーとか色々です)

電子書籍(epub)作成ツール「LeME」はQtで作ってます

 先日、リリースしたLeMEですが、いつものようにQtで作りました。
 ソースは今のところオープンにしていないですし、オープンになってても実際に中身を見てみようと思う方は中々いないと思うので、少し紹介です。
 これからのQtアプリ(どれくらいの規模に耐えられるのは分かりませんが)のスタンダードな作り方になるんじゃないかなーと思います。
 あくまでも構成的な話しなので、具体的な実装方法とかは今回はないです。

/// 構成 ///
 ざっくりと構成を図にすると下のようになります。
 path4250.png

 それぞれをざっくり説明するとこんな感じです。
①UI
 UIです。QMLを使用します。
 Qt Quick Controlsも2.0になって、ますますパワーアップして使い勝手が良くなってます。今回は使用していませんが、マテリアルデザインにさくっと変更することもできます。
 Qt Quickデザイナーが復活してhoge.qmlとhoge.ui.qmlという2つのファイルを組み合わせてデザインとロジックを分離する方式の作成方法も使用しました。
 レイアウトについてはRowLayoutなどが追加されてから、いろいろ強化されているのですが、デザイナーが使えるようになってわかりやすくなったと思います。

②読み書きクラスとのI/Fエレメント
 ユーザー操作や設定などを読み書きクラスへ届けます。逆に結果をユーザーに届けたりします。本の情報とかを保存したり、読み出したりと簡単なことをC++で書きます。
 他には、本に変換するコンテンツの一覧を管理するモデルクラスも作成します。それ程小難しいことはしませんが、ファイルの種類をQML側に伝えたりUI表示に必要な情報を提供します。

③読み書きクラス
 Wordファイルを解析したり、epubファイルを生成したりします。ここはC++のみでゴリゴリいきます。

④Qt Quick標準エレメント
 標準のエレメントです。見た目の部分をQMLで書かれていたりもします。

⑤Qt標準クラス
 言わずと知れたQtが提供する豊富なライブラリ群


/// Qt Quickデザイナーを使用するときの小ネタ ///
 見た目のないエレメントを配置すると左のツリーで思った通りの操作ができなくなります。
 文字通りツリーに表示されないのにいる扱いされて良く分からなくなります。
 なので、*.ui.qmlに見た目のないエレメントを手書きしないのが無難です。*.qmlをデザイナーで編集するときは注意しましょう。

/// まとめ? ///
 UIはQMLで作ります。
 アプリケーションのメイン機能はC++で作ります。
 見た目のない(今回の②)は、とても簡単です。まずは、この辺りから試して見ましょう。
 標準で用意されていない見た目を作りたいときはC++でエレメントを作ることになります(今回はない)。
 C++の部分は、今までどおりのQtプログラミングです。

 今回のソースコード8割弱はC++でした(Githubのリポジトリで表示される数字)。
 QMLかーと思っていても大丈夫です。全体から見ればそうでもないで安心してください(本当か?アプリ次第ですね)。
 ちょっと不安だなーと思われましたら、「Qt Quickを使いこなすクロスプラットフォームUIプログラミング+」という本があります。良ければ、どうぞ。

/// おまけ ///
 配布に使用しているインストーラに「Qt Installer Framework」を使用しています。
 こちらは、ちょこちょこっと設定ファイルを書くと簡単にインストーラを作成できます。
 ちなみに、解説書の「インストーラを作ろう!」と「インストーラを作ろう!!」があります。良ければ、どうぞ。
 作成方法と自動化で前後編になっています。

 作りました。
 夏休みくらいからチマチマ作業を進めて、いったんリリースしました。XMLとXHTMLとの長い戦いでした^^
 最初は、小説がルビ付きで変換できれば、いいやーくらい思っていたのに随分Wordファイルを再現できるようになってしまいました。
 それでも、いろいろ足りないところはあるかと思いますが、結構頑張ってます。
(だってー、某太郎さんのepub出力で画像の扱いが思い通りにいかないんだもん。挿絵が変なふうにしか出力できないんだもん)
 いつもは、アプリを作ってもこのブログで適当に配布していましたが、専用サイトっぽいものも作って見ました。

 公式サイト:LeME -Let's make ebooks!-

 上記のサイトにも書いてますが、作れる本は
 ・小説など文字が中心の本(縦書き)
 ・技術書など文字が中心の本(横書き)
 ・漫画、イラスト集、写真集など画像が中心の本
 です。

 売りっぽいところは
 ・Wordファイルの変換(Officeインストールしてなくてもできます)対応
 ・BOOK☆WALKERさんのめがイラスト(巻頭のカラー口絵で横にスクロールするやつ)対応
 ・リフローの縦書き・横書き対応
 ・QtなのでLinux系やMacへも移植が簡単(Linuxでは動くのは確認してます)

 漫画とか画像を並べるだけのは割と簡単なんですが、テキスト系はちょっと大変でした。
 Wordだと表とかスタイルとかいろいろ勉強になりました。Wordは2007からOffice Open XMLという形式(docx)なったため、ファイルフォーマットが誰でも知ることができるようになりました。なので、実現出来たわけです。.NETを使えばもっと簡単なのですが、クロスプラットフォームに一応したかったので。
 ファイルフォーマットについて知りたい方は以下のサイトを参照してみてください。

 ・Microsoft:Office Open XML と ECMA-376 仕様
 ・Wikipedia:Office Open XML

 注意事項としては、Wordファイルのすべての機能に対応しているわけではないので、思い通りな結果にならないかもしれないと言うことです。あと、epubに変換する上で不要だと思われる内容もそぎ落とす方針で進めてます。
 図が変換できないのが、現状の最大の弱点でしょうか。簡単な図形からだけでも変換できるようにしたいなぁ。ところで、図が「ここから下はアプリ独自に定義できるタグね(僕の解釈が間違ってなければ)」ってところにあることなんですが、なんでですかねぇ(棒

 最後に、今回のアプリは(使ってもらえたら)商売に直結できるので、課金要素を追加しました。基本無償ですが、本の最後に必ずロゴが入るようにしています。課金すると外せるようになります(早く課金方法を作らないと・・・)。

 もし、興味がある方はお試しいただけると嬉しいです。
 ご意見ご要望は随時受け付けてます。聞き遂げられる保証はありませんけど・・・・・・(これはいつもどおり)。


 夏コミの新刊情報のお知らせです。
 今年もなんだかんだと小説を続けてます。継続が力になると良いですね。
 さて、本作も「小説家になろう」に投稿している作品の書籍化です。
 表紙と挿絵が入りますので、お得度アップです。ぜひ、手に取って見てほしいです。
 当日、スペースにてお待ちしております。


販促用(表紙のみ).jpg

/// 情報 ///
サークル名:理ろぐ
場所:水曜日 東パ14a
ページ数:228ページ
予価:800円
著者:あやねいおり
イラスト:ましろ.あー。(pixiv)

/// 内容 ///
少女はひとり世界の終焉を見ていた。
それは、幾度となく繰り返され、そのたびに悲劇を目の当たりにする。
終焉を避けることはできず、いつしか目の当たりにする悲劇にすら慣れてしまっていたころ。
ひとりの少年との出会いを境に事態は好転する。
そして、同時にある感情が芽生えていた。
少女は、その感情と、世界の行く末を変えた理由を知ることになる。