
| ■ | Hello, Qt World |
えー、まずいきなりですが、「Hello, World」をするだけのプログラムであっても、 「ヘッダファイル(.h)」と「本体プログラム(.cpp)」の2つのソースファイルが必要になります。 「一緒に書けばええんとちゃうの」と言わずに、必ず2つに分けましょうね。 ここでは
hello.h hello.cpp |
/* hello.h */
#include "qwidget.h"
class HelloWidget : public QWidget {
Q_OBJECT
public:
HelloWidget(QWidget* parent, char* name=0);
public slots:
void hello(void);
};
|
簡単なアプリケーションなら、上の例で十分に使い回しが効きます。 Qtでは、Qtのウィジェットの種類ごとに(膨大な数の)ヘッダファイルが用意されているので、 必要なものをすべて、プログラマが #include する必要があります。 たとえば QWidget というウィジェットを使いたかったら qwidget.h をインクルードする、QPushButton というウィジェットを使いたかったら qpushbutton.h をインクルードする、…などなどで、 複雑なプログラムになるとこれがずらっと並ぶことになります。
で、またもいきなりですが、Qt標準のウィジェットのひとつ QWidget を継承してクラスの定義を行います。 C++の文法については詳しくは省略します。 何か変なキーワードが2つありますが、これはこういうものだ、 ということでとりあえず先に進みます。
今度はその hello.h で宣言した HelloWidget クラスの実装と、 プログラム本体を記述した hello.cpp を作ります。
/* hello.cpp */
#include <stdio.h>
#include "qapplication.h"
#include "qlabel.h"
#include "qpushbutton.h"
/* ↑使うウィジェットの種類に応じて、全部このように */
/* インクルードする必要があります */
#include "hello.h"
/* 先程の hello.h も */
HelloWidget::HelloWidget(QWidget* parent, char* name=0){
QLabel* laba = new QLabel(this);
QPushButton* cmda = new QPushButton(this);
QPushButton* cmde = new QPushButton(this);
/* ウィジェットを作ります。各ウィジェットのコンストラクタ */
/* には自分の親ウィジェットを渡します。この場合は、これ */
/* (HelloWidget)の上にラベルを1つと、ボタンを2つ載せて */
/* います。Qtでは、「載せる」という処理をする関数(メソッド)は */
/* ありません。ウィンドウが表示されると、その上の子ウィジェット */
/* は全部自動的に表示してくれます。*/
laba->setText("Hello, World.");
cmda->setText("Push Me");
cmde->setText("Quit");
/* ラベルとボタンにそれぞれ表示したいテキストをセットして */
/* います。ここの場合は、QLabelの別のコンストラクタを使い */
/* laba = new QLabel("Hello, World.", this); */
/* のように初期化と同時にテキストのセットを行わせることも */
/* できます。*/
laba->move(120, 20);
cmda->move(30, 60);
cmde->move(170, 60);
/* QWidgetはいわゆるレイアウトマネジメント(縦横に子をそろえて */
/* 配置してくれる機能)はまったく行えません。そこで、最も簡単 */
/* には、このように子のmoveメソッドで、親(ここではHelloWidget)*/
/* の左上端からの相対位置(ピクセル数)で子を配置させます。 */
/* ちなみに各ウィジェットの大きさは resize(width, height) */
/* というメソッドで自由に変更できるほか、位置とサイズを同時に */
/* 変更できる setGeometry(x, y, width, height)というメソッド */
/* もあります。*/
QObject::connect(cmda, SIGNAL(clicked()), this, SLOT(hello()));
QObject::connect(cmde, SIGNAL(clicked()), this, SLOT(close()));
/* これがうわさのシグナルとスロットです。後述! */
this->resize(300, 100);
}
void HelloWidget::hello(void){
fprintf(stdout, "Hello, World.\n");
}
int main(int argc, char* argv[]){
QApplication* a = new QApplication(argc, argv);
/* QApplicationのインスタンスを1つ用意 */
/* Qtアプリケーションは必ずこれから始まります */
HelloWidget* my = new HelloWidget(NULL);
/* 上で作った HelloWidget のインスタンスも1丁 */
a->setMainWidget(my);
/* アプリケーションの「メインウィジェット」として */
/* あるウィジェットをセットすると、このウィジェット */
/* がメインの「ウィンドウ」となり、このウィジェット */
/* が閉じられるとアプリケーションも自動的に終了します。*/
my->show();
/* ウィンドウを表示 */
return a->exec();
/* イベントループに入ります。*/
}
/* end. */
|
プログラムの大体の紹介は中のコメントで済んでしまうのですが、 あとは最もやっかいで複雑な「シグナルとスロット」の話です。
QObject::connect(cmda, SIGNAL(clicked()), this, SLOT(hello())); QObject::connect(cmde, SIGNAL(clicked()), this, SLOT(close())); |
QObject::connect(button, SIGNAL(clicked()), window, SLOT(close())); |
QObject::connect(lstb, SIGNAL(selected(int)), slider, SLOT(setValue(int))); |
というようなことを踏まえて、それでは 「ボタンcmdaが押されると、Hello, World と出力する」 という処理はどうなるでしょうか?
QObject::connect(cmda, SIGNAL(clicked()), this, SLOT(hello())); |
void HelloWidget::hello(void){
fprintf(stdout, "Hello, World.\n");
}
|
int main(int argc, char* argv[]){
/* ... */
my->hello();
/* ... */
}
|
| ■ | moc(メタオブジェクトコンパイラ) |
CC = gcc
CXX = g++
QTDIR = /usr/local/qt-2.0.2
MOC = ${QTDIR}/bin/moc
CFLAGS = -I$(QTDIR)/include -g -O
LDFLAGS = -L$(QTDIR)/lib
LIBS = -lqt
.SUFFIXES: .cpp .cxx .cc .C .c
.cpp.o:
$(CXX) -c $(CFLAGS) -o $@ $<
SRCS = hello.cpp moc_hello.cpp
OBJS = hello.o moc_hello.o
hello: $(SRCS) $(OBJS)
$(CXX) -o $@ $(LDFLAGS) $(OBJS2) $(LIBS)
moc_hello.cpp : hello.h
$(MOC) -o $@ $<
|
つまり、まず hello.h を moc にかけて moc_hello.cpp (名前はなんでもOKです)なるソースファイルを1個作ります。 そして、その .cpp ファイルと、元の hello.cpp ファイルをコンパイルし、これらと Qt のライブラリをリンクすることでめでたく 「Hello, World」プログラムができあがります。
セクションのサブメニューに戻る
(first uploaded 2000/03/09 last updated 2002/03/21)