hakeの日記

Windows環境でプログラミングの勉強をしています。

QListViewの色 - C++で試す

Ruby/Qteでは現状無理そうなのでC++で試してみたら、あっけなく出来ました……orz。といってもC++でのプログラムはやたらに面倒なので、Ruby/Qteでも動作するようになるといいなぁ。


違う話になるけどこのプログラムでメインのWidget部とQListViewItemを継承したクラスを同じファイル内に書いてコンパイルしたらmoc_hoge.cppでエラーになった。やっぱクラス毎には一つのcppファイルとhファイルという構成で書かないとダメなのか?

追記

よくよく考えたらクラス毎に分けた方が部分的な修正を加えた場合にコンパイル時間が短くなりますね。ザウルスのセルフコンパイルの場合、重要な要素だ(笑)

QListViewの色

いくつかのブログでザウルスのRuby/QteではQListViewに色がつけられないと書いてあったので自分も挑戦してみる。
C++サンプルをみるとQListViewItemを継承したクラスを作ってpaintCellをオーバーライドしてQColorGroupの色指定を条件により変更すればよいみたいなのですが上手くいきません。前にQWidget上に線を描いたときにはpaintEventで描画処理しないと上手くいかないことがあったので、そっち方面でもあたってみたけどやっぱダメ。
というわけで見事玉砕です。どなたか上手い色付けの方法ご存知ないでしょうか……やっぱ機能として実装されていないのでしょうかね。

ウィジェットの配置 - QGridLayout

Ruby/Qteの勉強 その39
昨日のBigDecimalを利用して簡易電卓の作成、一応表示桁数は20桁としてみる。
QGridLayoutの使用方法は、あさあさみっくすさんの公開メモを参考にさせていただきました。
ウィジェット配置用に6×4のグリッドを作成、その内LCD表示用に0行目全体を使用

# 部品配置用グリッド 6x4
@v = QGridLayout.new(@f, 6, 4, 10, 10, 'grid')

# LCD表示部分
@lcd = QLCDNumber.new(MAX_DIGIT, @f)

# グリッド1行目(0,0)-(0,3)に配置
@v.addMultiCellWidget(@lcd, 0,0,0,3)

下のグリッドにはそれぞれに入力用のキーとなるQPushButtonを配置していく。QGridLayoutは複数のグリッドにまたがってウィジェットを置く方法さえ知っていれば、画面のデザインが簡単にできるので非常に使いやすいクラスだと思います。
最初キーの行数は少ない状態で実行したところQLCDNumberが縦方向に拡大されて表示してしまったので、.setRowStretchで0行目の優先度を下げていたのだけれども、キーの行数を増やしたところバランス良く表示されたのでコメントアウト
使用しているウィジェットは全てQFrameの上に置くようになっている、これを直接selfの上に置くようにするとエラーになった。何故QFrameが必要とされるのかは不明です。


ソースは別館のRuby/Qteの勉強部屋にて

関連付けとQCop受信 - ZEditorの場合

サムさんトコにコメントした際に気になったの実験。
以前の実験で関連付けによるアプリ起動の際はQCopメッセージ

setDocument(QString) filepath

でファイルパスを渡すというのを知ったわけなのですが。QCop受信の手段としてQCopChannelクラスを使用していました。ところがZEditorのソースを見るとQCopChannelを使用していません。ではどうなているかというとpublic slotでsetDocument(QString)を定義してるんですよね。
というわけで、rcvqcopに同じ様にして実験してみるとちゃんとQStringは引数を受け取っています。QCopChannelでは引数がQCStringとQByteArrayで処理が面倒なのでQStringで受け取れるのは便利です。

次に同じようにpublic slotでtest(QString)というのを定義してみてターミナルからメッセージを送信

$ qcop QPE/Application/rcvqcop 'setDocument(QString)' 'abcd'
$ qcop QPE/Application/rcvqcop 'test(QString)' 'abcd'

setDocumentの方は上手く行くのに、testの方は上手くいきません。何で???
ZEditorでももう一つのQcopメッセージJumpTo(int)はQCStringとQByteArrayで引数を渡しています、ということは何か理由があるのでしょうね。


