以前の章で、Qtであらかじめ用意されたダイアログをいくつか紹介した。
(メッセージボックス、ファイルダイアログ)
この章では,上のような2値化処理のためのダイアログを作成し、二値化処理を実装する。
サンプルの8という名前のフォルダの中に、以下の内容のファイルがある。
変更のないファイルは、リンクに追加しなかった。
新しくTo1bitクラスとそのダイアログを提供するクラスを追加した。
void To1bit::slotTo1bit(QImage* img, int border){ QRgb color; GrayScale gr; gr.toGrayScale(img); for(int y=0; y<img->height(); y++){ for(int x=0; x<img->width(); x++){ color = img->pixel(x,y); if(qRed(color) < border){ img->setPixel(x,y, qRgb(0,0,0)); }else{ img->setPixel(x,y, qRgb(255,255,255)); } } } }
前章で作成した関数で、グレースケールに変換して、 引数として得たしきい値から白か黒かを判断している。
レイアウトを上の図のように決めた。
To1bitDlg::To1bitDlg(QWidget* parent, const char* name, bool modal) :QDialog(parent, name, modal){ _slider = new QSlider(0,255,5,128,Horizontal,this,"dialog"); _edit = new QLineEdit("128", this, "dialog"); _bnOk = new QPushButton("OK", this, "dialog"); _bnCancel = new QPushButton("Cancel", this, "dialog"); setCaption("to 1bit"); resize(260,70); _slider->setGeometry(10,10,200,20); _edit->setGeometry(220,10,30,20); _bnOk->setGeometry(140,40,40,20); _bnCancel->setGeometry(190,40,60,20); connect(_slider, SIGNAL(valueChanged(int)), this, SLOT(setValue(int))); connect(_bnCancel, SIGNAL(clicked()), this, SLOT(reject()) ); connect(_bnOk, SIGNAL(clicked()), this, SLOT(accept()) ); }
まず、普段みられないbool modalという記述があるが、
これは、ダイアログが表示されている間、他のウィンドウ(メインウィンドウなど)
にアクセス出来るか出来ないかを指定できる。modalがtrueだとアクセス出来ない。
スライダーのシグナル、valueChangedを、ラインエディットに
整数値を表示させるために自作したスロット、setValueに接続した。
void To1bitDlg::setValue(int value){ QString str; _edit->setText(str.setNum(value,10)); }
スライダーを動かすと、それに併せてラインエディットの値も変更するようにする。
このためには、スライダーから得た整数値を文字列に変換しなければならない。
スライダーの値が変化すると、valueChanged(int)シグナルが発生し、
このsetValue(int)スロットにつなぐ事によって実現している。
QStringクラスのsetNumメソッドは、
setNum(整数値, 基数)
のように引数をとる。
int To1bitDlg::data(){ QString str = _edit->text(); return str.toInt(0,10); }
ラインエディットに入力された数値を得るための関数を作成した。
QStringクラスのtoInt関数を使って整数値に変換している。
toInt関数は、
toInt(bool エラーチェック, int 基数)
のように引数をとる。
エラーが見つかった場合、エラーチェックにFALSEがセットされる。
使用しない場合はnullを使う。
#include"to1bit.h" enum type_filter{ idGrayScale, idTo1bit };
private: 〜中略〜 To1bitDlg *_to1bitDlg; To1bit *_to1bit;
前回と同じく、新しく作成したヘッダファイルを読み込み、
idを割り当てた。
そして、privateであるメンバ変数に二値化処理のクラス変数を宣言した。
_filtermenu->insertItem("To 1bit",idTo1bit);
void MainWindow::callFilter(int id){ switch(id){ case idGrayScale: _grayscale->toGrayScale(_buffer); break; case idTo1bit: if(_to1bitDlg->exec() == _to1bitDlg->Accepted){ _to1bit->slotTo1bit(_buffer, _to1bitDlg->data()); } repaint(); break; } }
前回と同じく、割り当てたIDによって、どの処理を実行するか判断している。
ダイアログの関数exec()がAcceptedを返したら、
上の様なダイアログが表示され、結果が得られた。