So-net無料ブログ作成

constメンバ関数 [C++]

前回、知らない表記に出会ったので、調べておきます。以前のC++の記事同様、C++の基礎中の基礎の様な気もしてますが・・。

気になったのは、下記の様な関数の宣言です。

class QPainter
{
    const QBlush & background () const;    // ←末尾の「const」が気になる
}


気になるのは、関数末尾の「const」です。何これ?と思ったら、どうやら、「この指定がついている関数はメンバ変数の変更ができない(と言うか「しない」?)」と言うものらしいです。

こんな感じでしょうか・・。

class Test
{
public:
    int val;

    int set_get (int i) const {
        val = i;            // ←エラーになる?
        
        return val;
    }
}


でも、メンバ変数の宣言時に「mutable」と言う指定をつければ、その変数については、const メンバ関数でも書き込みができるそうです。

class Test
{
public:
    mutable int val;       // ←「mutable」で宣言

    int set_get (int i) const {
        val = i;            // ←大丈夫?
        
        return val;
    }
}


なんか、それ(mutableの方)って、どうなの?と言う仕様なのですが、ま、そう言うものの様です・・・。


【参考】
定数のconstメンバ関数をクラスに宣言 - C言語とC++入門勉強ルーム
第20章 constメンバ - C++編(言語解説)
C++ - const - ためになるホームページ
constの使い方。 関数・メンバ関数編 - akatukisidenのメモ帳






   

QPainterのメンバ関数 [Qt]

さて、かなり無理矢理感がありますが、SVGファイルから内部データ形式に変換するためにQPainterの派生クラスを作成します。なんでかと言うと前回の記事をご覧ください。

例によって、「File」→「Add New」で「C++ Class」を作成します。ベースクラスは「QPainter」ですが、選択肢にないんで、手入力しときます。

10072000.png
クラス名が長いな・・


ヘッダファイルとソースファイルが作成されますが、ちゃんとQPainterが継承されて、QPainterのヘッダのインクルードも行われています。

10072001.png
この辺は楽です


ここにメンバ関数を追加していきましょう。メンバ関数の数が多いんですよねぇ・・。ま、全てを確認する機会なんてそうそう無いでしょうから、いい機会だと考えましょう。

さて、コンストラクタ、デストラクタを除いて、Publicな関数を全部コピーしてみましたが、値を返す奴がいますね。それらについては、ちゃんとそれなりのを返す必要があります。う~ん、うまくいくかな・・。

ちなみに、関数の最後に「const」と言うキーワードが付いているのがあります。これは何でしょう・・?


ちょっと、調べます。つづく。





SVGファイルの読み込み [Qt]

前回、データの書き出しができたので、今回は読み込みを行おうと思います。前回の記事で、終了時に保存するようにしたファイルを起動時に読み込むと言う感じです。

読み込んだデータの編集を行う可能性があることを考えると、読み込みの際には、単にデータを表示するだけでなく、データを編集する必要が出てきます。一方、QtのSVGモジュールはDOMライクなデータ操作はできないとのこと。従って、SVGファイルを読み込む際に内部形式のデータに変換する必要があります。ま、そのために、わざわざQListで内部形式のデータとして保存する様にしたんですけどね。

さて、このデータの読み込みには、QSvgRendererQSvgWidgetがある様。QSvgWidgetはSVGファイルを読み込んで表示するのが機能。QSvgRendererはSVGファイルを読み込んで、QPaintDeviceに書き込むのが機能の様です。今回の目的(SVGファイルを読み込んで内部データ形式に変換する)には、QSvgRendererが適していますね。

このQSvgRendererQPainterを用いて、QPaintDeviceにデータを書き込む様なのですが、今回はSVG→内部形式のデータ変換用にQPainterの派生クラスを独自に作成しようと思っています。が、うまくいくのかな・・。一応、そのためには、ほとんどスタブになるでしょうが、QPainterに数多く用意されているメンバ関数を全て実装しておく必要があるのではと思っています・・。

