Qtを使用した迷路シミュレーターを作る (Qtのことはじめ編)

2020年6月7日

マイクロマウス関連記事のまとめはこちら。

マイクロマウスの交流会などで、迷路アルゴリズムを作成した後に動作確認をCUIですることはできるが確認が大変、実際に走らせて確認している、GUIのシミュレータを作りたいがやり方がわからないという話をちらほら聞いたので、Qtを使用した迷路シミュレータの迷路の壁画部分、左手法で動かすまでのやり方を書いていきたいと思います。

Qtを使用する理由は、マルチプラットフォームである、Qtの勉強をしてみたかった,C++でGUIを書いてみたかったからです。

目標は、GUI上で迷路アルゴリズムに対応して動くシミュレータの作成になります。

 




Qtのインストール

QTの公式ページからダウンロードのページに飛び、右側のオープンソースという方からインストーラーをダウンロードしましょう。ダウンロードするインストーラーは各自のPCの環境にあったものをインストールしてください。

インストーラーを起動した後はNextを押すと、アカウントの作成という画面がでてきますが、右下にあるSKIPボタンを押してセットアップを進めることもできるので、アカウントを作らなくても使用はできます。

インストールするディレクトリは、初期設定通りにしました。

すると、以下の写真に示すようなウィザードが出てきます。

 

今回のプログラムは、バージョン5.9で動作確認はしております。

最新バージョンでも動くとは思われますが、環境を同じにしておきたいという方は左側のチェックボックスのArchiveを選択してRefreshボタンを押すと、Qtの古いバージョンが出てきます。

そこからQt5.9をインストールしてください。

上記画像の右側をみると約44GBを占有しますと書いてあります。Qt5.xxをチェックをするとアンドロイドなどの環境のファイルがすべて入っています。

そのために容量が大きくなっているので、必要ない環境のパッケージはすべてチェックを外しましょう。

そうすることで、約15GB程度まで小さくすることができました。

これらの設定が終わったら次へを押していけばインストールができます。

インストールが終わったら、QtCreatorを開きましょう。左下の検索ボックスから検索すれば出ると思います。

QtCreatorはQt公式のIDEで、エディタでは関数や変数の補完、コンパイルが簡単に行えるので今回はこれを使用していこうと思います。

 

プロジェクトの生成

以下の流れで行いました。

  1. Qt Creatorを起動
  2. 新しいプロジェクトからQtウィジットアプリケーション、選択、名前、パスは各自好きな名前、場所を設定してください。
  3. キットの選択は初期設定のまま使用しました。
  4. クラス情報の画面が出てきます。今回は初期設定のまま次へを押してましょう。
  5. プロジェクト管理はなしで完了。

私は、sampleという名前に設定し、プロジェクトの置き場所はDocument/study直下に設定をしました。

左下の実行ボタンを押すと、ウィンドウが開くと思います。

これで、プロジェクトがちゃんと生成ができました。

 

画面レイアウト

左側のプロジェクトディレクトリからForms→mainWindow.uiをクリックしてください。

次のような画面が出てくると思います。

GUIでフォームの設定をすることができます。

迷路の表示はGraphics Viewを使用していこうと思っているので、左上のテキストボックスにGraphics Viewを検索して、ドロップアンドペーストをしてください。

続いて、メインウィンドウの大きさの変更をしていきたいと思います。

右上のオブジェクト、クラスと書いてあるところのMainWindowにカーソルを合わせてワンクリックすると、色がグレーになって選択されると思います。

そしたら、右下の設定から幅1200,高さ900に設定してください。

同様にgraphicsViewを選択、X:30,Y:30,幅800,高さ800で設定します。

画面からはみ出すと思います。これで実行を行うと、この画面をしたウィンドウが生成されます。実行して確認してみてください。

同様にして、Push Button, TextBox,TextEdit,TextLabelを次のように設定しました。

TextLabelの表示名は変更しています。右下のオレンジ色が背景になっているところから編集することが可能です。

オブジェクトの名前の変更方法は複数あるので各自でいじってみてください。プッシュスイッチやラベルは、ウィンドウの部品の上でダブルクリックすることで名前の変更ができます。

上記の画像のようにレイアウトしてみました。

続いて、部品を押されたときに処理をしたいので設定をしていきます。

