QtとWindowsと流川ガールズと

Qtと沙織さんのお話。

Creatorも含めてQtでコードを書くと言うのは基本的にプラットフォーム依存を少なく出来る、と言う利点があると思うのだけど、実際は書いてると結構出てくる。別件で書いてるOpenGL周りのコードもQt+Creatorを使っているけど、そりゃあもうね。

なのだけど、saoriに関しては当初から「できるだけQtに依存して同一コードを以って特定環境で動かないところを無くしてみよう」と考えて書いております。まあ、いつまでこれ続けられるかは謎ですけどねえ。
結果、実は現状同じコードでWindows上でも動きます。


素敵ですねえ。
まあandroidは素晴らしいクライアントが存在するから試す気も無いし、アポー系は宗教上の理由で試す環境が無いのでWindowsしか試してませんが、Windwos10のノートPCで出先で思いついた修正をさくっと出来て試せるのはそれだけでも素晴らしいし便利ですねえ。

とは言え、既に問題は見つかっていて、例えばWindowsでQNetworkReply::readAll()が空な場合がある、とかね。色々調べた結果どうも一定データ量を超えるとダメっぽくて、最終的に落ち着いたのが「タイムラインの取得量(limit=で指定するんですが)を若干小さくすることで回避」だったりします。内部バッファ量の違いかなーと思ったりもするんですが、このへんはQtのコード見てみないとなんとも。Windowsの場合OpenSSL周りも別個用意してたりするわけだったりするのでこの辺の差もあるのかも。

もうひとつはまりかけたのが、変数長の違い。
statusのidを保存するのに最初longを使ってたのだけど、どうもWindowsだとおかしくなる、結局qlonglongに落ち着いたのだけど、後で気になってlimit.h見てみたら、linux(64)だとlong=longlong、Windows(64)だとint=long、うおおおい!って感じ。難しい。

まあどこまで頑張れるかは分かりませんが、一応Windowsでもコンパイルして動かしてみてますよと言うお話。

Qtとmastodonと糞コードと流川ガールズと

お久しぶりどころか、あけましておめでとうですが、すっかり春めいてといいますかやや暑い日もあったりする梅雨前のひととき、皆様いかがお過ごしでしょうか。

えーとりあえずmastodonクライアントを昨年から作ってて本当は年末には見せびらかす予定だったんですけど、色々バタバタしまして気がつけばゴールデンウィークですよ。まあいいんですけど。
と言うわけで、機能足らなすぎで作りかけ感満載ですが、

沙織さんです。見ての通りマルチアカウント対応のMDIクライアント。名前の由来は特にありませんが、俺は流川ガールズが大好きです。

現状できることと言うのは本当に少なく、インスタンスに接続して一部タイムラインや通知を読み出すくらいです。Tootもまだ出来ませんし画面には機能しないボタンが並んでいたりしますが、まあmastodonにおけるごくごく基本的な「認証してアクセストークンをゲットしてJSONデータを得る」は実装されております。

コード化結構簡単ですので是非皆さんも手作りmastodonクライアント挑戦して欲しい感じですかねえ。まあ色々勉強になったところもあるので、何回かに分けてこのへん日記にまとめようかな。

以下、認証まわりのコード的な話。

twitterクライアントもそうなんだけど、ぶっちゃけアクセストークンを取得してAPIに正しくアクセスできれば後はデータをいじるだけ、mastodonはJSONでデータくれるのでQtのQJsonDocument他をごっそり使うことで手軽に得たデータを利用できます。素晴らしいですねえ。

ポイントはどうやって認証するのって話ですが、saoriでは

  1. Saoridonクラスでクライアント登録。
  2. SaoriAddAccountDialogで認証、アクセストークン取得。
  3. SaoriAccountに情報を保存、アクセス時もここからAPIにアクセス。

こんな感じの流れになってます。

