Qt 5 の未来は明るいブログ

オープンソースカンファレンス 2014 Tokyo/Fall に日本 Qt ユーザー会として参加しました

Published: 2014-10-20

10月18日から2日間に渡って 明星大学 日野キャンパス で開催された オープンソースカンファレンス 2014 Tokyo/Fall に「日本 Qt ユーザー会」として参加しました。

展示ブース

Qt Developer Day Tokyo 2014 の時に作った、テーブルクロスが素敵過ぎて死にそうです。

それから、前回の反省を踏まえて、Qt と日本 Qt ユーザー会の紹介の冊子を作成しました。

画期的なバグの修正の仕方ですが、決して真似はしないようにしましょう。

あと、私のむちゃぶりで実現した新しい Qt のシールも配ることができました。

Qt ブースにお越しいただいたみなさん、ありがとうございました!

Continue reading...

Qt 勉強会 #15 @Tokyo 開催しました

Published: 2014-09-30 / Last modified: 2014-09-30

2014年9月27日(土曜日)に Qt 勉強会 #15 @Tokyo株式会社 PTP さんのミーティングルームで開催しました。

今月は諸事情により第4土曜日の開催になりました。来られなかった方すいません。

簡単な自己紹介

今回は参加者が10人。学生(高校生)の方が1人、初めて参加された方が1名でした。

もくもく

自己紹介の後は自由時間ということで、自分のやりたいことを進めながら、誰かが質問したり、なんかの発表があったりという形で進めていきました。

おやつ

Qt の本を書こう

と、宣言をして色々調べました。

過去の資料を発掘したり、

4年前に書いた記事 を読み返したり、

Re:VIEW を試すために texlive と格闘していたりという感じで、文章は一文字も書かずに終わってしまいました。

OSC 2014 Tokyo/Fall の準備

メーリングリストにそろそろブース当番を決めましょう!という投稿をしました。

Continue reading...

QtQuick でコマンドライン引数を定義し扱う

Published: 2014-09-23 / Last modified: 2014-09-23

こんな要望を受けて、自分で作ってみました

$ git clone git://git.qtquick.me/qmlplugins/commandlineoptions.git
$ cd commandlineoptions
$ qmake
$ make
$ (sudo) make install
import me.qtquick.CommandLineOptions 1.0

Rectangle {
width: 300
height: 100

CommandLineOptions {
id: cmo
property bool boolOption
property string stringOption: "default"
property string string_option: "default"
default property var options
}
}

こんな風に QML に書くと、qmlscene などに渡されたコマンドライン引数を自動で解析して値が入ります。

default がついたプロパティがある場合には、オプション形式以外の引数がそこに文字列の配列で入ります。

内部的な処理は、CommandLineOptions エレメントが生成された時点で定義されたプロパティを取得し、コマンドライン引数を扱う方法 の仕組みを使って引数を解析してプロパティに設定しています。実装に興味のある方は CommandLineOptions::componentComplete() を参照してください。

これでまた一つ Qt/C++ 書かなくてよくなりました!

QtQuick の import のデバッグは QML_IMPORT_TRACE=1 で

Published: 2014-09-22

import なんとか 1.0

がなんか動かないことありますよね。この場合まず環境変数「QML_IMPORT_TRACE」に値をセットすることで内部的な処理(どのプラグインを読み込んでいるのか、どのエレメントをどう解決しているのかなど)をデバッグ出力することができます。

よく忘れるのでメモでした。

Qt から VoiceText Web API(β版) を使う

Published: 2014-08-24 / Last modified: 2014-08-25

Qt 勉強会 #14 @ Tokyo で倒せなかった VoiceText Web API(β版) を Qt/Quick で簡単に使えるようにしてみました。

API利用登録

API キーを取得してください。

ソースコードのダウンロード、コンパイル、インストール

$ git clone git://git.qtquick.me/qmlplugins/qtvoicetextwebapi.git
$ cd qtvoicetextwebapi
$ perl Qtがインストールされている場所/bin/syncqt.pl -version 0.1.0
$ cd ..
$ mkdir build
$ qmake ../qtvoicetextwebapi/
$ (n)make
$ (sudo) make install
$ make sub-examples

Widget サンプル

$ ./examples/widget/widget

Continue reading...

Qt 勉強会 #14 @Tokyo 開催しました

Published: 2014-08-24 / Last modified: 2014-08-24

2014年8月23日(土曜日)に Qt 勉強会 #14 @Tokyo株式会社 PTP さんのミーティングルームで開催しました。

簡単な自己紹介

今回は8人中、初めて参加された方が2名、大学(院)生さんが2名という感じでした。

もくもく

自己紹介の後は自由時間ということで、自分のやりたいことを進めながら、誰かが質問したり、なんかの発表があったりという形で進めていきました。

おやつ

Qt のヘッダファイルのインクルードガードの大文字化