右上の表のプッシュボタンのオブジェクトの上で右クリック、スロットへ移動をクリックすると次の画面が出てきます。

 

clicked()を選択してOKボタンをクリックするとmainWindow.cppに飛ぶと思います。

cppファイルを各印するとon_(自分が選択したプッシュボタンのオブジェクト名)_clicked()という関数ができていると思います。

これで、スイッチが押された時に動作をする関数を定義することができました。

同様に、もう一つのスイッチも設定してください。

プログラムの実装

テキストエディタに文字を表示する

GUIで編集したテキストエディタやプッシュボタンのオブジェクトは、

Ui::MainWindow *ui

にオブジェクトの実体がポインタで定義されています。詳しくは、ui_mainwindow.hを確認してみてください。

したがって、GUIで作成したオブジェクトには、

ui->"GUIで定義したオブジェクト名"

のようにしてアクセスるることが可能です。

テキストエディタに文字を表示するという場面では、テキストエディタが編集できる必要性がないため、読み込み専用にしてしまおうと思います。

まずは、filePathEditに"Hello World"と表示をしてみます。

まず初めに、mainwindow.hで<QtWidgets>をインクルードしておいてください。Widgets関連のhファイルをほぼすべてインクルードすることができます。

また、initialize用関数としてvoid init()をprivate関数として定義しておいてください。

mainwindow.cppに移動して、filePathEditを読み込み専用にしたのち、文字の設定をします。

Qtを使用するときは、Qt Documentationで使用しているクラスのメンバ関数や保持している関数などを読み、必要な関数をしらべるという方法でやっていくことをお勧めします。だいたいは公式ドキュメントで解決ができると思います。ほかにはQtFormやブログなどがあります。

filePathEditはQTextEditクラスなので、QTextEdit Classのドキュメントを見ていきたいと思います。

このページより、読み込み専用にするには、setReadOnly(bool),テキストを追加するにはsetText(const QString &text)で行うことができるということがわかりました。

実装は次のように行いました。

/*
 * Initialize function
 * call MainWindow class constructor
*/
void MainWindow::init()
{
  ui->filePathEdit->setReadOnly(true); 
    ui->filePathEdit->setText("Hello World");
}

init()は private 関数として定義しました。

ボタンが押された時の処理をできるようにする

drawMazeボタンが押された際にメッセージボックスに[You push drawMaze]表示するようにします。

MainWindowクラスには

private slots:
    void on_drawMazeButton_clicked();

が定義されていると思います。

slotsに追加した関数は、クラスのメンバ関数の特性を持ちながら、シグナルに接続する特性を持つ追加でもったものという認識を持っていただければと思います。詳しくは、QtDocumantionのDifferences between String-Based and Functor-Based Connectionsなどを読んでみてください。

この関数は、clickedに追加をされているのでこの中に処理を書くことでボタンを押された際の処理ができそうということがわかりました。

続いて、メッセージボックスを使うためにQMessageBox Classのドキュメントを見ていきます。

中ほどにある、The Property-based APIの通りに使用すれば今回やりたいことができそうということが分かったので、これを模範にして実装をしました。

 

実装したプログラムのまとめ

今回の内容を実装した結果、mainwindow.cpp(h)のソースコードの全体は以下のようになりました。

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    init();
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::on_drawMazeButton_clicked()
{
    QMessageBox *box = new QMessageBox;
    box->setText("You push draw Maze Button");
    box->exec();

}

void MainWindow::init()
{
    ui->filePathEdit->setReadOnly(true);
    ui->filePathEdit->setText("Hello World");
}
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QtWidgets>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private slots:
    void on_drawMazeButton_clicked();

private:
    Ui::MainWindow *ui;

    void init();
};

#endif // MAINWINDOW_H

 

プログラムの実行結果

 

さいごに

今回は、Qtのインストールからプロジェクト作成し、メインウィンドウをGUIで設定しました。その後、テキストエディタに文字を表示する、ボタンを押したときに動作をするプログラムの作成まで行いました。

ここまでの内容がわかれば簡単な数値計算をするGUIアプリを作成できるようになったかなと思います。

次回は、ボタンを押された際にエクスプローラーのダイアログを表示して、ファイルを読み込んでみるということを書いていく予定です。

 

参考文献

QtDocumentation