Qt小技集
CUIもQtで行こうよ
* 諸事情により一部画像は、発表時から差し替えております。ご想像によりご自由な画像を思い浮か
べてお読みください。
13年6月17日月曜日
自己紹介
Twitter :hermit4
職業 : 文系出身のプログラマ
所属   :フリーランス
分野   :最近何でも屋の雰囲気
最近の興味 : プライベート時間の作り方
最近の課題 : 勉強時間の確保
13年6月17日月曜日
本日のお題
• Qt5って美味しいの?Qt4.8で行きます!
• QMLってなんだっけ。C++で行きます!
• GUIはQMLでいいじゃん。CUIで行きます。
13年6月17日月曜日
QtでCUIってぶっちゃけどうなの?
• 正規表現が使えます
• Write-on-copy等に対応したコンテナ
• 強化された文字を扱うQStringの利用
• 豊富なマルチスレッド機能
• シグナルやスロットを使ったイベントドリブンな設計
13年6月17日月曜日
QtでCUIってどう作るの?
13年6月17日月曜日
QtでCUIってどう作るの?
13年6月17日月曜日
QtでCUIってどう作るの?
13年6月17日月曜日
QtでCUIってどう作るの?
イベントループが回り続けるだけなので、何も
せず終了もしないプログラムが出来るだけで
す。
13年6月17日月曜日
QtでCUIってどう作るの?
返事が無い。
ただのしかばねのようだ・・・
イベントループが回り続けるだけなので、何も
せず終了もしないプログラムが出来るだけで
す。
13年6月17日月曜日
QtでCUIってどう作るの?
// 心配になってGoogle検索したら出てきたブログ記事から抜粋
#include <QCoreApplication>
#include <iostream>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
std::cout << "Hello World." << std::endl;
return a.exec();
}
標準出力へメッセージを出した後、イベントループ待ちするため、終了しないコ
マンドになります。死んだわけではなく、イベント待ちしているのですが、コンソ
ールアプリとしては間違ってます。
13年6月17日月曜日
QtでCUIってどう作るの?
// 心配になってGoogle検索したら出てきたブログ記事から抜粋
#include <QCoreApplication>
#include <iostream>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
std::cout << "Hello World." << std::endl;
return a.exec();
}
Hello World.
もの言わなくなった。
死んでしまうとは情けない・・・
標準出力へメッセージを出した後、イベントループ待ちするため、終了しないコ
マンドになります。死んだわけではなく、イベント待ちしているのですが、コンソ
ールアプリとしては間違ってます。
13年6月17日月曜日
QtでCUIってどう作るの?
#include <iostream>
// ただ表示するだけなら、これだけで良いのです
int main(int argc, char *argv[])
{
std::cout << "Hello World." << std::endl;
return 0;
}
Qt
SOUND
ONLY
Qtはどこへ・・・。わたし気になります。
13年6月17日月曜日
QtでCUIってどう作るの?
#include <QTextStream>
static QTextStream cout(stdout);
int main(int argc, char* argv[])
{
Q_UNUSED(argc);
Q_UNUSED(argv);
cout << "Hello World" << endl;
return 0;
}
Qt
SOUND
ONLY
QCoreApplicationはいらないのですか?
無理矢理Qt使ってみていますが、
とはいえ使う意味はあまりないプ
ログラムになります
13年6月17日月曜日
QCoreApplicationは必要?
無くてもQtの色々は使えます
• Qt定義のタイプを使えます(qreal, qint16, qint32, qint64)
• コンテナクラスを使えます(QList, QVector,QMap)
• QTextStream経由でコンソールに文字出せます
• QString, QVariantなんかも使えます
13年6月17日月曜日
• Event LoopとEvent Handling
• アプリケーションおよびライブラリのPATH取得
• 国際化及び翻訳機能
• コマンドライン引数への簡単アクセス
• ロケールの設定
QCoreApplicationで出来る事
13年6月17日月曜日
• いわゆるシグナルとスロットを使うもの
• QTimer
• QProcessで終了をスロット検知する
• QThread間のやり取り
• QFileSystemWatcherのような監視してるもの
Event LoopとEvent Handling
13年6月17日月曜日
• QString	

QCoreApplication::applicationDirPath()
• QString	

QCoreApplication::applicationFilePath()
• qint64	

 QCoreApplication::applicationPid()
• QStringList	

