macdeployqt

http://d.hatena.ne.jp/QtCoder/20111107/1320766981 (Mac用アプリをリリースする
トラブルといえば、Mac用アプリを作るには macdeployqt を使うのが一般的のようですが、以前、何処かしらのタイミングで 「Leopard と SnowLeopard でアプリが動かなくなる」という問題が発生した事がありました。
「どのバージョンから問題が起きるようになったの?」とソースを確認していったけど、問題は見つからず、恐らく macdeployqt が差し替わった所為でした (SDKを入れなおしたら直った)。そんな事もあり、それ以降、無闇にバージョン変えるのが怖くなりましたね…。

Qt 4.8.1

いつまでもQt4.7.4を使い続けるのもアレかなと思い、"Maintain Qt SDK" でQt4.8.1に差し替えてみました。Windows版は既存のコードで問題なくビルドできましたが、Mac版でのビルドは思うように行きませんでした。

Qtシミュレータ?

あれ、今までQtシミュレータなんてものでしたっけ……ターゲット設定で「Qtシミュレータ」「Harmattan」という候補しか出てこないです (「デスクトップ」ってのが無くなったのか)。「Qtシミュレータ」「Harmattan」を外すと、「有効なQtバージョンが見つかりません。」と出ますね。
"Desktop Qt" の "Qt 4.8.1 (Desktop)" にチェックは入ってるのに…。"Qt 4.7.4" に戻そうとしたら、エラーが出て戻せない(涙)>"Error while relocating Qt:" 云々。

QPrinter, QPrinterInfoが 今まで通り使えない

'QPrinterInfo' was not declared in this scope

などとエラーが出て、今まで通り使えません。何か変わったんでしょうか……"Qtシミュレータ" という奴だからかも。

というわけで

4.7.4 のまま使い続けるのが無難かな。MaintainaceTool から戻せないから、昔のSDKを入れ直そう(涙)。

Qtを使ってアプリを開発しました (Mac/Win両対応)

http://firealpaca.com/

昨年の春頃にQt/QtCreatorを調査し始めて、昨年末にリリースしました。お陰様で、多くの方にダウンロード・使用して頂いています。これも何より、Qtの生産性と設計の素晴らしさのお陰です! Qt万歳!

当時を思い出すと、最初に取り掛かったのは「思ったようなアプリが作れるかどうか」を調査する事でした。こういうツールだと、何より表示周りが上手く実装できるかどうかが肝です。自由なタイミングでウィンドウの中身 (キャンバス) を更新できない (paintEvent内に限定される)など、多少困るところもありましたが、何とかなりそうでした。DockWidgetの挙動にもちょっとハマりましたね……過去日記にメモってあります :D

Macでも動くアプリを作る」というのが大きな目標だったので、ある程度の形ができたら (上手く行きそうだと感じたので)、Mac版のQtCreatorでもビルドを試してみました。Windows版との違いもなく、同じソースコードで問題なく動くし、本当に素晴らしい開発環境です。こんなに簡単にクロスプラットフォームで動くとは! IDEは色々試しましたが、最高に使いやすいし、シンプルで分かりやすいです。C/C++でのネイティブアプリ開発の決定版じゃないでしょうか。

参考資料としては、「入門 Qt 4 プログラミング」(ASIN:487311344X) は外せませんね。Qtはウェブ上の日本語情報が少ないので (Win32情報に比べると…ねw)、Stack Overflow (http://stackoverflow.com/) で直接検索するのが良いです。そもそも、公式のリファレンス (http://doc.qt.nokia.com/latest/) が抜群の分かりやすさなので、ハマることは少なそうですが。

Macだと arguments が渡ってこない

アプリケーションにファイルをDrag&Dropする場合、Windowsだと以下のコードでパラメータを取得できるのですが、Macだと何も渡ってこないようです。MacOSネイティブなAPIを呼ぶ必要がありそうで大変そうです。何か良い方法はないものでしょうか……。

    QStringList args = qApp->arguments();
    for (int i=1; i<args.size(); i++)
    {
      QString str = args.at( i );
      fileOpen( str );
    }

補足

Macの場合、Finderからファイルを送る・関連付けて開く場合ですね。D&Dは出来てなかった…。

QtCreatorでValgrindを使うとクラッシュする

QtCreatorには、メモリ解析ツールValgrindが統合されていますが、どうも自分が使った限り、新規作成したプロジェクトを解析するだけでもクラッシュしてしまいます。ValgrindはWindowsでは使えないようなので、Mac版のQtCreatorで試してみました。

1. Valgrindをダウンロードする

http://valgrind.org/ (こちらからどうぞ

2. 展開してビルドする

自分でビルドする必要があるようです。展開したフォルダまでターミナルまで潜って、

    1. ./configure を実行
    2. make を実行
    3. make install を実行

make install は、rootじゃないと実行できないようです。Macだと最初はroot用パスワードが設定されてないようなので、

> sudo passwd root

でrootのパスワードを設定し、su する必要がありました。詳しくはこちらをどうぞ。
http://stackoverflow.com/questions/8102143/how-to-build-and-install-valgrind-on-mac

3. QtCreatorにValgrindを設定する

「環境設定」の「アナライザ」から、Valgrind実行パスを指定します。"./coregrind/valgrind" というファイルが生成されていたので、これを指定しました。(/usr/local/bin/valgrind が正しいのかも)

4. 実行する (そしてクラッシュ)

「解析」メニューから「Valgrindメモリアナライザ」を実行します。残念ながら「プロセスがクラッシュしました」と言われて落ちてしまいます(涙)。

DockWidget の paintEvent

DockWidgetを継承したクラスで paintEvent を実装し、

  QPainter painter( this );
  painter.drawRect( .... )

という形で描画を行うと、floating状態だとクライアント内に描画が行われますが、dock状態だとタイトル部分に描画が重なってしまいます。なので、QDockWidgetは継承せずにそのまま生成し、中身用に用意したWidget (こっちでpaintEventを実装する) を setWidget すると良いようです。

QDockWidget* dock = new QDockWidget();
WidgetContents* w = new WidgetContents(); // 中身用のWidget
dock->setWidget( w );
addDockWidget( Qt::LeftDockWidgetArea, dock );

IMEを無効にできない

IMEが有効になっていると、keyPressEventが来なくなるようです。IMEを無効にするには、

setAttribute( Qt::WA_InputMethodEnabled, false );

http://doc.qt.nokia.com/latest/qt.html#WidgetAttribute-enum

で良さそうに見えるんですが、さっぱり無効化してくれません(涙)。フォーカスのあるWidgetIMEが無効 (英語入力のみ) になるフラグ、という事じゃないんでしょうか……。昔は QWidget::setInputMethodEnabled() なんてものがあったようです。

補足

QLineEdit に setAttribute( Qt::WA_InputMethodEnabled, false ); すると、ASCII文字以外が弾かれるようになるんですね。入力コントロールの配置されてない Widget (プレーンなDialogとか) に対して、IMEの切り替え (A ← → あ) 自体できない (常に A になる) ようにしたいので、ちょっと違うかも…。

補足2

問題あるのはWindowsだけなので、ちょっと嫌ですが Win32 API を呼んで無効にするのが良さそうですね。

(*.pro)
win32:LIBS += -limm32
#ifdef Q_WS_WIN
  #include <qt_windows.h>
  ImmAssociateContext( (HWND)winId(), NULL );
#endif