ところで、そのJumpTo(int)の処理も

connect( qApp, SIGNAL(appMessage( const QCString&, const QByteArray&)), this,
         SLOT( qcop_receive( const QCString&, const QByteArray& )));

void TextEdit::qcop_receive( const QCString& msg, const QByteArray& data )
{
   // 処理
}

というようにQCopChannnelを使用していません、rcvqcopで同じ記述でsetDocumentを試してみたのですが上手く行かないのですよね、これも謎です。

補足

上のqAppをconnectする方法、setDocumentではダメでしたがgoingToSendSetDocumentとtestは受信しました。ということは関連付けに関係するQCopメッセージでsetDocumentだけはシステム側で特別なことを行っているということなのでしょうか。

結論

  • setDocument(関連付けで使用)はpublic slotで定義
  • その他のQCopメッセージは以下の様にslotを接続してそのslot内でメッセージを解析して処理を行う
connect( qApp, SIGNAL(appMessage( const QCString&, const QByteArray&)), this,
         SLOT( slot( const QCString&, const QByteArray& )));
続きを読む

関連付け起動時のQCopメッセージ(続き)

昨日の疑問を試すべく、実験してみる。goingToSendSetDocument(QString)とsetDocument(QString)を受信したときに時間のかかる処理をさせてみる。本当はRubyやShell Scriptのsleep(n)のような関数を使いたかったのだけれど、C++で相当するのが何かわからなかったので単純に1000行の文字出力をさせるようにしてみる。これでrcvqcop起動させているところにファイルタブから関連付けされているファイルをタップ。
結果、goingToSendSetDocument(QString)で呼ばれる処理を行う為にrcvqcopの画面に切り替わるのに時間がかかったけれども、画面をみるとしっかりqcopメッセージを受けたどおりの順番で処理を行っているみたい。
これが各メッセージ受信時の処理をスレッド処理をさせるとどうなるのかわかりませんけれども。

続きを読む

関連付け起動時のQCopメッセージ

下の日記に関連してちょっと疑問に思ったので調べてみた。
使用したのは以前QTアプリの勉強で作ったrcvqcopの修正版、これをアイコン登録して新規拡張子と新規MimeTypeを登録して、その拡張子も持つファイルをファイルタブから起動

goingToSendSetDocument(QString) filepath ←既にrcvqcopが起動している場合はこのコマンドも受信
raise()
setDocument(QString) filepath

上の2つ(3つ)のメッセージが送られていることが判明。
通常はraise()で起動(何故かこのときにfilepathが引数で渡されている)させて、setDocument(QString)で選択されたファイルを通知しているみたい。既にアプリが起動している場合はgoingToSendSetDocument(QString)も送られているけど、これで既にオープンしているファイルのクローズ処理なんかさせるのかな。


ここで素朴な疑問、あるqcopを受信してそれに対応する処理が終わらないうちに次のqcopを受信したらどうなるのだろうか?
明日へ続く

QtDesigner

にゃののんさんの日記を拝見してQtアプリのレイアウトに使用するQtDesignerというアプリを知りました。自分のクロスコンパイル環境の/opt/Qtopia/bin/をみると確かにdesignerというファイルが存在します。
起動して使用してみると、いろいろなウィジェットの配置や色などのパラメータ変更が自在にできてこりゃ便利だわ、こんなのがフリーで使えるなんてスゴイなぁ。いろいろなアプリのソースをみてると偶に拡張子uiのファイルがあったのはこれを使ってたのですね。
一応手順をメモ

$ /opt/Qtopia/bin/designer    QtDesigner起動、レイアウト作業、ファイル拡張子はui

$ /opt/Qtopia/bin/uic sample.ui -o sample.h          ヘッダファイル生成
$ /opt/Qtopia/bin/uic sample.ui -i sample.h -o sample.cpp  プログラムファイル生成

ただし自分の環境ではMakefileを作ってコンパイルするとmocがどーたらというエラーになります。ザウルス用でもエミュレーション用でも同じエラーになるので環境構築でなにかが足りないのかもしれません。まぁその辺は追々に解決していくつもり。