C++でQTアプリ(その1) シグナルとスロット
勉強としてdev-img1.6環境でC++を使ってHello Worldよりましなプログラムを書いてみる。とりあえずボタンを押すとテキストエリアに文字を書くプログラム。
QT部分はRuby/Qteの知識で何とかなりそうなんだけど、C++の書き方がよくわからない。
気付いたポイント
- クラスの定義はmain.cppと別のファイルにする、下のプログラムを一個のファイルに書いてコンパイルしたらVirtual何とかが定義されていないというエラーになった。
- 変数の宣言について以下の様に2種類の方法があるけど、後者の方が良いらしい。でも前者の方法でしか書けないものもある(書き方を知らないだけ?)
QLabel label(); label.setText(); QLabel *label = new QLabel(); // *がクラス側にくっついている場合もある、違いは??? label->setText();
- 自分でスロットを定義する場合はヘッダーファイルの「Q_OBJECT」行が必要らしい
- ヘッダーファイルには#ifndef〜#endifの記述が必要らしい(二重宣言の防止?)
- cppファイルで使用していない変数をヘッダーファイルで宣言していると妙なことになる場合があるので注意
- コンパイル時のエラーはproファイルやMakefileも疑う。(cppの#includeに"xxx.cpp"と書いてあり不適切なproファイルになっていて一日中ハマッてしまった)
main.cpp
#include <qpe/qpeapplication.h> #include <qtextcodec.h> //#include <qfont.h> #include "hello.h" int main(int argc, char *argv[]) { QPEApplication a(argc,argv); // この2行が無いとtrで日本語を書いたときに化ける QTextCodec* codec = QTextCodec::codecForName("eucJP"); a.setDefaultCodec(codec); // Hello *hello = new Hello(0, "top"); Hello *hello = new Hello(); // QFont f("lcfont",24); // a.setFont(f); // mainのcaptionが大きくなる // top->setFont(f); // main内の文字が大きくなる a.showMainWidget(hello); // 全画面表示 // a.setMainWidget(hello); // こちらだと全画面にならない // hello->show(); return a.exec(); }
hello.h
#ifndef HELLO_H #define HELLO_H #include <qmainwindow.h> #include <qtextcodec.h> #include <qfont.h> #include <qvbox.h> #include <qlabel.h> #include <qmultilineedit.h> #include <qpushbutton.h> #include <qapplication.h> class Hello : public QMainWindow{ Q_OBJECT // これが無いとスロットが作れない? public: // Hello(); Hello(QWidget *parent = 0, const char *name = 0); // ~Hello(); private: // QTextCodec* codec; // QFont f; QVBox *v; QLabel *label; QMultiLineEdit *eb; QPushButton *pb; private slots: void slot_pb(); }; #endif //HELLO_H
hello.cpp
#include "hello.h" Hello::Hello(QWidget *parent, const char *name) : QMainWindow(parent, name) { // codec = QTextCodec::codecForName("eucJP"); setCaption("Hello World"); QFont f("lcfont",24); // ポインタ方式の書き方が不明 setFont(f); // Widget内のフォント設定 v = new QVBox( this ); // v->setGeometry(0, 0, 640, 400); setCentralWidget(v); // label = new QLabel(codec->toUnicode("こんにちは"), v); label = new QLabel(tr("こんにちは"), v); // label->setGeometry(0, 0, 600, 100); eb = new QMultiLineEdit(v); // eb->insertLine(codec->toUnicode("一行目")); eb->insertLine(tr("一行目")); // pb = new QPushButton(codec->toUnicode("ボタン"), v); pb = new QPushButton(tr("ボタン"), v); // QObject::connect( pb, SIGNAL(clicked()), qApp, SLOT(quit()) ); // アプリ終了 QObject::connect( pb, SIGNAL(clicked()), this, SLOT(slot_pb()) ); } // 新規定義したスロット void Hello::slot_pb() { // eb->insertLine(codec->toUnicode("ボタンを押した")); eb->insertLine(tr("ボタンを押した")); // close(); // parentWidget()->close(); }