qtbase/src/widgets/widgets/qwidgetlinecontrol_p.h

#ifndef QWidgetLineControl_P_H
#define QWidgetLineControl_P_H

...

#endif // QWidgetLineControl_P_H

となっていたので他にも同じようになっている箇所を探して修正しようと思ってましたが、やり始めるとコンパイルしているだけで勉強会が終わってしまいそうだったのでやめました。

だれか代わりに修正してもらえませんか?

Continue reading...

Qt 勉強会 #13 @Tokyo 開催しました

Published: 2014-07-21 / Last modified: 2014-07-21

2014年7月19日(土曜日)に Qt 勉強会 #13 @Tokyo株式会社 PTP さんのミーティングルームで開催しました。

簡単な自己紹介

今回は初めて参加された方が4名、大学生さんが1名、高校生が2名という感じでした。

もくもく

自己紹介の後は自由時間ということで、自分のやりたいことを進めながら、誰かが質問したり、なんかの発表があったりという形で進めていきました。

おやつ

QState クラスの API の追加

と提案をしてみたところメンテナの人から「Good idea」と言われたので(なんかやれって言われてる気がして)色々調べてみました。

QFinalState *s2 = new QFinalState();
s1->addTransition(&button, SIGNAL(clicked()), s2);

を以下のようにも記述できるようにするのが目標です。

QFinalState *s2 = new QFinalState();
s1->addTransition(&button, &QPushButton::clicked, s2);

QObject::connect の関数ポインタ版のコードはテンプレートを使った以下のようなものになっています。

template <typename Func1, typename Func2>
static inline QMetaObject::Connection connect(const typename QtPrivate::FunctionPointer<Func1>::Object *sender, Func1 signal,
                        const typename QtPrivate::FunctionPointer<Func2>::Object *receiver, Func2 slot,
                        Qt::ConnectionType type = Qt::AutoConnection)
{
    typedef QtPrivate::FunctionPointer<Func1> SignalType;
    typedef QtPrivate::FunctionPointer<Func2> SlotType;

    Q_STATIC_ASSERT_X(QtPrivate::HasQ_OBJECT_Macro<typename SignalType::Object>::Value, "No Q_OBJECT in the class with the signal");

    //compilation error if the arguments does not match.
    Q_STATIC_ASSERT_X(int(SignalType::ArgumentCount) >= int(SlotType::ArgumentCount),
                "The slot requires more arguments than the signal provides.");
    Q_STATIC_ASSERT_X((QtPrivate::CheckCompatibleArguments<typename SignalType::Arguments, typename SlotType::Arguments>::value),
                "Signal and slot arguments are not compatible.");
    Q_STATIC_ASSERT_X((QtPrivate::AreArgumentsCompatible<typename SlotType::ReturnType, typename SignalType::ReturnType>::value),
                "Return type of the slot is not compatible with the return type of the signal.");

    const int *types = 0;
    if (type == Qt::QueuedConnection || type == Qt::BlockingQueuedConnection)
        types = QtPrivate::ConnectionTypes<typename SignalType::Arguments>::types();

    return connectImpl(sender, reinterpret_cast<void **>(&signal),
                receiver, reinterpret_cast<void **>(&slot),
                new QtPrivate::QSlotObject<Func2, typename QtPrivate::List_Left<typename SignalType::Arguments, SlotType::ArgumentCount>::Value,
                        typename SignalType::ReturnType>(slot),
                type, types, &SignalType::Object::staticMetaObject);
}

シグナル/スロットの接続の場合には引数の数や型の静的チェックが行われていますね。

そこから呼ばれる connectImpl はこんな感じです。

QMetaObject::Connection QObject::connectImpl(const QObject *sender, void **signal,
                                             const QObject *receiver, void **slot,
                                             QtPrivate::QSlotObjectBase *slotObj, Qt::ConnectionType type,
                                             const int *types, const QMetaObject *senderMetaObject)
{
    if (!signal) {
        qWarning("QObject::connect: invalid null parameter");
        if (slotObj)
            slotObj->destroyIfLastRef();
        return QMetaObject::Connection();
    }
 
    int signal_index = -1;
    void *args[] = { &signal_index, signal };
    for (; senderMetaObject && signal_index < 0; senderMetaObject = senderMetaObject->superClass()) {
        senderMetaObject->static_metacall(QMetaObject::IndexOfMethod, 0, args);
        if (signal_index >= 0 && signal_index < QMetaObjectPrivate::get(senderMetaObject)->signalCount)
            break;
    }
    if (!senderMetaObject) {
        qWarning("QObject::connect: signal not found in %s", sender->metaObject()->className());
        slotObj->destroyIfLastRef();
        return QMetaObject::Connection(0);
    }
    signal_index += QMetaObjectPrivate::signalOffset(senderMetaObject);
    return QObjectPrivate::connectImpl(sender, signal_index, receiver, slot, slotObj, type, types, senderMetaObject);
}

