CreateWindow! -2ページ目

QtCreatorを使ってみる

QtCreatorを使ってLCDカウンタをインクリメントするプログラムを書いてみる。

メニューからFile - New File or Projectを選択。
Qt Gui Applicationを選択する


プロジェクト名はqt2とした。
そのままメニューからBuild - Build ALLを実行する。
なんとちゃんとコンパイルが通って(当たり前か。。)
実行ファイルができる。
前回の記事のようにrun settingをすれば
実行ボタン(三角の再生ボタン)を押すと
ちゃんと動いてWindowが出る。

これはこれで感動モノ。

こっからカスタマイズしていく。
mainwindow.uiファイルをクリックするとGUIを編集するDesignが開く。
まずはメニューとかいらないので
menuBar, mainToolBar, statusBarを右クリックでremoveする。


次にWindowの大きさをaitendo LCDのサイズの
480x320に変更する。


次にツールからVertical LayoutをWindowにドラッグして入れて、
赤い箱の大きさを調整する。
その中にLCDNumber,PushButtonの順に入れるとこのようになる。


もうけっこうそれっぽい。
右下の設定が出来る部分で
objectNameを前と同じようにlcd,buttonに変更して、
textで表示文字列を変更する。
これでGUIは完成。

次にボタンが押されたプログラムを書く。
このまえSLOTでハマったところだ。
これがQtCreatorだと簡単。右上のbuttonオブジェクトを右クリック。
Go to SLOTを選択。


Clicked()を選択してOKを押すとコード編集に移って、
関数が自動的に追加されている。

ここにコードを書くだけ。
lcdの関数を呼び出すには
ui->lcd->display(++num);
みたいに書くようだ。
uiファイルはxmlなのにそのままC++から呼べるのはとても不思議。
でもとても便利。

numをhファイルで定義して、コンストラクタで初期化する。
ここは前回と同じコード。

実行すると前回と同じような機能のアプリが出来た。

GUIで作ることができるのでとてもわかりやすくて作りやすい。
SLOTの作法とか考えなくていいのが特にいいね。

QtCreatorの初期設定

QtCreatorを使ってみたらかなり使える。
RaspberryPi2にリモートデスクトップで入ってWinからプログラムとかできる。
そのまま実行できるので開発効率もいい。

QtCreatorはバージョンが古いようだけど
sudo apt-get install qtcreator
でインストールしたもの。
スタートから起動する。



ちょっと設定が必要。
インストールしただけだとコンパイラとかの設定ができていない。
デブロイというらしい。
Tools-Optionsから


QtVersionタブで赤いビックリマークが出ていたらそれをクリックして
下のBrowseボタンをクリックして
/usr/bin/qmake-qt4
を選択する。

同じように
Tool ChainsタブでAddボタンを押してgccを選択。
下のCompiler pathを/usr/bin/gcc
Debuggerを/usr/bin/gdbを指定する。

必須じゃないけどプロジェクトファイルが2つできるので
GeneralタブのProjectDirectoryに/home/pi/QtCreate
を指定しておくといい。フォルダは手で作る必要があるかも。

これでコンパイルは出来るんだけど、左下の実行ボタンが使えない。
よくわからないんだけど、プロジェクトを作るたびに実行ファイルを設定する必要がある。
一回コンパイルすると実行ファイルができる。プロジェクト名の実行パーミッションファイル。
左のProjectsでRun Settingタブを開いてAddボタンを押して、下のAddボタンを押して
Executableにできた実行ファイルを指定すると実行ボタンが使えるようになる。

ちょっとめんどくさい。

QMacStyleうごかず

Qtのドキュメントを見てるとスタイルというのがあって
簡単にlook and feelを変えれるとある。
設定リストがあってMac風がかっこいい。
こんな感じ


これをやってみた。
書き方は

#include <QMacStyle>
QApplication app(argc, argv);
app.setStyle(new QMacStyle);

とすればいいみたい。
でも、コンパイルが通らない。
includeしてるQMacStyleを検索すると
/usr/include/qt4/QtGui
にあった。開いてみるとこの一行
#include "qmacstyle_mac.h"
qmacstyle_mac.hを見てみると
全体が
#if defined(Q_WS_MAC) && !defined(QT_NO_STYLE_MAC)
で囲われていた。Macでしか動かないようだ。

残念。
他に動くのはあるのかな?

