📢 Webサイト閉鎖と移転のお知らせ
このWebサイトは2026年9月に閉鎖いたします。
新しい記事は移転先で追加しております。(旧サイトでは記事を追加しておりません)
| (同じ利用者による、間の8版が非表示) | |||
| 13行目: | 13行目: | ||
ダウンロードしたQwtを解凍するため、以下のコマンドを実行する。<br> | ダウンロードしたQwtを解凍するため、以下のコマンドを実行する。<br> | ||
tar xf qwt-x.x.x.tar.bz2 | tar xf qwt-x.x.x.tar.bz2 | ||
cd qwt-x.x.x | |||
<br> | |||
または、<code>git clone</code>を使用して、Qwtのソースコードをダウンロードする。<br> | |||
git clone https://git.code.sf.net/p/qwt/git -b qwt-x.x qwt | |||
cd qwt | |||
<br> | <br> | ||
解凍したQwtディレクトリに移動して、qwtconfig.priファイルを以下のように編集する。<br> | 解凍したQwtディレクトリに移動して、qwtconfig.priファイルを以下のように編集する。<br> | ||
| 41行目: | 46行目: | ||
} | } | ||
<br> | <br> | ||
ビルドディレクトリを作成する。<br> | |||
qmake qwt.pro | mkdir build && cd build | ||
make -j | <br> | ||
Qwtをビルドおよびインストールする。<br> | |||
qmake ../qwt.pro | |||
make -j $(nproc) | |||
make install | make install | ||
<br> | <br> | ||
| 62行目: | 70行目: | ||
Qwtを使用するため、Qtプロジェクトファイルに以下の設定を追記する。<br> | Qwtを使用するため、Qtプロジェクトファイルに以下の設定を追記する。<br> | ||
# QWT | # QWT | ||
QWT_LOCATION = / | QWT_LOCATION = /<Qtのインストールディレクトリ>/Qwt-x.x.x | ||
INCLUDEPATH += $${QWT_LOCATION}/include/ | INCLUDEPATH += $${QWT_LOCATION}/include/ | ||
LIBS += -L$${QWT_LOCATION}/lib -lqwt | LIBS += -L$${QWT_LOCATION}/lib -lqwt | ||
| 265行目: | 273行目: | ||
item->attach(m_pPlot); | item->attach(m_pPlot); | ||
</syntaxhighlight> | </syntaxhighlight> | ||
<br> | |||
[[ファイル:Qt Qwt Plot 1.jpg|フレームなし|中央]] | |||
<br><br> | <br><br> | ||
| 384行目: | 394行目: | ||
この時、大きい数値は指数型の文字列を返す。<br> | この時、大きい数値は指数型の文字列を返す。<br> | ||
指数型の文字列を表示させない場合も、上記のように、<code>QwtPlot</code>クラスを継承した派生クラスを作成する必要がある。<br> | 指数型の文字列を表示させない場合も、上記のように、<code>QwtPlot</code>クラスを継承した派生クラスを作成する必要がある。<br> | ||
<br> | |||
[[ファイル:Qt Qwt Plot 2.jpg|フレームなし|中央]] | |||
<br><br> | <br><br> | ||
| 433行目: | 445行目: | ||
m_pVMarker->setLabel(textVMarker); | m_pVMarker->setLabel(textVMarker); | ||
m_pVMarker->attach(m_pPlot); | m_pVMarker->attach(m_pPlot); | ||
} | |||
</syntaxhighlight> | |||
<br> | |||
[[ファイル:Qt Qwt Plot 3.jpg|フレームなし|中央]] | |||
<br><br> | |||
== ラバーバンドの描画 == | |||
プロット上に選択枠のような図形を描画する場合、<code>QwtPlotPicker</code>クラスを使用する。<br> | |||
<code>QwtPlotPicker</code>クラスは、ズーム枠の親クラスである。<br> | |||
<br> | |||
以下の例では、<code>QwtPlot</code>クラスを継承した派生クラスを作成して、<code>QwtPlotPicker</code>クラスを使用して設定している。<br> | |||
<syntaxhighlight lang="c++"> | |||
MyPlot::MyPlot(QWidget *parent) : QwtPlot(parent) | |||
{ | |||
// Picker | |||
m_pPicker = std::make_unique<QwtPlotPicker>(canvas()); | |||
m_pPicker->setRubberBandPen(QColor(Qt::darkRed)); | |||
m_pPicker->setTrackerMode(QwtPicker::ActiveOnly); | |||
} | |||
</syntaxhighlight> | |||
<br> | |||
マウスボタンの設定は、<code>QwtPickerMachine</code>クラスの派生クラスで管理している。<br> | |||
以下の例では、ズーム枠のような矩形を描画している。<br> | |||
<syntaxhighlight lang="c++"> | |||
m_pPicker->setRubberBand(QwtPicker::RectRubberBand); | |||
m_pPicker->setStateMachine(new QwtPickerDragRectMachine); | |||
</syntaxhighlight> | |||
<br> | |||
<code>QwtPickerDragRectMachine</code>クラスは、マウスの左ボタンを押下しながらドラッグすることにより矩形を描画して、<br> | |||
左ボタンを離すと描画を終了する設定である。<br> | |||
<br> | |||
以下の例では、楕円を描画している。<br> | |||
<syntaxhighlight lang="c++"> | |||
m_pPicker->setRubberBand(QwtPicker::EllipseRubberBand); | |||
m_pPicker->setStateMachine(new QwtPickerDragRectMachine); | |||
</syntaxhighlight> | |||
<br> | |||
以下の例では、ポリゴンを描画している。<br> | |||
<syntaxhighlight lang="c++"> | |||
m_pPicker->setRubberBand(QwtPicker::PolygonRubberBand); | |||
m_pPicker->setStateMachine(new QwtPickerPolygonMachine); | |||
</syntaxhighlight> | |||
<br> | |||
<code>setStateMachine</code>メソッドは、左ボタンで点を追加、右ボタンで終了する動作である。<br> | |||
しかし、左ボタンで最初の1点、右ボタンで2点目以降を追加、左ボタンで終了となっている。(2012/4 現在)<br> | |||
<br> | |||
この動作を、左ボタンで点を追加、右ボタンで終了に変更するため、qwt_picker_machin.cppファイルを変更する。<br> | |||
<syntaxhighlight lang="c++"> | |||
// qwt_picker_machin.cpp | |||
//! Transition | |||
QList<QwtPickerMachine::Command> QwtPickerPolygonMachine::transition(const QwtEventPattern &eventPattern, const QEvent *event) | |||
{ | |||
QList<QwtPickerMachine::Command> cmdList; | |||
switch(event->type()) | |||
{ | |||
case QEvent::MouseButtonPress: | |||
if(eventPattern.mouseMatch(QwtEventPattern::MouseSelect1, (const QMouseEvent *)event)) | |||
{ | |||
// if(state() == 0) | |||
// { | |||
cmdList += Begin; | |||
cmdList += Append; | |||
cmdList += Append; | |||
setState( 1 ); | |||
// } | |||
// else | |||
// { | |||
// cmdList += End; | |||
// setState(0); | |||
// } | |||
} | |||
if(eventPattern.mouseMatch(QwtEventPattern::MouseSelect2, (const QMouseEvent *)event)) | |||
{ | |||
if(state() == 1) | |||
{ | |||
// cmdList += Append; | |||
cmdList += End; | |||
} | |||
} | |||
break; | |||
} | |||
} | |||
</syntaxhighlight> | |||
<br> | |||
ラバーバンドで描画した図形を、確定図形としてプロット上に描画する場合、<br> | |||
ラバーバンド描画終了時の図形データを、ラバーバンドクラスから取得する必要がある。<br> | |||
<br> | |||
ここでは、ラバーバンド描画終了時のシグナルを受信して図形を取り出す手順を使用する。<br> | |||
<br> | |||
上記の例では、QwtPlotクラスを継承した派生クラスにラバーバンドクラスがあるため、<br> | |||
プロットアイテムを、プロットの親ウィンドウ側で管理する場合はシグナルをさらに親ウィンドウへ転送する必要がある。<br> | |||
<br> | |||
QMainWindowクラスのコンストラクタにおいて、以下のようにシグナル・スロットを記述する。<br> | |||
また、QwtPlotクラスを継承した派生クラスを持つ親ウィンドウにて、転送されるシグナルを受信する。<br> | |||
<br> | |||
シグナルの引数は、ラバーバンドの矩形または頂点となっているため、スロットで図形を追加するとよい。<br> | |||
楕円の場合は、矩形選択のスロットが戻るため、選択図形の楕円をスロット側で再作成する必要がある。<br> | |||
<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 MainWindow::appendPoly(const QRectF& rc) | |||
{ | |||
QVector<QPointF> tempPoly; | |||
QPointF pnt; | |||
if(/* 楕円選択の場合 */ ) | |||
{ | |||
double dAlpha = 0.0; | |||
while(dAlpha < 2 * M_PI) | |||
{ | |||
pnt.setX(cos(dAlpha) * rc.width() * 0.5 + rc.center().x()); | |||
pnt.setY(sin(dAlpha) * rc.height() * 0.5 + rc.center().y()); | |||
tempPoly.push_back(pnt); | |||
dAlpha += M_PI / 128; | |||
} | |||
} | |||
else /* 矩形選択の場合 */ | |||
{ | |||
tempPoly.push_back(rc.topLeft()); | |||
tempPoly.push_back(rc.bottomLeft()); | |||
tempPoly.push_back(rc.bottomRight()); | |||
tempPoly.push_back(rc.topRight()); | |||
tempPoly.push_back(rc.topLeft()); | |||
} | |||
// QwtPlotCurveクラスとして図形を追加 | |||
std::unique_ptr<QwtPlotCurve> pCurve = std::make_unique<QwtPlotCurve>(); | |||
pCurve->setSamples(tempPoly); | |||
pCurve->setPen(QPen(QBrush(QColor::fromRgb(255, 0, 0)), 2.0)); | |||
pCurve->attach(m_pPlot); | |||
} | |||
// ポリゴンの場合のスロット | |||
void MainWindow::appendPoly(const QVector<QPointF> &poly) | |||
{ | |||
// 点列の末尾に始点を追加してポリゴンを閉じる | |||
QVector<QPointF> tempPoly(poly); | |||
tempPoly.push_back(tempPoly.front()); | |||
// QwtPlotCurveクラスとして図形を追加 | |||
std::unique_ptr<QwtPlotCurve> pCurve = std::make_unique<QwtPlotCurve>(); | |||
pCurve->setSamples(tempPoly); | |||
pCurve->setPen(QPen(QBrush(QColor::fromRgb(255, 0, 0)), 2.0)); | |||
pCurve->attach(m_pPlot); | |||
} | } | ||
</syntaxhighlight> | </syntaxhighlight> | ||