QCoreApplication::libraryPaths()
• void QCoreApplication::addLibraryPath(const QString& path)
アプリケーションやライブラリのパス取得
13年6月17日月曜日
国際化と翻訳
#include <QTextStream>
#include <QCoreApplication>
#include <QTranslator>
static QTextStream cout(stdout);
int main(int argc, char* argv[])
{
QCoreApplication app(argc, argv);
QTranslator trans;
trans.load("hello.qm");
app.installTranslator( &trans );
cout << QObject::tr("Hello World") << endl;
return 0;
}
13年6月17日月曜日
lupdate hello.pro -ts hello.ts
linguist hello.ts
国際化と翻訳
13年6月17日月曜日
国際化と翻訳
13年6月17日月曜日
コマンドライン引数への簡単アクセス
QStringList QCoreApplication::arguments()
ちなみに、これstaticなメンバ関数です。
QStringListなので、オプション解析は自力でも
簡単にできるかと。
arguments().contains(“-t”)
順番や無効引数でhelpが必要とかいうなら、
loopしながら見てくなりすれば良いと思うよ
13年6月17日月曜日
ところで
Qt
SOUND
ONLY
小技はどこへ・・・。わたし気にな(ry
コンソールアプリ作るときの小技紹介のつもりで、そもそもコ
ンソールアプリの作り方を話しただけで時間無くなってしまう
計算に・・・・。内容を良く考えもせずタイトルだけ伝えてあ
ったもので・・・。実際この時点で残り時間5分ちょっと。
とはいえ、タイトル詐欺に成らないように駆け足でざっくり小技
のご紹介をしました。
13年6月17日月曜日
小技(1) QDebug
Qtでデバッグ出力といったら<QDebug>
実は、このデバッグ、書き出し先や挙動を変更できます。
qDebug() << “hogehoge”;
qWarning() << “Warning”;
qCritical() << “Critical”;
QtMsgHandler qInstallMsgHandler(QtMsgHandler handler)
を使います。
13年6月17日月曜日
小技(1) QDebug
#include <qapplication.h>
#include <stdio.h>
#include <stdlib.h>
void myMessageOutput(QtMsgType type, const char *msg)
{
switch (type) {
case QtDebugMsg:
fprintf(stderr, "Debug: %sn", msg);
break;
case QtWarningMsg:
fprintf(stderr, "Warning: %sn", msg);
break;
case QtCriticalMsg:
fprintf(stderr, "Critical: %sn", msg);
break;
case QtFatalMsg:
fprintf(stderr, "Fatal: %sn", msg);
abort();
}
}
int main(int argc, char **argv)
{
qInstallMsgHandler(myMessageOutput);
QApplication app(argc, argv);
...
return app.exec();
}
13年6月17日月曜日
小技(2) QtGlobal - typedef
qint8
qint16
qint32
qint64
qlonglong
qptrdiff
qreal
quint8
quint16
quint32
quint64
quintptr
qulonglong
uchar
uint
ulong
ushort
各自がバラバラに作り
やすいtypedef
Qtを使えば解決じゃん
というおはなし
13年6月17日月曜日
小技(3) QtGlobal - 演算関数
T	

 qAbs ( const T & value )
const T &	

 qBound ( const T & min, const T & value, const T & max )
bool	

qFuzzyCompare ( double p1, double p2 )
bool	

qFuzzyCompare ( float p1, float p2 )
const T &	

 qMax ( const T & value1, const T & value2 )
const T &	

 qMin ( const T & value1, const T & value2 )
qint64	

 qRound64 ( qreal value )
int	

 qRound ( qreal value )
qFuzzyCompareは、その名の通り適当な感じで比較しているので、計算
機イプシロンを使った厳密な比較ではないものの、浮動小数点の簡易的
な比較には十分使える。
13年6月17日月曜日
浮動小数点数の補足説明(追記)
便利そうという顔をした人が少ない気もしたので念のため補足。floatもdoubleも使わない業界の人はずっと使わないですしね
ぇ・・・。かく言う私も、この仕事についてかなり後の方でした、floatやdoubleをガリガリ使う仕事についたのは。
現代のコンピュータにおいては、実数であっても有限なビット数の2進数を使って表現しています。
実装方法は色々ですが、WikipediaのIEEE 754とか、その辺りを見ると割と一般的に使われているものが説明されています。いや、IEEE
754自体を読むのが正しいとは思いますけど、知らないと言う事は必要な局面に立っていないのでしょうし、楽な解説読めばいいんじ
ゃなイカ。
で、Google先生に聞けば、文系出の私の知識よりよっぽど詳しく正しいものが見つかりそうなので省きますが、floatやdoubleには、同
じ数字に思えても、誤差を含んでいる場合があります。このため、C,C++において、!=や==は正常に動作しない場合があります。
こういった比較をする時は、比較する「実数同士の差の絶対値」が、「ある数値」を超えるか否かで判断します。この「ある数値」
は、非常に厳密にやるなら、”比較する数のうち「大きい数」とその「大きい数を超えた最小の数」の差”を比較対象にするのです
が、いちいち比較の度にこれを厳密に求めるのは無駄な場合が多い(そこまで厳密である必要が無い事が多い)ので、システムとし
て必要な有効桁数を決めてざっくり決めるのが現実的かと思います。で、Qtの方で適当に決めた範囲で比較してくれてますというお
話です。ただし、かなりざっくりな事は覚悟して使って下さいと。
なお、1.0と1.0を超える最小の数値を計算機イプシロンと呼びます(と私は人に教わりました)が、C,C++では、1.0と1.0を超える最小
の数値の差をFLT_EPSILON, DBL_EPSILONと定義していたりで、こちらをイプシロンと呼ぶ人もいます。ちなみにこのイプシロンです
が、1.0の場合の話で、1.0より小さい数の場合、もっと小さな値になる相対的なものです。また、人によっては、その相対的な差の事
をイプシロンと呼ぶ人もいるので注意が必要です。まぁ、イプシロンについては、Cで定義されているイプシロンは、「1.0と1.0を超
える最小の数との差」で、それをそのまま等号比較に使ってはいけないとだけ覚えておけば良いでしょう。
あとは、相当真面目にやらなきゃ行けない仕事についた時に頑張って調べ直して下さい。
13年6月17日月曜日
小技(4) QtGlobal - rand関数
int	

 qrand ()
void	

qsrand ( uint seed )
seedをもとにしたランダム値の生成。Thread-safe版
小技(5) QtGlobal - 環境変数
環境変数の取得・設定用の関数
QByteArray	

 qgetenv ( const char * varName )
bool	

qputenv ( const char * varName, const QByteArray & value )
13年6月17日月曜日
小技(6) QtGlobal - マクロ編
QT_REQUIRE_VERSION ( int argc, char ** argv, const char * version )
必要なQtバージョンを指定できる。
(GUIのみ) QMessageBoxに定義されている
#include <QApplication>
#include <QMessageBox>
int main(int argc, char *argv[])
{
QT_REQUIRE_VERSION(argc, argv, "4.0.2")
QApplication app(argc, argv);
...
return app.exec();
}
13年6月17日月曜日
小技(6) QtGlobal - マクロ編
Q_BYTE_ORDER
ビルド環境のエンディアンに応じた処理を記述できる
#if Q_BYTE_ORDER == Q_BIG_ENDIAN
...
#endif
or
#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
...
#endif
その他、assertの変わり、コンパイラやQtバージョンのマクロ等もある
ので、見てみるとこれはと言う物がみつかるかも
http://qt-project.org/doc/qt-4.8/qtglobal.html
13年6月17日月曜日
小技(7) .pro編
元々Qt Creatorを使っていなかった時代の知識なので、若干古くさいで
すが、qmake用の.proファイルを手作業でいじるお話です。
QtはデフォルトでlibQtGUIとリンクしようとするので、それをはずすに
は.proファイルに以下の記述が必要です。
Qt -= gui
Qtはモジュールと呼ばれる単位に分かれています。(完全に奇麗に分か
れているかは少し怪しい所もありますが)使いたいモジュールを足して
いきます。
13年6月17日月曜日
小技(6) .pro編
network ネットワーク関連クラスを使う
sql データベース関連のクラスを使う
xml XML関連で、SAX,DOMを使う
xmlpatterns XPath,XQuery,XSLT,SchemaValidation
script スクリプトエンジンの組込み
CUIで使えそうなものだけ抜き出してみました。
マニュアルのAll ModulesでModuleを選択すると何をQT+=するか出てま
す。
13年6月17日月曜日
小技(7) .pro編
アプリケーション名、インストール先を変える
TARGET = hello
target.path = /usr/local/bin
INSTALLS += target
これで生成されるMakefileには、インストール用の設定が行われます。
13年6月17日月曜日
小技(7) .pro編
複雑になり始めたアプリケーション構成への対応
TEMPLATE = lib
qmake -projectで生成されるのは、基本アプリケーションビルド用のの
appですが、ライブラリを生成したい時には、lib templateを選択します。
TEMPLATE = subdirs
SUBDIRS += lib hello
ちなみに、subdirsを使うと、サブディレクトリを分けてそれぞれの下を
巡回してqmakeを行い、サブディレクトリをたどるMakefileを生成してく
れます。
13年6月17日月曜日
ご清聴ありがとうございました
もともとQtをあまり知らない人用にと思って書いたのでみなさんには
既知の内容が多かったかもしれません。
RubyやPython等のお手軽さに比べるとビルドの必要性ややらなければな
ことの多さで負けていますが、処理するものの量が多ければ、Qtの方
が有用な場合もあります。
ちょとしたスクリプトを書いた時、お暇があれば、Qtを使って書き直
してみてはどうでしょうか。
13年6月17日月曜日

Qt小技(修正版)