リード開発メモ

大阪のソフトウェア会社です。 技術的な事柄についてのメモとしてブログを始めます。

2015年08月

Qt を使う(その2)

Qt を使ってみる2回目
今回は新規プロジェクトを作成し、画面にラベルとボタンを置き、ボタンを押されたらラベルの表示を変えてみる。

まず、Vsiaul Studio 2010のメニューから
    ファイル - 新規作成 - プロジェクト - Qt4 Projects - Qt Application
を選択。
名前は QtTest1 とした。
qt6

OKを押すと Qt GUI Projects Wizard が立ち上がった。とくに変更しない。このまま Finish。
qt7

Form Files の qttest1.ui をダブルクリックすると Qt Designer が立ち上がるので、Label と Push Button をフォームにドロップする。
ドロップしたら、右側のプロパティウィンドウにある ObjectNameプロパティを label1、pushButton1 と変更しておく。
qt10

保存し、Qt Designer を閉じる。

pushButton1 が押されたら label1 に「Hello World」と表示するためには、qttest1.h を以下のように編集する。 「public slots:」を使い、「on_pushButton1_clicked」という名前にしておくことによって、自動的にボタンが押されたときの処理となるようだ。
#ifndef QTTEST1_H
#define QTTEST1_H

#include 
#include "ui_qttest1.h"

class QtTest1 : public QMainWindow
{
	Q_OBJECT

public:
	QtTest1(QWidget *parent = 0, Qt::WFlags flags = 0);
	~QtTest1();

private:
	Ui::QtTest1Class ui;

public slots:
    void on_pushButton1_clicked() {
        ui.label1->setText("Hello World");
    }
};

#endif // QTTEST1_H


別の名前を使う場合は「QObject::connect」を使って、自分でイベントを接続してやる必要がある。
qttest1.h で以下のようにメソッド名を変えたとすると、これだけでイベントは処理されなくなってしまう。
#ifndef QTTEST1_H
#define QTTEST1_H

#include 
#include "ui_qttest1.h"

class QtTest1 : public QMainWindow
{
	Q_OBJECT

public:
	QtTest1(QWidget *parent = 0, Qt::WFlags flags = 0);
	~QtTest1();

private:
	Ui::QtTest1Class ui;

public slots:
    void onPushButton1Clicked() {
        ui.label1->setText("Hello World");
    }
};

#endif // QTTEST1_H

この場合は QObject::connect を使って SIGNAL と SLOT を結びつける必要があるようだ。
たとえば qttest1.cpp のコントラクタなどで QObject::connect を使って関連づけておく。
#include "qttest1.h"

QtTest1::QtTest1(QWidget *parent, Qt::WFlags flags)
	: QMainWindow(parent, flags)
{
	ui.setupUi(this);

	QObject::connect(ui.pushButton1, SIGNAL(clicked()), this, SLOT(onClickPushButton1()));
}

QtTest1::~QtTest1()
{

}

以上です。

Qt を使う(その1)

Windows で Qt を使ってみる。
ただし都合により、環境は Vsiaul Studio 2010 で、Qt は 4.8.5 を使用する。

今回は開発環境を整える。

Qt は以下よりダウンロードできる。
Vsiaul Studio 2010 用のバイナリ版の qt-win-opensource-4.8.5-vs2010.exe をダウンロードする。
http://download.qt.io/archive/qt/4.8/4.8.5/

ダウンロードしたらインストールする。 qt1

今回はCドライブの直下にインストールした。
qt2

ちなみに、インストールすると環境変数に QTDIR 、QTJAVA が追加される模様。

次に、以下から Visual Studio用のadd-inをダウンロードしてインストールする。
http://download.qt.io/archive/vsaddin/

インストールすると Vsiaul Studio 2010 に 「Qt」 というメインメニューが追加される。
qt3

また、Qt プロジェクトのテンプレートが追加される。
qt5

以上です。

LINQ to SQL で Group by して上位1件を取得する

テーブルAとBがあり、AとBは1対Nになっているとする。
AとBを結合し、Aの項目a_groupごとにグループ化して、Bの項目b_dateのもっとも古いものだけを取り出したいとする。

SQL Server で普通にやる場合、row_number を使った以下のような SQL を思いつく。
select * from (
    select
        row_number() over (partition by A.a_group order by B.b_date, B.b_id) as rn,
        B.*
    from A 
    inner join B
        on A.a_id = B.a_id
) t
where rn = 1

これを LINQ to SQL で書けば以下のようになる。
var query = from dr in db.B
            join cr in db.A
                on B.a_id equals A.a_id
            group dr by new { aGroup = cr.a_group } into gdr
            select gdr.OrderBy(x => x.b_date).ThenBy(x => x.b_id).First();

そして、実際に LINQ to SQL が実行する SQL を見てみると、row_number は使わず outer apply を使っていた。
以下のような SQL になると思うが、たしかに最初の SQL とこちらの SQL は同じ結果となる。なるほど。
ただし、select される項目は違う。
outer apply は outer apply 句の前の select 項目の後ろに、outer apply 句の後の select 項目がくっつく。
select * from (
    select A.a_group
    from A 
    inner join B
        on A.a_id = B.a_id
    group by A.a_group
) t
outer apply (
    select top 1 B.*
    from A 
    inner join B
        on A.a_id = B.a_id
    where t.a_group = A.a_group
    order by B.b_date, B.b_id
) u

以上です。

LINQ to SQL で実行される SQL を出力ウィンドウに表示する

LINQ to SQL で実行される SQL を出力ウィンドウに表示する方法。

まず、次のようなクラスを定義する。
class DebugTextWriter : System.IO.TextWriter {
   public override void Write(char[] buffer, int index, int count) {
       System.Diagnostics.Debug.Write(new String(buffer, index, count));
   }

   public override void Write(string value) {
       System.Diagnostics.Debug.Write(value);
   }

   public override Encoding Encoding {
       get { return System.Text.Encoding.Default; }
   }
}

そして System.Data.Linq.DataContext の Log プロパティにセットしてやればいいようだ。
db.Log = new DebugTextWriter();

また、ファイルに書き出す場合は以下のようにする。
   db.Log = new System.IO.StreamWriter("sql.log") { AutoFlush = true };

以上です。

アクセスカウンター
  • 今日:
  • 昨日:
  • 累計:

livedoor 天気