Qt 勉強会 @ Tokyo #58 参加報告 | はじめてのQt勉強会

Qt勉強会@Tokyo #58の参加記録を記す。

概要

イベント情報
項目 内容
イベント名 Qt 勉強会 @ Tokyo #58
URL https://qt-users.connpass.com/event/85873/
ハッシュタグ #qtjp
開催地 株式会社PTP 9F会議室
東京都新宿区新宿1-23-1 新宿マルネビル9F
開催日時 2018-04-28 13:00-18:00
参加人数 13

動機

今回は初めてのQtの勉強会への参加だった。Qt関係のイベントでは,Qt Summit 2015に参加したくらいで,ユーザーコミュニティのイベントはこれが初めてだった。

今回は,今後長い付き合いになると思われるQtとそのコミュニティの人々への顔合わせくらいのつもりで参加した。

先日開催された「CAEに関する課題雑感(CAE情報交換会)」で記したとおり,自分の目標として以下の2点を掲げている。

  1. 大気環境の数値解析のソフトの作成
  2. HTMLエディターの作成

このどちらにもGUIが必要である。これに向けてこれまで時間をかけてGUIのライブラリー(GTK+, wxWidgets, Tcl/Tk, JavaFX)を調査して試してきた。その結果,Qtを採用することにした。

2017-12頃から,まずは開発になれるためにQtCreatorを使い始めた。1月からQtのドキュメントを読み始め,サンプルコードの読み書きを始めた。当面(ここ5年)は「2. HTMLエディターの作成」を念頭において活動するつもりでいる。

いきなり,着手するのは無謀であり,モチベーションが続かない。モチベーションを維持するために,適度な難易度でかつ自分に有益なソフトを作ることが,極めて重要だ。まずは,Qtに慣れるための身近な目標として以下の2ソフトの開発を行う。

  1. CUIのコマンドをGUIから行うソフト(GUIExec
  2. SNSのクライアント

2018-03末から1のGUIExecの開発に着手した。2018-04-09に転職して,開発がストップしていた。Qt勉強会はもくもく会がメインということで,本日はGUIExecの開発を進めることにした。

場所

今回は初参加だったので,参考までに場所の写真を掲載しておく。

開催地は,新宿マルネビルの9Fだった。1Fの角にセブンイレブンがあるのが目印になった。


建物外観

中を進むとエレベーターがあり,その前にイベントの案内の張り出しがあったのでわかりやすかった。

イベントの案内

会場

13:00に到着したのだが,来ていたのは一人だけだった。13:00会場で,13:30から自己紹介だったようだ。僕が来て少ししてもう一人来た。その人から,Qtのステッカーシールをもらった。Qtの現在のロゴはシンプルで洗練されていてカッコいいので嬉しかった。すぐに一番大きなシールをノートパソコンに貼った。


Qtのステッカーシール

13:30付近に集まりだして,最終的に12人が参加した。会場はエアコンがきいており,電源とWiFiも完備,さらにはプロジェクターまであったので,会場としてとてもよかった。

幹事が大量のお菓子を持ってきていたのが驚いた。供給過多だった。お菓子持参可能とあったので,挨拶代わりにお菓子を持ってきたのだが,けっこう大きかったので持ち帰ることにした。

参加者の年齢層はやや高い印象を持った。QtはC++のライブラリーであり,C++自体の難易度が高いため,ある程度年齢層があがるのはしかたないのかもしれない。多くの人は仕事で何らかの関わりがあるようだった。

作業

今までローカルで作業していて,特にコミットしていなかったので,作業前に一旦コミットした。

現在開発中のGUIExecは以下の外観となる。

GUIExec外観

GUIのテキストフォームに実行したいプログラムや引数を入力して[Run]を押下すると,その実行結果が[EXIT CODE], [STDERR], [STDOUT]に出力される。

画面のUIはQMLで作っており,コマンドの実行部分だけC++で実装している。

本日の作業前の段階では,STDERRをうまく受け取れていなかった。指定したコマンドの実行はQProcessで行っているのだが,関数のreturnで一度に複数の値を返す方法がわからなくて止まっていた。

GUIExec/main.cpp at bd7d3d9621e95baf4e7be41ee7a5c363bebf4af6 · senooken/GUIExec
    Q_INVOKABLE QString exec(QString exe)
    {
        QProcess process;
        process.start(exe);
        process.waitForFinished(-1);
        qDebug(process.readAllStandardError());
        return process.readAllStandardOutput();
}

単純にC++のstd::mapなどを使おうとすると,QMLでデータ型を変換できないので,何らかのQtのデータ型を使う必要があると考えていた。

調べていたら,QVariantMapを使えば,QMLでもデータを使うことができるようで,比較的簡単に解決できた。ただし,コマンドが見つからなかった場合などに何も表示されなくて困った。

シェル上では存在しないコマンドを実行した場合,[command not found]と表示されるのだが,これが取得できなかった。

Qprocess::start()が失敗した場合,QProcess::errorOccurredシグナルが発生するので,これで識別する必要があるようだった。slotを用意してconnectする場合,専用の関数を用意する必要があって,冗長になるので避けたかった。

相談したところ,Qt5からSignal Slotの構文が更新され,ラムダ式が使えるようになったらしい。自分で試して書いてみたが,何かコンパイルエラーが出てしまいうまくいかなかったので,再びみてもらって解決した。従来であれば,以下のようにシグナルとスロットのオブジェクトの指定が必要だった。

connect(
    sender, SIGNAL( valueChanged( QString, QString ) ),
    receiver, SLOT( updateValue( QString ) )
);

スロットのオブジェクトは省略して関数だけ実行させることが可能になったようだ。

最終的に,コマンドを実行してその結果を返却する処理は以下の通りとなった。

修正後ソース
    Q_INVOKABLE QVariantMap exec(QString exe)
    {
        QProcess process;
        QVariantMap map;

        connect(&process, &QProcess::errorOccurred, [&](QProcess::ProcessError e) {
            map.insert("stderr", QMetaEnum::fromType<QProcess::ProcessError>().key(e));
        });

        process.start(exe);
        process.waitForFinished(-1);

        if (!map.count("stderr"))
          map.insert("stderr", process.readAllStandardError());

        map.insert("stdout", process.readAllStandardOutput());
        map.insert("exit", process.exitCode());

        return map;
}

stderrだけでなく,exitコードやエラーが発生したときに数字だけだと意味がわからないので,metaEnumでQtのエラーコードのenumの変数名を表示するようにしたりした。

そもそも,Qt5でSignal/Slotの構文に更新があったということを知らなかった。今までは,QMLを重点的に見ていたので,QtCore側での更新内容をチェックしきれていなかった。自分の勉強不足を痛感した。

わかっている人が見れば一発で解決できる問題であっても,初学者であれば解決できなくて先に進めないということがよくある。勉強会に参加して助けてもらえて先に進めたので,とてもありがたかった。ただし,甘える形になり,他人に負担をかけてしまうので,心苦しいのでできるだけ減らしたい。

まとめ

初めてのQt勉強会の参加だった。

もくもく会だったので,慣れない環境,見知らぬ人の近くでの作業だったので,自分としては落ち着かず作業効率はあまりよくなかった。しかし,それ以上にわからないところや躓いたところを質問して助けてもらえたのがとてもありがたかった。

作業効率に関しては,持ち運び可能な外部モニターを持参して出先でもデュアルディスプレイにできれば緩和されると予想している。

今後,継続して参加できるかどうかわからないが,つまづいたときや自分の作業の進捗があればその相談や報告という名目で参加させてもらいたいと考えている。

今後もどうぞよろしくしていただきたい。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です