「C++」 カテゴリーの記事です。

QtでMacOSXアプリケーションをつくる


最近また、Qt を始めています。

実は、NokiaがQtを手放してから、もう終わったか・・・と、しばらく触っていなかったのですが、
しばらく見ないうちに、高機能で、マルチプラットフォーム化が進んでいたので、びっくりです。
商用ですが、Android、iOSにも対応しているようです。

そんなわけで、改めてなぜいま Qt なのかというと、Mac OSX アプリケーションが作りたくて。
心地よく日本語テキストを打ち込める、軽量な執筆エディターがほしくて探し回りましたが、
ぴったりのものが見つからないんですよね。

海外製のは、変換候補があさっての方へ飛んでいってしまったり、
段落下げしたら、以降、全部段落が下がるという、完全に海外文書仕様になっていて、
日本語的な一字下げのみということができなかったり、そもそも日本語対応は微妙なのが多い。

で、とりあえず僕はいま、Qtに、面倒なMacOSX側の処理をやってもらって、
あとは、エディタ部分も含め、WebView(Weblit+JavaScript)の方で
表示・編集できるように開発してこうと考えています。

いわゆる The QtWebKit Bridge(http://qt-project.org/doc/qt-5/qtwebkit-bridge.html)を使います。

Qt Creatorから、「新しいプロジェクト」を開くと、
「HTML5アプリケーション」という項目があるので、基本はそれで作ります。

ただ、これだと、シングルウィンドウのWebブラウザアプリと変わりがなくなってしまいます。
ファイルを保存したり、ファイルを開く、アプリ自体の設定なんかも各々のマシンに記憶しておきたい。

そうなると、MacOSXのネイティブなところをいじる必要があるわけです。
つまり、Qt(MacOSX)ネイティブ+JavaScriptのハイブリッドアプリケーションの構成で、というわけです。

ちなみに、エディタ部分は、CodeMirrorを使います。

これがなかなかの高機能で、ライセンスも、MITライセンス。
これをWebKitに組み込んで使っている海外製のエディタアプリケーションも多い。

このサンプルソースは、なかなか見当たらないのですが、以下の記事が参考になりました。

hybrid web+native: desktop codemirror
http://ariya.ofilabs.com/2011/09/hybrid-webnative-desktop-codemirror.html

「CodeMirrorを使う」という目的だけの、エディタの機能としては少なめのサンプルです。
とはいえ、限定されている分、ソースはシンプルで分かりやすいかもしれません。

ソースコードは、同ページにリンクが貼ってありますが、わかりにくいので、ここに再掲。
https://github.com/ariya/X2/tree/master/webkit/codemirror

ゆくゆくは、App Storeに出したいなあ、とは思っていますが、年間登録料をケチって野良配布するかもしれません。

とりあえず自分が使いたいツールを作るのが目標です。オープンソースも視野に入れています。
 
 

QtでMacOSXアプリケーションメニューに「環境設定」項目を追加、表示する


一昨日の土曜日、はじめてQt 勉強会 #11 @Tokyoにも参加。まとめは、こちらです。

めっちゃ濃いことやっている人たちばかりで腰引けました(笑)。

僕はせいぜいライブラリの寄せ集めで、さくっとアプリつくっちゃうという軽さが、とても恥ずかくなります(笑)。続々成果が発表されるなか、勉強会でやりたかったこと、をやる前に、ちがう問題が発生し、さらにそれもその日に解決できずに、宿題になってしまったという・・・

ただ、主催者の @task_jpさんからのアドバイスもあり、その後、それら宿題を解消できたのでここにシェアします。

メインメニュー「環境設定」というは、いわゆるコレです。

環境設定メニューの画像

Qtの公式ページを見ると、
http://qt-project.org/doc/qt-5/qmenubar.html#qmenubar-on-mac-os-x

If you want all windows in a Mac application to share one menu bar, you must create a menu bar that does not have a parent. Create a parent-less menu bar this way:

  
QMenuBar *menuBar = new QMenuBar(0);
  

親のないメニューバーから生成する、とある。
ただ、すでにそのようなメニューは作っていて、どこに「それら」を挿入するのかが分からない。

  
QMenu *fileMenu = menuBar()->addMenu("&File");
fileMenu->addAction(tr("&New Window"), this, SLOT(fileNew()), QKeySequence::New);
fileMenu->addAction(tr("&Open..."), this, SLOT(fileOpen()), QKeySequence::Open);
fileMenu->addAction(tr("&Save"), this, SLOT(fileSave()), QKeySequence::Save);
fileMenu->addAction(tr("Save &As..."), this, SLOT(fileSaveAs()));
  

ファイルメニュー

結論を言うと、なんか、実に微妙な実装なのですが、AddMenu() にある特定の文字列があれば、
QMenu のどこに存在してようと、良いみたい。

マニュアルにもそう書いてある。
http://qt-project.org/doc/qt-5/qmenubar.html#qmenubar-on-mac-os-x

String matches Placement Notes
about.* Application Menu | About <application name> The application name is fetched from the Info.plist file (see note below). If this entry is not found no About item will appear in the Application Menu.
config, options, setup, settings or preferences Application Menu | Preferences If this entry is not found the Settings item will be disabled
quit or exit Application Menu | Quit <application name> If this entry is not found a default Quit item will be created to call QApplication::quit()

なので、ソースコードには、こんなふうにしました。

   
QMenu *fileMenu = menuBar()->addMenu("&File");
fileMenu->addAction(tr("&New Window"), this, SLOT(fileNew()), QKeySequence::New);
fileMenu->addAction(tr("&Open..."), this, SLOT(fileOpen()), QKeySequence::Open);
fileMenu->addAction(tr("&Save"), this, SLOT(fileSave()), QKeySequence::Save);
fileMenu->addAction(tr("Save &As..."), this, SLOT(fileSaveAs()));

//ファイルメニューにぶら下がるようにコードを挿入
fileMenu->addAction(tr("about.*"), this, SLOT(aboutPaneView()));
fileMenu->addAction(tr("preferences"), this, SLOT(optionPanelView()));

こう書くと、「ファイル」メニューのプルダウン項目に表示されそうですが、そこには表示されず、
実際は、アプリケーションメニュー内に表示されます。

アプリケーションメニュー

「about.*」は、ママです。そのままアスタリスクを書きます。.plistにある「アプリケーション名」をQt が自動的に引っ張ってきて、「About AppName」という感じに表示してくれます。たぶん、アプリケーションが日本語表示対応なら、「AppNameについて」というメニューになるはずです。

「preferences」も同様に、日本語環境に対応させると「環境設定」と表示されるようです。

File メニューの中に AddMenu() したのに、実際はアプリケーションメニューに表示されるという、なんだか気持ち悪い仕様ですが、MacOSXがそうなのであって、他のOSでは、ちがう実装になるということに注意が必要でしょう。

一昨日のQt 勉強会 #11 @Tokyoでも、「気持ち悪い」「ホントに大丈夫なの?」との感想がありましたが、「マニュアルがそうなっているので、そうなんでしょう」っていう結論でした(笑)。
 
 

s