13,007
回編集
437行目: | 437行目: | ||
<br><br> | <br><br> | ||
== | == ラバーバンドの描画 == | ||
プロット上に選択枠のような図形を描画する場合、<code>QwtPlotPicker</code>クラスを使用する。<br> | |||
<code>QwtPlotPicker</code>クラスは、ズーム枠の親クラスである。<br> | |||
<br> | |||
以下の例では、<code>QwtPlot</code>クラスを継承した派生クラスを作成して、<code>QwtPlotPicker</code>クラスを使用して設定している。<br> | |||
<syntaxhighlight lang="c++"> | <syntaxhighlight lang="c++"> | ||
MyPlot::MyPlot(QWidget *parent) : QwtPlot(parent) | MyPlot::MyPlot(QWidget *parent) : QwtPlot(parent) | ||
{ | { | ||
// Picker | // Picker | ||
m_pPicker = | m_pPicker = std::make_unique<QwtPlotPicker>(canvas()); | ||
m_pPicker->setRubberBandPen( QColor( Qt::darkRed ) ); | m_pPicker->setRubberBandPen(QColor(Qt::darkRed)); | ||
m_pPicker->setTrackerMode( QwtPicker::ActiveOnly ); | m_pPicker->setTrackerMode(QwtPicker::ActiveOnly); | ||
} | } | ||
</syntaxhighlight> | </syntaxhighlight> | ||
<br> | <br> | ||
マウスボタンの設定は、<code>QwtPickerMachine</code>クラスの派生クラスで管理している。<br> | |||
以下の例では、ズーム枠のような矩形を描画している。 | 以下の例では、ズーム枠のような矩形を描画している。<br> | ||
<syntaxhighlight lang="c++"> | <syntaxhighlight lang="c++"> | ||
m_pPicker->setRubberBand( QwtPicker::RectRubberBand ); | m_pPicker->setRubberBand(QwtPicker::RectRubberBand); | ||
m_pPicker->setStateMachine( new QwtPickerDragRectMachine ); | m_pPicker->setStateMachine(new QwtPickerDragRectMachine); | ||
</syntaxhighlight> | </syntaxhighlight> | ||
<br> | <br> | ||
<code>QwtPickerDragRectMachine</code>クラスは、マウスの左ボタンを押下しながらドラッグすることにより矩形を描画して、<br> | |||
左ボタンを離すと描画を終了する設定である。 | 左ボタンを離すと描画を終了する設定である。<br> | ||
<br> | |||
以下の例では、楕円を描画している。 | 以下の例では、楕円を描画している。<br> | ||
<syntaxhighlight lang="c++"> | <syntaxhighlight lang="c++"> | ||
m_pPicker->setRubberBand( QwtPicker::EllipseRubberBand ); | m_pPicker->setRubberBand(QwtPicker::EllipseRubberBand); | ||
m_pPicker->setStateMachine( new QwtPickerDragRectMachine ); | m_pPicker->setStateMachine(new QwtPickerDragRectMachine); | ||
</syntaxhighlight> | </syntaxhighlight> | ||
<br> | <br> | ||
以下の例では、ポリゴンを描画している。 | 以下の例では、ポリゴンを描画している。<br> | ||
<syntaxhighlight lang="c++"> | <syntaxhighlight lang="c++"> | ||
m_pPicker->setRubberBand( QwtPicker::PolygonRubberBand ); | m_pPicker->setRubberBand(QwtPicker::PolygonRubberBand); | ||
m_pPicker->setStateMachine( new QwtPickerPolygonMachine ); | m_pPicker->setStateMachine(new QwtPickerPolygonMachine); | ||
</syntaxhighlight> | </syntaxhighlight> | ||
<br> | <br> | ||
<code>setStateMachine</code>メソッドは、左ボタンで点を追加、右ボタンで終了する動作である。<br> | |||
しかし、左ボタンで最初の1点、右ボタンで2点目以降を追加、左ボタンで終了となっている。(2012/4 現在)<br> | |||
<br> | |||
この動作を、左ボタンで点を追加、右ボタンで終了に変更するため、qwt_picker_machin.cppファイルを変更する。<br> | |||
<syntaxhighlight lang="c++"> | <syntaxhighlight lang="c++"> | ||
// qwt_picker_machin.cpp | |||
//! Transition | //! Transition | ||
QList<QwtPickerMachine::Command> QwtPickerPolygonMachine::transition(const QwtEventPattern &eventPattern, const QEvent *event) | QList<QwtPickerMachine::Command> QwtPickerPolygonMachine::transition(const QwtEventPattern &eventPattern, const QEvent *event) | ||
516行目: | 518行目: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
<br> | <br> | ||
ラバーバンドで描画した図形を、確定図形としてプロット上に描画する場合、 | ラバーバンドで描画した図形を、確定図形としてプロット上に描画する場合、<br> | ||
ラバーバンド描画終了時の図形データを、ラバーバンドクラスから取得する必要がある。<br> | |||
<br> | |||
ここでは、ラバーバンド描画終了時のシグナルを受信して図形を取り出す手順を使用する。 | ここでは、ラバーバンド描画終了時のシグナルを受信して図形を取り出す手順を使用する。<br> | ||
<br> | |||
上記の例では、QwtPlotクラスを継承した派生クラスにラバーバンドクラスがあるため、<br> | |||
プロットアイテムを、プロットの親ウィンドウ側で管理する場合はシグナルをさらに親ウィンドウへ転送する必要がある。<br> | |||
<br> | |||
QMainWindowクラスのコンストラクタにおいて、以下のようにシグナル・スロットを記述する。<br> | |||
また、QwtPlotクラスを継承した派生クラスを持つ親ウィンドウにて、転送されるシグナルを受信する。<br> | |||
<br> | |||
シグナルの引数は、ラバーバンドの矩形または頂点となっているため、スロットで図形を追加するとよい。<br> | |||
楕円の場合は、矩形選択のスロットが戻るため、選択図形の楕円をスロット側で再作成する必要がある。<br> | |||
<syntaxhighlight lang="c++"> | <syntaxhighlight lang="c++"> | ||
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) | |||
{ | |||
// ...略 | |||
// ポリゴン選択の場合 | // 矩形、楕円選択の場合 | ||
QObject::connect(m_pPicker, SIGNAL(selected(const QRectF&)), this, SIGNAL(selected(const QRectF&))); | |||
// 矩形、楕円選択の場合 | |||
QObject::connect(m_pPlot, SIGNAL(selected(const QRectF&)), this, SLOT(appendPoly(const QRectF&))); | |||
// ポリゴン選択の場合 | |||
QObject::connect(m_pPicker, SIGNAL(selected(const QVector<QPointF>&)), this, SIGNAL(selected(const QVector<QPointF>&))); | |||
// ポリゴン選択の場合 | |||
QObject::connect(m_pPlot, SIGNAL(selected(const QVector<QPointF>&)), this, SLOT(appendPoly(const QVector<QPointF>&))); | |||
// ...略 | |||
} | |||
// 矩形の場合のスロット | // 矩形の場合のスロット | ||
void | void MainWindow::appendPoly(const QRectF& rc) | ||
{ | { | ||
QVector<QPointF> tempPoly; | QVector<QPointF> tempPoly; | ||
563行目: | 571行目: | ||
else /* 矩形選択の場合 */ | else /* 矩形選択の場合 */ | ||
{ | { | ||
tempPoly.push_back( rc.topLeft() ); | tempPoly.push_back(rc.topLeft()); | ||
tempPoly.push_back( rc.bottomLeft() ); | tempPoly.push_back(rc.bottomLeft()); | ||
tempPoly.push_back( rc.bottomRight() ); | tempPoly.push_back(rc.bottomRight()); | ||
tempPoly.push_back( rc.topRight() ); | tempPoly.push_back(rc.topRight()); | ||
tempPoly.push_back( rc.topLeft() ); | tempPoly.push_back(rc.topLeft()); | ||
} | } | ||
// | // QwtPlotCurveクラスとして図形を追加 | ||
QwtPlotCurve | std::unique_ptr<QwtPlotCurve> pCurve = std::make_unique<QwtPlotCurve>(); | ||
pCurve->setSamples(tempPoly); | pCurve->setSamples(tempPoly); | ||
pCurve->setPen(QPen(QBrush(QColor::fromRgb(255, 0, 0)), 2.0)); | pCurve->setPen(QPen(QBrush(QColor::fromRgb(255, 0, 0)), 2.0)); | ||
578行目: | 586行目: | ||
// ポリゴンの場合のスロット | // ポリゴンの場合のスロット | ||
void | void MainWindow::appendPoly(const QVector<QPointF> &poly) | ||
{ | { | ||
// 点列の末尾に始点を追加してポリゴンを閉じる | // 点列の末尾に始点を追加してポリゴンを閉じる | ||
584行目: | 592行目: | ||
tempPoly.push_back(tempPoly.front()); | tempPoly.push_back(tempPoly.front()); | ||
// | // QwtPlotCurveクラスとして図形を追加 | ||
QwtPlotCurve | std::unique_ptr<QwtPlotCurve> pCurve = std::make_unique<QwtPlotCurve>(); | ||
pCurve->setSamples(tempPoly); | pCurve->setSamples(tempPoly); | ||
pCurve->setPen(QPen(QBrush(QColor::fromRgb(255, 0, 0)), 2.0)); | pCurve->setPen(QPen(QBrush(QColor::fromRgb(255, 0, 0)), 2.0)); |