pi@raspberrypi ~/qt1 $ ls /usr/include/qt4/QtGui/*Style
/usr/include/qt4/QtGui/QCDEStyle
/usr/include/qt4/QtGui/QCleanlooksStyle
/usr/include/qt4/QtGui/QCommonStyle
/usr/include/qt4/QtGui/QGtkStyle
/usr/include/qt4/QtGui/QMacStyle
/usr/include/qt4/QtGui/QMotifStyle
/usr/include/qt4/QtGui/QPlastiqueStyle
/usr/include/qt4/QtGui/QProxyStyle
/usr/include/qt4/QtGui/QS60Style
/usr/include/qt4/QtGui/QStyle
/usr/include/qt4/QtGui/QWindowsCEStyle
/usr/include/qt4/QtGui/QWindowsMobileStyle
/usr/include/qt4/QtGui/QWindowsStyle
/usr/include/qt4/QtGui/QWindowsVistaStyle
/usr/include/qt4/QtGui/QWindowsXPStyle

それぞれについてコンパイルできるか試してみた。

QCDEStyle,QCleanlooksStyle,QCommonStyle,QGtkStyle,QMotifStyle,
QPlastiqueStyle,QProxyStyle, QWindowsStyle, 
はコンパイルできる。

QMacStyle, QS60Style, QStyle, QWindowsCEStyle, QWindowsMobileStyle,
QWindowsVistaStyle, QWindowsXPStyle
はコンパイル通らない。

できるやつはどれもぱっとしないというか、あんまり変わらない。
Macのようにボタンが青くなってくれるとかっこいいのになぁ。

今回は数が多い割りに結果が変わらないので疲れた。。。

QTimerの使い方

SLOTの使い方がわかったので
QTimerを使ってみた。

mainWindowのコンストラクタに以下を追加したら勝手にボタンが押されたことになる
    // タイマで100msごとにかってに押されるようにする
    QTimer *timer = new QTimer(this);
    connect(timer, SIGNAL(timeout()), this, SLOT(onClick()));
    timer->start(100);  // 100ms

結構簡単。SLOT便利かも。

Qtの流儀

QtのSLOTは流儀があるようでなかなか難しい。
でもQtでSLOTは避けて通れなさそう。

いくつかルールがあるようだ。
・QObjectから派生したクラスである必要がある
・クラスの宣言でQ_OBJECTを書く必要がる
・Q_OBJECTを書いたクラスの宣言はヘッダに置かなければならい
 (undefined reference to vtable というコンパイルエラーが出る)
・SLOT関数はprivate slots:という宣言をする
・SingnalとSLOTは引数を合わせる必要がある

ヘッダに書かないといけないのはファイルが増えてめんどくさい
まぁ、C++的には普通といえばふつうなんだけど。
LCDとボタンを配置したwindowを作って、
ボタンを押すとLCDの数がインクリメントするアプリを作ってみた。


main.cpp
#include <QApplication>

#include "mainWindow.h"

int main(int argc, char** argv)
{
    QApplication app(argc, argv);
    MainWindow* mainWindow = new MainWindow;

    mainWindow->show();

    return app.exec();
}

mainWindow.h
#include <QLCDNumber>
#include <QPushButton>

// トップwindowのクラス
class MainWindow : public QWidget
{
    Q_OBJECT        // SLOTを有効にするのには必要みたい

public:
    MainWindow();

private slots:      // SLOTの宣言はこう書く
    void onClick(); // 押された時の関数(SLOT)

private:
    QLCDNumber* lcd;
    QPushButton* button;
    int number;
};

mainWindow.cpp
#include <QVBoxLayout>

#include "mainWindow.h"

// トップwindowのコンストラクタ
MainWindow::MainWindow()
    : QWidget()
{
    number = 0;
    lcd = new QLCDNumber(3, this);
    button = new QPushButton("increment", this);

    // 押された時の関数(SLOT)を登録
    connect(button, SIGNAL(clicked()), this, SLOT(onClick()));      

    // 縦方向につなげて表示
    QVBoxLayout* layout = new QVBoxLayout;
    layout->addWidget(lcd);
    layout->addWidget(button);
    setLayout(layout);
}

// ボタンが押された時の関数
void MainWindow::onClick()
{
    lcd->display(++number); // LCDの数字をインクリメント
}

ファイルを追加した時は
qmake -project
からやり直す必要がある。

QPushButtonのclikedというシグナルをonClickという関数につなげている。
書き方がわかってればそんなに大したことじゃないんだろうけど
わかるまで結構長く試行錯誤&ネット検索する必要があった。。。