・・・ちょっと、やってみないと分かりませんが、データは直接QList型に入れるのではなく、何か、内部データ形式用のクラスを作成してそこを介して、QList型に入れるのがいいかもしれませんね。

また、元画像のサイズと描こうとしているQPaintDeviceのサイズが異なる場合の動作がよくわかりませんね・・。自動的に拡大・縮小を行ってくれるのでしょうか・・? う~ん、とりあえず、実装してどのような動作をするのか見てみますか・・。


進展なしですが、つづく。






→<< 10affivc07020731 >> 7/31までのギフト券コードです。3000円以上で300円引き!

SVGファイルの作成 [Qt]

一応、QListの使い方がわかったので、それを使用して、内部にデータを保持する実装をしました。次は、ようやくSVGファイル生成の実装です。SVGモジュールを利用するためには下記の通り「#include <QtSvg>」を追加しておかなければいけないとのこと。

#include <QtSvg>


一通り実装してビルドしたのですが、エラーが出ますね。再度、よく読んでみると、ついでに、リンク時のために.proファイルに下記の設定が必要だとのことです。ファイルを直接編集しましたが、これはQtCreatorから設定できないんですかね・・?このファイルはqmake用のファイルらしいですが、これの書式と言うか、設定内容も見とく必要がありますね・・。そもそもこの設定が何か良くわかってなかったりします。使うモジュールの名前を列挙するんかな・・?

QT += svg


さて、これで該当箇所のコンパイルは通りましたが、まだなんか他のエラーが出てます。今回利用するのはQSvGeneratorなのですが、説明のページを見てみると、「#include <QSvgGenerator>」も必要な様です。

#include <QSvgGenerator>


はい。これでリンクまで通りました。

さて、以前書いた通り、QSvgGeneratorはpainterを用いてデータを設定し、painter.end()のタイミングでデータを保存する様なので、QSvgGeneratorを使用するデータ保存用の関数を作成し、そこで一気に内部に保持している筆跡をQSvgGeneratorに書き込むことにします。で、QSvgGeneratorの利用方法なんですが、ドキュメントに例示されている内容に沿って、下記の様に実装しました。

	// QSvgGenerator 準備(ファイル名設定(固定名))
	QSvgGenerator *svg_generator = new QSvgGenerator();
	svg_generator->setFileName(fileName);
	svg_generator->setSize(canvas->size());
	svg_generator->setViewBox(canvas->rect());
	svg_generator->setTitle(tr("Test Data"));
	svg_generator->setDescription(tr("This is a test data."));


上記で突然出ている変数についてですが、「fileName」はQStringでファイル名を設定しています。「canvas」はペンの軌跡を書きこむためのオフスクリーンに使っているQPixmapです。

setTitleの引数に使用している「tr()」は、例に書かれていたまま使ってみたんですが、このままでは定義されてないと怒られてしまいました。調べてみたところ、QObjectのメンバ関数だとのこと。上記の実装は独自にデータ保存用に作成したクラスのメンバ関数への実装となってるんですが、面倒なので、この独自クラスもQObjectを継承しました。この辺、どうするのが妥当かはおいおい調べることにします。

とりあえず、ウィンドウを閉じるタイミングで保存するようにして見ました。試しに書いたのがこれ。

10070600.png
芸がないですが・・


で、ウィンドウを閉じるとちゃんとSVGファイルが出来ていました。そのファイルをMacに持ってきて、Safariで表示してみたのがこれ。

10070601.png
アンチエイリアスがかかってる・・


おぉ〜!ちゃんと表示出来ましたっ! と、地味ながら感心してしまいました。かなりお手軽にポータブルなベクトルデータの作成ができたのがすごく嬉しかったりします。


次は、読み込みですね。






    

ブログを作る(無料) powered by So-netブログ

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。

×

この広告は1年以上新しい記事の更新がないブログに表示されております。