Qtブログ(日本語)

Qt Quick 2 のデバッグ – Console API

作成者: 鈴木 佑|Mar 22, 2012 1:20:16 PM

この記事は Qt Blog の "Debugging Qt Quick 2 – Console API" を翻訳したものです。
執筆: Aurindam Jana, 2012年3月1日

Qt Quick はより柔軟でスピーディーな開発が可能になります。これまでは「コンパイル」「パッケージング」「デプロイ」「実行」というサイクルを何度も何度も繰り返す必要がありましたが、Qt Quick では実行中にソースを変更することも可能です。Qt Creator ではバージョンが新しくなるたびに Qt Quick をさらに効果的に使うことができるようにしてきました。しかし、どんなプログラミング言語も完璧ではありません。QML では文法の間違いは実行時のエラーになります。QtDeclarative のバインディングループに悩まされた経験がある方もいると思いますが、JavaScript には嵌りどころがたくさんあります。これらに対しては、デバッガやプロファイラ、インスペクタといった武器で対抗しましょう :)

この記事ではデバッグ、特に最も簡単な Console API を使用した手法について紹介します。console.log() メソッドはこの API の一部で、すでにみなさんも helloworld.qml でこの API を使ったことがあると思いますが、使用する機会はとても多いです。少し前に、(ウェブブラウザでのデファクトスタンダードである) FireBug console API を参考に、Qt 5 の API にとても便利なメソッドをいくつか追加しました。

ログの出力

console.log と console.debug は Qt Quick 1.0 からサポートされています。QtScript 由来の print() も動作はしますが、ウェブブラウザで実行した場合とは動きが少し異なります。Qt 5 には、さらにいくつかのログ関数が追加されています。これらを実行すると Qt の対応する関数が直接呼び出されます。

JavaScript の関数 対応する Qt/C++ の関数
console.log() qDebug()
console.debug() qDebug()
console.info() qDebug()
console.warn() qWarning()
console.error() qCritical()

見ての通り、現在は console.log() と console.debug() そして console.info() は同じ動作になります。これらはよく使われるメソッドであり、インターネット上にある数えきれないほどの JavaScript のコードのサンプルにも登場するため、すべてをサポートしています。また、qlogging.h に新たなログレベルを追加することも検討中です :)

プロファイリング

あるコードの実行にどのくらいの時間を要するかを知りたいと思ったことはありませんか? onCompleted メソッドで以下のコードを試してみてください。

Component.onCompleted() {
console.time("onCompleted");
// ...
console.timeEnd("onCompleted");
}

これによりミリ秒単位での時間が表示されます。文字列型の引数は個々の測定のキーになると同時に出力のプレフィックスになります。測定を複数同時に行うことが可能で、測定範囲の重複も許されています。

onCompleted: 401ms

console.profile() と console.profileEnd() はさらに詳細な解析のために用意されています。

Component.onCompleted() {
console.profile();
}
Component.onDestruction() {
console.profileEnd();
}

この API では、QDeclarativeEngine の状態と V8 のメソッド呼び出しの両方のプロファイルを行います。このデータを取得するためには console.profileEnd() が呼び出されるよりも前に QML のプロファイラをアタッチしなければなりません。そうしない場合にはデータは破棄されます。Qt Creator の一部である QML のプロファイラについては Christiaan Janssen が以前に QML プロファイラのアップデート という記事を書いています。Qt 5 ではスタンドアローンのプロファイラが提供され、プロファイルの結果をファイルに保存することができるようになります。このファイルは Qt Creator で読み込むことができます。

さらに...

以下の API も導入しました。

console.assert() : 式の評価を行い、結果が false の場合に、メッセージと JavaScript のスタックトレースを表示します。

console.exception() : エラーメッセージと JavaScript のスタックトレースを表示します。

console.trace() : 呼び出された時点での JavaScript のスタックトレースを表示します。

console.count() : 関数の呼び出し回数を指定されたメッセージとともに表示します。

スクリプトコンソール - 見た目が変わりました

QML 用のコンソールは Qt Creator 2.1 で導入された機能です。しかし、このコンソールの機能は単純な式の評価に限定されていました。Qt Quick 2 では QML の力を発揮させるためのより高機能なコンソールが必要だと考えました。
それではスクリプトコンソールと呼ばれる新しい QML コンソールを紹介しましょう。

スクリプトコンソールでは式の評価に加え、Qt のデバッグ出力と JavaScript のコンソールメッセージも綺麗に表示されます :) 右上にあるフィルターボタンを使うことで特定のログにしぼることも可能です。また、info ボタンと warning ボタンの選択を解除するとエラーメッセージのみを見ることができます。デバッグ出力にはファイル名や行の情報も含まれ、クリックすると該当するファイルが開き、該当する行にカーソルが移動します。デバッグメッセージの出力自体にファイル名や行などの位置を特定するコードを含める必要がなくなりました。さらに、ツールバーからコンソール内の文字を検索もできるようになっています。

JavaScript のオブジェクトと配列は展開可能なツリーとしてコンソールに表示されます。式の評価に使われる現在のコンテキストはステータスバーに表示されます。Script Console はデバッグ中でなくても使用することができ、複数行の入力にも対応しています。さらに、過去に入力したものを保持しているため、長い式を何度も入力する必要もありません。

ちなみにこのスクリプトコンソールは Qt Creator 2.5 に含まれる予定なので、首を長くして待つ必要はありません。

他に足りないものは?

コンソールはコマンドラインインターフェースでしかないため、コンソールを操作するようなメソッドは今のところ実装していません。例えば、console.clear() を汎用性のある形で実装するのは難しいでしょう ;) 同じような理由で console.group() や console.groupCollapsed()、console.groupEnd()、console.table()、console.dir()、console.dirXml() なども後回しにしています。

Qt Creator のスクリプトコンソールは依然開発中です。現時点では QML のオブジェクトと配列はツリーに表示されません。今後のバージョンに向けたさらなる改善と機能の追加が必要です。

このコンソールに対するみなさんの要望や感想を是非お聞かせ下さい。メーリングリスト もしくは IRC (freenode サーバーの #qt-creator チャンネル) までお願いします。