相変わらずコードにコメントを書かない糞コード書きなのでわかりにくいですが、Saoridon::clientRedistration()でクライアントをインスタンスに登録します。
若干ずるのようなイメージもありますがQEventLoopを回してQNetworkAccessManagerからのQNetworkReplyをその場でもらうと言うテク、これ便利で結構使ってしまいますがさておき。

登録が済んだらclient_secretとclient_idがJSONで帰ってきますので、今度はSaoriAddAccountDialogでアクセストークンを取ります。実際は上のクライアント登録もこのダイアログでやるんだけどね。
Saoridon::getAuthorizedUrl()でURLを作りWebブラウザで開いて認証、コードをコピーしてそれをSaoridon::getAccessToken()で渡すとアクセストークンが返ってくる、と言う手順ですねえ(grant_typeはauthorization_codeです)。SaoriAddAccountDialog自体はボタンを押せなくしたり複雑に組んでありますが、実際に必要なコードはSaoridonの方にほぼほぼまとめられています。

で、client_idとclient_secretからaccess_tokenとれたらそれをSaoriAccountに保存し、実際のAPIアクセスはこのクラスからアクセス、と言う感じです。
アクセストークンはヘッダにぶち込むだけでいいのでSaoriAccount::createHeader()を見てもらえば簡単かと。あとは、mastodonのAPIとにらめっこどぞー、って感じですね。

ここまでくればQNetworkReplyでJSON取れますからあとは煮るなり焼くなり。QJsonObjectで取得してHTMLに整形してQTextBrowserに流しこむ、と言うことをsaoriではやってますが、この辺はまた今度。

QtとC++でモダンなOpenGLプログラムを書いてみる

shaderを基本としたモッダーンなOpenGLプログラムをQtとC++で書こうって話。Qt5.9を使ってますが5.7あたりでもいけるんじゃないでしょうか。compute shaderがサポートされたのは5.9からのような気もしますが、別にQOpenGLFunctions_4_3_Coreとか使えばそれ以前からも使えないことはない…まあ、そのへんはいいか。

QtでOpenGLを使うと良い点と言えば、とりあえず色んな環境で動くようにコンパイルできることとか、ウィンドウ操作周りやらマウス入力系等をQt一式に任せられるとか、おなじみsignal/slotでのコードが書けるとか、まあ色々ありますが、個人的にQt大好きっ子ですので「かっこいい」が一番ですかねえ。
と言うことで、QtっぽくOpenGLのコードを書くぜーと言う感じでGo。

続きを読む

Qt5.5開発環境をWindows10にぶちこむよ

前置きはいりません、はいぶち込みましょう。

コンパイラはVS2013Expressにします。2015はいけるんでしょうか。分かりません。

Qtぶちこみます。VS2013の32/64bit版でいきましょうか。

QtCreator立ち上がるぜ。

早速サンプルをコンパイル。簡単なものですねえ…。

以上。簡単ですねえ。