関数ポインタからシグナル QMetaObject の中のシグナルの特定をしているので、同じ事をすると実現できそうです。

勉強会中にたどり着いたのはここまででしたが、暇を見つけて続きもやってみようかな?と思っています。

みんなの疑問/質問に答えよう

「質問あったら気軽に聞いてください」と言っても初心者の方や初めて来た方が自分から質問を切り出すのはなかなか難しいですよね。というわけで、Qt で何かを作っている上で困っていることや気になってることがないかを聞いて回ってみました。2周くらいしたかな?

Qt Quick 関連の質問であれば「本のこの辺見たら書いてあるよ」で済むのですが、C++ の方になると Qt 5 で書かれた参考になるコードがすぐには見つからないので結構めんどくさいですね。Qt 4 時代のコードであればあれこれ出せるものもあるのですが。。。

Continue reading...

Linux(XCB) で QWindow::setWindowTitle が即座に反映されないバグの修正

Published: 2014-06-28 / Last modified: 2014-07-04

ふとしたことから QWidget::setWindowTitle が XCB 上でうまく動いていないことに気づいたので直しました。今回は楽勝でした。

再現するための最小限のコード

#include <QtWidgets>

int main(int argc, char *argv[])
{
        QApplication app(argc, argv);

        QLabel label(QStringLiteral("Hello World!"));
        label.resize(250, 100);
        label.show();

        QTimer timer;
        QObject::connect(&timer, &QTimer::timeout, [&]() {
                label.setWindowTitle(QTime::currentTime().toString());
        });
        timer.start(100);
        return app.exec();
}

QTimer を使用して 0.1 秒毎に現在時刻をウィンドウのタイトルバーに設定しています。

これによって毎秒時刻が表示されるはずなのですが、Gentoo Linux 上で試したところ不定期に更新される(正確には、なにかしらの操作や描画イベントのタイミングで更新される)という感じで正常に動作していませんでした。

どのへんに問題がありそうか

Linux 向けの XCB 対応の問題なのか、Windows や Mac でも再現するのかを切り分けるため、Twitter で聞いてみたところ、

という返事をいただき、多分 XCB の中に問題があるんだろうという感触を得ました。

Continue reading...

Qt Developer Day Tokyo 2014 のキーノートの動画が公開されました

Published: 2014-06-25 / Last modified: 2014-06-25

また、Qt Developer 2014 Tokyo のセッションのページ に各セッションで使用された資料やサンプルコードなども公開されています。

Qt 勉強会 #12 @Tokyo 開催しました

Published: 2014-06-22 / Last modified: 2014-06-22

2014年6月21日(土曜日)に Qt 勉強会 #12 @Tokyo株式会社 PTP さんのミーティングルームで開催しました。

Qt Developer Day Tokyo 2014 が大変盛り上がって以来の今回の勉強会ですが、参加者の数も普段と変わらず、いままでどおりの楽しい勉強会となりました。

今回のおやつ

Qt おやつ部の部員などが持ち寄ったお菓子を食べながら各自もくもくと Qt の勉強をしたりなにかを作ったりしていました。

簡単な自己紹介

今回は初めて参加された方が2名、学生さんが1名という感じでした。参加登録されて来られなかった方も2名いらっしゃいました。

もくもく

自己紹介の後は自由(自習?)タイムということで、自分のやりたいことを進めながら、誰かが質問したり、なんかの発表があったりという形で進めていきました。

Qt Quick の紹介

Qt をはじめたばかりで何から手をつけたらいいですか?という方がいらっしゃったので、Qt Developer Day Tokyo 2014 で行われた「Qt Quick の紹介」のセッションの内容を スライド(.pdf)サンプルコード(.zip) を見ながら、朝木さんに簡単にもう一度話をしてもらいました。

Qt Contributors summit 2014 の紹介

2014/6/10,11 にドイツのベルリンで開催された Qt Contributors Summit 略して QtCS の簡単な紹介をしました。

オープニングセッションの動画が公開されているので、それを見ながら簡単にどんな話がここでなされたのかを紹介しました。

後半の Qt のフラグメンテーションを解消する話がとてもワクワクする内容だったので、お暇な方は是非見てみてください。

QtCS の各セッションの議論の内容は QtCS 2014 Program にまとまっているので、今後の Qt に興味のある方はご覧ください。

Qt for iOS と QML Compiler

朝木さんに Qt for iOS のシミュレーターでのデモと、QML Compiler を試してみた話をしてもらいました。

QML Compiler は現在は有償版でのみ提供されているようですが、こういうものはちゃんとオープンソース化してみんなで開発して、みんなで使えるようにしてもらいたいものですね。

その他

初めて参加された方も、毎回参加している人も、初心者の方も、長年 Qt を使っている人も、それぞれ楽しく Qt の勉強をしていました。

Continue reading...