Getting Started on the Commandline/ja
Qt ではじめる GUI プログラミング
Qt の世界へようこそ - Qt はクロスプラットフォームの GUI ツールキットです。この入門ガイドでは簡単なメモ帳プログラムの作成を通して基本的な Qt の知識を説明します。このガイドを読み終わるころには Qt の概要および API ドキュメントを参照しながら開発に必要な情報を集めることができるはずです。
Hello Notepad
最初のサンプルではウィンドウにテキストエリアを作成して表示します。これは GUI を持つもっとも簡単な Qt プログラムと言えます。
これがソースコードです:
それでは1行ずつ見ていきましょう。最初の2行でサンプルプログラムに必要な2つのクラス、 QApplication [doc.qt.nokia.com] と QTextEdit [doc.qt.nokia.com] のヘッダファイルをインクルードしています。すべての Qt のクラスはその名前のヘッダファイルを持っています。
6行目で QApplication [doc.qt.nokia.com] オブジェクトを作成しています。このオブジェクトはアプリケーション全体のリソースを管理し、 GUI を持つ Qt プログラムを動作させるのに欠くことのできない存在です。Qt はコマンドラインオプションを受け取るため、
argv
と
args
が必要です。
8行目で QTextEdit [doc.qt.nokia.com] オブジェクトを作成しています。テキスト入力は GUI の視覚的な構成要素の1つです。Qt では通常これらをウィジェットと呼んでいます。ウィジェットは他にもスクロールバー、ラベル、ラジオボタンなどがあります。ウィジェットは他のウィジェットのコンテナ (入れ物) になることができます。たとえばダイアログやメインウィンドウなどです。
9行目でテキスト入力を画面に表示しています。ウィジェットはコンテナとしても機能しますので (たとえばツールバーやメニュー、ステータスバーなどのウィジェットを持つ QMainWindow [doc.qt.nokia.com])、ウィジェット単体を独立したウィンドウに表示することが可能です。ウィジェットはデフォルトでは非表示になっています。 show() [doc.qt.nokia.com] 関数を使ってウィジェットを表示してください。
11行目で QApplication [doc.qt.nokia.com] のイベントループを開始します。 Qt アプリケーションが動いているとき、イベントが生成されてアプリケーションのウィジェットに送られます。具体的にはマウスボタンを押し込んだ、キーの押下などのイベントです。テキスト入力のウィジェットでテキストを入力したとき、ウィジェットはキー入力イベントを受け取り、打ち込まれたテキストを描画することで応答します。
アプリケーションの起動は、コマンドプロンプトを開いて、
.cpp
ファイルのあるディレクトリに移動した後、次のコマンドを入力してプログラムをビルドしてください。 その結果、
part1
ディレクトリに実行ファイルが生成されます (Windows の場合は
make
のかわりに
nmake
を使う必要があります。さらに実行ファイルは
part1/debug
または
part1/release
に置かれます)。
qmake
は Qt のビルドツールで、設定ファイルを受け取ります。
qmake
は
-project
オプションを使用するとその設定ファイルを生成してくれます。渡された設定ファイル (拡張子は
.pro
) からプログラムをビルドするための
make
ファイルを生成します。独自に
.pro
ファイルを書く方法については後ほど説明します。
関連するドキュメント
- ウィジェットとウィンドウのジオメトリ: Window and Dialog Widgets [doc.qt.nokia.com]
- イベントとその処理: The Event System [doc.qt.nokia.com]
終了ボタンを追加する
実際のアプリケーションでは通常より多くのウィジェットが必要です。そこで QPushButton [doc.qt.nokia.com] をテキスト入力の真下に配置してみましょう。このボタンは押されるとメモ帳プログラムが終了します。
それではソースコードを見ていきます。
1行目ではすべての Qt の GUI クラスを含む QtGui [doc.qt.nokia.com] ヘッダをインクルードしています。
10行目では終了ボタンが押されたときにアプリケーションが終了するように Qt のシグナルとスロットの仕組みを使っています。
スロットは実行時に名前 (通常の文字列) で呼び出される機能です。シグナルは呼び出されたときに登録されたスロットを起動する機能です。これを Qt では、スロットをシグナルにつないで、シグナルを送信する、と言います。
quit() [doc.qt.nokia.com] はアプリケーションを終了する QApplication [doc.qt.nokia.com] のスロットです。 clicked() [doc.qt.nokia.com] は QPushButton [doc.qt.nokia.com] が押されたときに送信されるシグナルです。静的な QObject::connect() [doc.qt.nokia.com] 関数はスロットをシグナルにつなぎます。2つのマクロ
<span class="caps">SIGNAL</span>
と
<span class="caps">SLOT</span>
はシグナルとスロットの関数シグニチャを受け取ります。そしてシグナルを送信するオブジェクトと受け取るオブジェクトのポインタも渡します。
12行目では QVBoxLayout [doc.qt.nokia.com] オブジェクトを生成しています。前述の通り、ウィジェットは他のウィジェットを含むことができます。子ウィジェットの位置やサイズを直接指定することもできますが、通常はレイアウトを使うのが簡単です。レイアウトはウィジェットの子要素の位置とサイズを管理します。 例えば QVBoxLayout [doc.qt.nokia.com] は子要素を縦の列に配置します。
13行目と14行目ではテキスト入力とボタンをそれぞれレイアウトに追加しています。
そして17行目でウィンドウにそのレイアウトを設定しています。
関連するドキュメント
- シグナルとスロット: Signals & Slots [doc.qt.nokia.com]
- レイアウト: Layout Management [doc.qt.nokia.com], Widgets and Layouts [doc.qt.nokia.com], Layout Examples [doc.qt.nokia.com]
- Qt のウィジェット: Qt Widget Gallery [doc.qt.nokia.com], Widget Examples [doc.qt.nokia.com]
QWidget の派生クラスを作る
ユーザがアプリケーションを終了するとき、本当に終了したいかどうかを確認するダイアログを表示したいとします。このサンプルでは QWidget [doc.qt.nokia.com] の派生クラスを定義して終了ボタンにつなぐためのスロットを追加します。
それではソースコードを見ていきます。
Q_OBJECT
マクロはクラス定義の先頭に置く必要があり、このクラスが
QObject
であることを宣言します (QObject [doc.qt.nokia.com] を継承しているので当然ではありますが)。 QObject [doc.qt.nokia.com] は通常の C++ クラスにさまざまな機能を追加します。特にクラス名とスロット名は実行時に利用されます。同様にスロット引数の種類についても知ることができます。 9行目 (実際のソースコードでは13行目) で
quit()
スロットを宣言しています。
slots
マクロを使えば簡単です。 これでシグニチャの一致するシグナル (ここでは引数を1つも持たないシグナルなら何でも) を
quit()
スロットに接続できます。
main()
関数で GUI の構築やスロットの接続を行うかわりに、
Notepad
クラスのコンストラクタを使います。 上のクラス定義のように、 QObject [doc.qt.nokia.com] へのポインタを使います (
textEdit
と
quitButton
)。通常、 QObject [doc.qt.nokia.com] は常にヒープ上に作成し、それらをコピーはしないようにしてください。 ユーザに表示される文字列が tr() [doc.qt.nokia.com] 関数で囲まれています。この関数はアプリケーションを他の言語 (英語や中国語) 向けに提供するときに必要になります。ここではこれ以上触れませんが、関連ドキュメントの
Qt Linguist
を参照してみてください。
関連するドキュメント
- tr() 関数と国際化: Qt Linguist Manual [doc.qt.nokia.com], Writing Source Code for Translation [doc.qt.nokia.com], Hello tr() [doc.qt.nokia.com], Internationalization with Qt [doc.qt.nokia.com]
- QObject と Qt のオブジェクトモデル (Qt の本質を知る): Object Model [doc.qt.nokia.com]
- qmake と Qt のビルドシステム: qmake Manual [doc.qt.nokia.com]
.pro ファイルを作成する
qmake
の
-project
オプションを使うかわりに、このサンプルプログラムのための
.pro
ファイルを書いてみましょう。
以下のシェルコマンドでサンプルプログラムをビルドします。
QMainWindow を使う
QMainWindow [doc.qt.nokia.com] はメニュバー、ドック、ツールバー、ステータスバーを追加するための独自のレイアウトが備わっているため、多くのアプリケーションがその恩恵を受けるでしょう。中央のエリアにはどのような種類のウィジェットでも配置することができます。今回のサンプルプログラムではテキスト入力がそこに置かれます。
それでは新しい
Notepad
クラスの定義を見ていきましょう。
ドキュメントの保存と開く処理のためにさらに2つのスロットを追加しました。これらのスロットは次のセクションで実装します。
メインウィンドウにおいてはしばしば同じスロットがさまざまなウィジェットから呼び出されます。具体的にはメニューアイテムとツールバーのボタンなどです。これをより簡単にするために Qt はさまざまなウィジェットに渡されて、1つのスロットに接続される QAction [doc.qt.nokia.com] を提供しています。たとえば QMenu [doc.qt.nokia.com] と QToolBar [doc.qt.nokia.com] は同じ QAction [doc.qt.nokia.com] から メニューアイテムとツールボタンを作成できます。これがどのように動くのかちょっと見てみましょう。
これまで通り Notepad クラスのコンストラクタを GUI の構築に使います。
QAction [doc.qt.nokia.com] は追加するウィジェットにラベルとして表示されるテキストと共に作成します (今回のサンプルではメニューアイテム)。ツールバーに追加するのであれば、そのアクションに アイコン [doc.qt.nokia.com] を持たせておくこともできます。
これでメニューアイテムがクリックされると、アクションが起動し、スロットが呼び出されます。
関連するドキュメント
- メインウィンドウとそのクラス: Application Main Window [doc.qt.nokia.com], Main Window Examples [doc.qt.nokia.com]
- MDI アプリケーション: QMdiArea [doc.qt.nokia.com], MDI Example [doc.qt.nokia.com]
ドキュメントの保存と読み込み
このサンプルでは1つ前のサンプルで追加した
open()
と
save()
の2つのスロットを実装していきます。
open()
スロットの方からはじめてみましょう:
まず最初のステップで開くファイル名をユーザに求めています。Qt にはユーザがファイルを選択できるダイアログである QFileDialog [doc.qt.nokia.com] があります。上の画像のダイアログは Kubuntu で表示させたものです。静的な getOpenFileName() [doc.qt.nokia.com] 関数はモーダルなファイルダイアログを表示し、ユーザがファイルを選択するまで制御を戻しません。ダイアログは選択されたファイルのファイルパスか、ユーザがキャンセルした場合は空の文字列を返します。
もし何らかのファイル名があるときは open() [doc.qt.nokia.com] を使ってファイルのオープンを試みて、正しく開くことができたら true を返します。ここではエラー処理について詳しく説明しませんが、関連ドキュメントを参照してみてください。ファイルが開けなかった場合、ここでは QMessageBox [doc.qt.nokia.com] を使ってエラーメッセージを表示します (詳しくは QMessageBox [doc.qt.nokia.com] クラスの説明を参照してください)。
今回はファイルのすべてのデータを QByteArray [doc.qt.nokia.com] として返す readAll() [doc.qt.nokia.com] 関数を使っています。 constData() [doc.qt.nokia.com] は配列のすべてのデータを const char* で返します (QString [doc.qt.nokia.com] にはそのコンストラクタがある)。そして内容がテキスト入力に表示されます。あとは close() [doc.qt.nokia.com] を呼び出してファイルディスクリプタを OS に返します。
次は
save()
スロットにとりかかりましょう。
テキスト入力の内容をファイルに書き込むとき、 QFile [doc.qt.nokia.com] オブジェクトをラップする QTextStream [doc.qt.nokia.com] クラスを使います。テキストストリームは QString をファイルに書き込むことができます。 QFile [doc.qt.nokia.com] はオブジェクト化されていない文字列データ (char*) のみを QIODevice [doc.qt.nokia.com] の write() [doc.qt.nokia.com] 関数で受け付けます。