「お前それkubuntuでも同じこと言えんの?」

 って言うAAを思いつきました。まあどうでもいいですね。

 OSのアップグレードを即やるなんてモグリですよ多少あらが出きってからアップデートするのが通でしょ推奨されてますし。と、俺も思うのですけど、なら何故しつこくなんども「新しいディストリビューションアップデートが利用できます押せ」と定期的に通知されるんですかやめてくださいよ押しちゃうでしょう。
 と言うわけで。押しました。
 
 で、kubuntuの13.04のアップグレードのお話をするわけですが、俺はひねくれておりますゆえ以下のような前提があることは留意していただきたい。
 まず、ATOKX3ユーザでございます。
 そして、Qt大好きっ子でございます。
 以前のバージョンでもKDEのアップデートはちゃんとしていたので最新KDEの乗った12.10からのアップグレードです。
 ではどうぞ。
 
 今回のアップデートは普通のubuntuだとちょっと速くなったくらいの差だそうです。まあ、使ってないのでそのへんはわかりませんが、kubuntuの場合さり気なく大きな違いが出てきております。
 それは何か。簡単な話です。Qt5がまざっとります。
 
 Qt5が混ざること自体は大した問題じゃない、ぶっちゃけどこに混ざったのかもよくわかんないかもしれないし気にならない人には全くどうでもいいことに思えるかもしれませんが、先に上げた「前提」を見て頂ければ簡単な話ではないと言うのはなんとなく想像つくかと。
 具体的に言いますと、Qt5でどうやってATOKX3で入力するんでしょう?と言うお話です。結論から言ってしまうと、俺はibus-mozcへ渋々移行することとなりました。
 
 実はアップグレードする前からQt5向け開発環境の整備を渋ってたのも理由はこれだったんですよねえ。まあ、来るべき時が来ちゃったのかなあと受け入れることにしますが、もしもそれでもATOKを使いたいのであればQt5のみibusを使うかたちにしてgtkとQt4はiiimとximでーって方法も、できなくはないですねえ。/usr/share/im-config/data/あたりのファイルをごにょごにょ・・・。
 で、このQt4/Qt5の壁にぶちあたるアプリケーションはなんだ!って話なんですが、ぶっちゃけますとqtcreatorです。やべえ俺的にchromeに継いで使うアプリケーションじゃないですか。因みにchromeは主に可愛い眼鏡の女の子のイラストを見るのに使われていますとかそんなことはどうでもよろしい。
 
 まあ、Qt5とQt4ってぶっちゃけそんな大幅なコード修正を強いられることも無く移行できる感じで、過去にあったQt3→Qt4の思い出すだけで血の涙が出そうな感覚とは随分違います。このへんは皆様誤解しないで頂きたいところです。対応するプラットフォームも増えましたし、Qt4からQt5に移行するのは全く問題ない、むしろ推奨されるべきところかとも思うのですが、やはり混在となると色々問題がねえ。そしてこのバージョンのkubuntuは、ちょっとばかし混在しとります。まあQt4向けのqtcreatorをコンパイルして突っ込むってのもありなんですけどね。
 ただまあ、Qt5でximが使えるように整えられるかどうかはわかんないし、正直整える方向が正しいのかどうかも俺にはちょっとわかんないですねえ。まあどっちにせよ、iiimqcfもありませんからQt5でATOKX3使った入力は諦める方向になりますねえ。
 
 で、それはおいといて。
 
 kubuntuのページを見ていただくとドヤ顔で「新しいスクリーンマネジメントツールだぜヒャッハー!」と紹介されているツールがありますが、すいませんapt-get remove kscreenとかさせて頂きました。理由は今までのディスプレイ設定で調整してあるデュアルモニタ構成を起動時に毎回キレイに上書きして下さるからです。ぱっと見とてもわかりやすいツールに見えますが、何故既にあるものを作りなおしたのかは俺にもまあよく分からないところですねえ。とりあえず余計なことされるのは困っちゃう。
 
 もうひとつ。
 これはkubuntuのアップグレードでってことではないのですが、スクリーンロックがどうやっても無効化できないって謎の問題を抱えているような気がしますねえ。正直KDEのコントロールセンターの配置って物凄くわかりにくいところがあるんですが、例えばスクリーンロックやスクリーンセイバーに関する設定って「ディスプレイとモニタ」以下にあったりする(以前はまた別のとこにあった気がするなあ)わけですけど、こことは別に電源管理のところにもロックに関する項目があります。前者は単に一定時間触らなかったときのソフトウエア的?な設定かと思うのですが、後者に関しては例えば電源状態に合わせて一定時間触らなかった時の設定ってのができる・・・・ってわけわからんでしょもうw。
 で、この後者のほうがどうも設定反映されないところがあるような感じですかねえ。On AC Power時のタイムアウト時間を無効にしても開きなおすとやっぱり元にもどってる。powermanagementprofilesrcあたりに記録されるんだろうなあと見てみてもどうも残っていなかったり。
 電源管理の方はActivity SettingsでUse separate settingsを選んでチェックを外していけば一応無理やりロックかかるのは外せるみたいな感じですねえ。この辺、謎です。まあ、設定が反映されないのはバグなのかなあ。ちょっと探ってみたいところ。
 
 あとちょっと気になった点としては、果たしてibusをremoveしたい人がいるかどうかは別として、ibus消そうとするとkde-l10n-jaも消しにかかるのはちょっと驚いた。いやまあ、組み合わせとしては大多数が使うんでしょうけどさあ・・・。
 
 まとめます。
 
 えっと、今までのkubuntuですんなりすべてがスムーズに進んだことがありましたか?と言う前提でお話しますと、今回も今までと変わりません。以前までを上出来とするならば今回も上出来。
 kubuntuのいいところはubuntuの便利さの上でそれなりに最新のKDEをぶん回すことができると言う点だと思うのです。とはいえ、もちろんkubuntuにしかない実装もちょろちょろあるわけですし(muonとかもそうですねえ)完全な生KDEではありませんがそれらがとにかく使えるように整備されているってところは相変わらず素敵。KDEのアップデートも比較的簡単につっこめますしねえ。
 今回はTAMはATOKを諦めると言う悲しい選択にはなったのですが、正直これレアケースのような気がします。12.10をそんなにいじらずに使ってたならそのままアップグレードでいいんじゃないですかねえ、わかんないけど。
 まあ、もしもQt5が入ってきて過去のKDE4.0とかをフラッシュバックしちゃったりする人がいるなら、そのへんはATOKX3使ったりしてない限りは安心していいんではないでしょうかねえ。まあ、KDE5が出たらまたわかんないですけど、少なくとも自分で書いたQt4向けコードはほとんどが小さな修正でコンパイルできて動いてますからねー。楽観視しておりますよ。

KDE上でのQtのフォントおかしいよね

 おひさ。
 と言うわけでお題の通りでKDE上でのQtアプリケーション(KDEアプリケーションを除く、ね)のフォントってなんかちょっとおかしくね?を直すパッチ。ばっつりかいつまむよ。
 因みに対象はkubuntu 11.10、Qt-4.7.4でございます。
--- a/src/gui/kernel/qapplication_x11.cpp
+++ b/src/gui/kernel/qapplication_x11.cpp
@@ -936,6 +936,7 @@
             // Override Qt font if KDE4 settings can be used
             if (X11->desktopVersion == 4) {
                 QSettings kdeSettings(QKde::kdeHome() + QLatin1String("/share/config/kdeglobals"), QSettings::IniFormat);
+                kdeSettings.setIniCodec("UTF-8");
                 fontDescription = kdeSettings.value(QLatin1String("font")).toString();
                 if (fontDescription.isEmpty()) {
                     // KDE stores fonts without quotes
 見ての通り1行です。お疲れ様でした。
 kubuntuならパッチ当ててlibqtgui4だけ入れ替えればいいかと思います。

QNetworkAccessManagerでtwitterに凸

ネットワーク上から何かしらデータを持ってくる作業と言うのは時々出てくるわけだ。twitterクライアントにしてもQOAuthでOAuthはパスできたにせよ、そのURLからデータを持ってこないとAPIアクセスはできないわけで。

と言うわけでさくっとwgetのような感じでURLからもってこいやあ!ってな実装。

  1. QNetworkAccessManagerを用意します。
  2. QNetworkAccessManager::finished(QNetworkReply*)と言うシグナルと適当なスロットをconnect。
  3. QNetworkRequestを作ってQNetworkAccessManager::get()を叩く。
  4. スロットでQNetworkReply*をあされ!。

以上。

やることはQNetworkRequestを作って読み込み開始してあとはシグナル待ちだけで済むって言う。シンプルやなー。素敵。

QNetworkReply::readAll()でもってきたデータをQByteArrayで拾えたりします。QNetworkRequestにQOAuthで作ったtwitterのAPIに渡すURLを指定してやればあっさりAPIにアクセスできるのよ。

んで拾ってきたXMLを解析してprofile_image_urlを同じようにQNetworkAccessManager経由で取得してやると、

あっさりアイコン付きに。

余談。

profile_image_urlの表示にQGraphicsWebViewを使ったらどうなるのかな?、とか思ってやってみたのだけど、普通に表示されました。が、rotateしたときに画像は回転しているものの枠が残っちゃうのよね。なのでQImageで取得した上でQGraphicsPixmapItemに。

QGraphicsItemはQObjectじゃないよなー、どうやってQImageのやりとりしよっかなーとか考えたり。アイコン一つ表示させるためにわざわざ取得用クラスを作ったり、地味に手間かかったやんよー。

「そもそもなんでお前はそんなに回したいんだ?」って感じですが、なんでだろう。でもなんかQGraphicsViewを折角使ってるんだし拡縮したり回したりしたいじゃんよ!。

QGraphicsViewでtwitterに凸

と言うわけで前にも言ったけどQOAuth使ってtwitterからXML取れてQDomDocument使ってtweetをクラスに放り込めたのであとはお好みのUI組み込むだけで俺仕様のtwitterクライアントのできあがりとなっちゃう。tweet自体をメモリに取り込んでるわけだからそこから検索するなりスコアリングするなり好きにできるのでもうつぶやきに埋もれて窒息することもないぜ!、とまではいかないけども。

で、UIの話。

普通にdesignerなんかでUI作ってもいいんだけど、折角ですからQGraphicsView使おうぜ!と言う方向でちと遊んでみる。

QGraphicsViewのいいところは通常のレイアウトを使ったWidgetの配置と違ってその自由度の高さってことになると思います。逆に言うと自由であるが故にぐちゃぐちゃにもなるって感じ。

線やテキストなんかをシーンに配置して、そのシーン(QGraphicsSceneかな)をQGraphicsViewに結びつけて表示、表示するオブジェクトに関してはQGraphicsItemと言う形でアクセスする、って感じなのですが、これがQWidgetも置くことができるわけで。アクセス方法がQGraphicsProxyWidgetってのになりますが。

ざっくりと表示例を上げると、

どーん。QLabelを使ったWidgetがscaleとrotateされてならんだりとか。

で、こいつらWidgetなので当然ボタンとかを配置して押すこともできたり。楽しいですよね。

ただ、回転なんかをかけ始めるとどうも動作が重く。そりゃそうだわなーと言う感じですが、assistantなんかを参照していただければ分かるのですが、QGLWidgetを使うこともできて、そっち使うと結構早いです。しかもQGraphicsView::setViewport()でQGLWidgetをnewして渡すだけ。

くるくる回したりズームさせたり。UI作りって楽しいですよねー。まあ、ほんと一歩間違えればぐっちゃぐちゃになるけどね!。

QDomDocumentでtwitterに凸

QDomDocumentのサンプルコードはQDomNode→QDomElementと変換してってコードになっとおけど、QDomElement::firstChild()じゃなくてもQDomElement::firstChildElement()なんて言うそのまんまの名前のものもあったりして。こりゃ使うっきゃない。どうしてもだらだらしがちだしね。

以前のQOAuth周りでゲットできたXMLをざざざーっと適当な構造体配列に突っ込む感じで。

ぶっちゃけOAuth経由でアクセスできて、XMLが取得さえできてしまえばあとは正直どうとでもなる。適当にメモリ上に格納できてしまえばあとは煮るなり焼くなり好きにした上でUIでもつけりゃtwitterクライアントのできあがり。まあ、投稿部分スルーしてるけどね。

以前上げたQOAuthのんと組み合わせれば簡単なコマンドライン型クライアントとかならさくっと作れるんじゃないでしょうか。俺は作りませんけどね。

しかしtwitterの吐くXML、status毎にuser情報持ってたりとかしていやに長い。できるだけ一回のアクセスで情報を流すって工夫だとは思うんだけど、RT元とRT自体の情報を1つのstatusが持ってたりとかするのね。いいのか悪いのかは分からんなあ。まあ取り込んで解析さえしてしまえば同じっちゃあそうだけど。

さて。

例によってかいつまむよー。ちょっとだらだら長いよー。

続きを読む