Qwtライブラリ:平面に関数グラフをプロットする方法は?

Qwtウィジェットの使用を示す簡単なプログラムのスクリーンショット
5年間、私はGUIでアプリケーションを作成していません。したがって、提供は 特定のスケジュールを作成するプログラムを彼の講義の準備をする部門は、最初は多少動揺しました。

本物のプログラマーとして、私は最も簡単な(そして自己開発に役立つ)パスを見つけることにしました。
つまり、このタスクは、QtとQwtライブラリに精通する良い機会であることが判明しました。 同時に、GUIを備えたアプリケーションはクロスプラットフォームであることがわかり、そのコードは「Unix™スタイルのインターフェイス」を備えたアプリケーションのコードよりもエレガントであることがわかりました。

そのため、 Qwtは、技術的な焦点を持つアプリケーションをプログラミングするためのウィジェットライブラリです。 これには、すべての種類のスライダーとディスクの「ダイアラー」であるウィジェットのセットが含まれ、ヒストグラムを作成するためのウィジェットです。 しかし、ここではQwtを使用してy = f(x)の形式の関数の最も一般的な2次元グラフを作成する方法を説明します。

このメモでさらに


最も単純な例とそのコンパイル


この記事では、Qwtの研究の出発点として使用できる非常に小さな例を用意しました。

ダウンロードリンク(308 KB)を使用すると、tgzアーカイブを取得できます。

これらのバイナリをソースから収集するには、次のコマンドを使用できます。

Linux:

Windows:

ソースディレクトリには、元の配信からのqwt.prfファイルがあることに注意してください。 ライブラリの静的バージョンを使用しているため、 QwtBuild変数は空の値にQwtBuildれます。 さらに、 win32セクションでは、 QwtBase変数の値が、ライブラリがインストールされているディレクトリへのパスに変更されます。

ソースを見てみましょう


Qwtは簡単です。 ウィジェット「描画領域」 QwtPlotます。 複数の曲線をそれに関連付けることができますQwtPlotCurveオブジェクト。 それだけです。

クラスの説明(QwtBeginner.hファイル)

私の例では、アプリケーションウィンドウは、 QWidgetクラスの子孫であるQwtBeginnerクラスのインスタンスです。

2つのQwtPlot描画QwtPlot含まれますfunPlotでは関数のグラフが表示され、 derPlotではその派生グラフが表示されます。

合計で、正弦関数と3次関数( sinFunCurvecubFunCurve )およびそれらの微分( sinDerCurvecubDerCurve )の4つの曲線が作成されます。

cubButtonボタンとcubButtonボタンは、対応するグラフの表示のオンとオフをsinToggled() 、その信号にsinToggled()およびcubToggled()スロットが接続されます。
class QwtBeginner : public QWidget<br>{<br> Q_OBJECT<br><br> public :<br> QwtBeginner(QWidget *parent = 0);<br><br> private :<br> QwtPlot *funPlot, *derPlot;<br> QwtPlotCurve *sinFunCurve, *sinDerCurve;<br> QwtPlotCurve *cubFunCurve, *cubDerCurve;<br> QPushButton *sinButton, *cubButton;<br><br> private slots:<br> void sinToggled( bool checked );<br> void cubToggled( bool checked );<br>};


クラスの実装(QwtBeginner.cppファイル)

クラスコンストラクター内
QwtBeginner::QwtBeginner(QWidget *parent)<br> : QWidget(parent)<br>{

描画領域が作成され、ヘッダーが設定されます:
// Create plots <br> funPlot = new QwtPlot;<br> derPlot = new QwtPlot;<br><br> funPlot->setTitle( "Function" );<br> derPlot->setTitle( "Derivative" );

曲線を描く「フェザー」を設定します。
// Create curves and attach them to plots <br> QPen sinPen = QPen(Qt::red);<br> QPen cubPen = QPen(Qt::blue);

曲線を作成し、滑らかにする必要があり( RenderAntialiased )、「フェザー」を指定し( setPen() )、曲線を対応する描画領域にバインドします( attach() )。
sinFunCurve = new QwtPlotCurve;<br> sinFunCurve->setRenderHint(QwtPlotItem::RenderAntialiased);<br> sinFunCurve->setPen(sinPen);<br> sinFunCurve->attach(funPlot);<br><br> sinDerCurve = new QwtPlotCurve;<br> sinDerCurve->setRenderHint(QwtPlotItem::RenderAntialiased);<br> sinDerCurve->setPen(sinPen);<br> sinDerCurve->attach(derPlot);<br><br> cubFunCurve = new QwtPlotCurve;<br> cubFunCurve->setRenderHint(QwtPlotItem::RenderAntialiased);<br> cubFunCurve->setPen(cubPen);<br> cubFunCurve->attach(funPlot);<br><br> cubDerCurve = new QwtPlotCurve;<br> cubDerCurve->setRenderHint(QwtPlotItem::RenderAntialiased);<br> cubDerCurve->setPen(cubPen);<br> cubDerCurve->attach(derPlot);

表示するデータ配列を入力します。
// Set data <br> const int N = 20;<br> double x[N+1];<br> double sinFunData[N+1], sinDerData[N+1];<br> double cubFunData[N+1], cubDerData[N+1];<br> for ( int i = 0; i <= N; ++i)<br> {<br> const double pi = 4.0 * atan(1.0);<br> double L = 2;<br> double h = L / N;<br><br> x[i] = -L/2 + i * h;<br> sinFunData[i] = sin(x[i] * pi);<br> sinDerData[i] = cos(x[i] * pi) * pi;<br> cubFunData[i] = x[i] * x[i] * x[i];<br> cubDerData[i] = 3 * x[i] * x[i];<br> }

このデータを曲線に接続します。
sinFunCurve->setData(x, sinFunData, N+1);<br> sinDerCurve->setData(x, sinDerData, N+1);<br> cubFunCurve->setData(x, cubFunData, N+1);<br> cubDerCurve->setData(x, cubDerData, N+1);

まず、曲線を非表示にします。
// Hide curves <br> sinFunCurve->setVisible( false );<br> sinDerCurve->setVisible( false );<br><br> cubFunCurve->setVisible( false );<br> cubDerCurve->setVisible( false );

ボタンを作成し、信号をスロットに関連付けます。
// Create buttons <br> sinButton = new QPushButton( "Sinus" ),<br> cubButton = new QPushButton( "Cubic function" ),<br><br> sinButton->setCheckable( true );<br> cubButton->setCheckable( true );<br><br> // Connect signals <br> connect(sinButton, SIGNAL(toggled( bool )), this , SLOT(sinToggled( bool )));<br> connect(cubButton, SIGNAL(toggled( bool )), this , SLOT(cubToggled( bool )));

フォームにウィジェットを配置し、ウィンドウを全画面で開きます。
// Set layouts <br> QHBoxLayout *plotsLayout = new QHBoxLayout;<br> plotsLayout->setSpacing(10);<br> plotsLayout->addWidget(funPlot);<br> plotsLayout->addWidget(derPlot);<br><br> QHBoxLayout *buttonsLayout = new QHBoxLayout ;<br> buttonsLayout->addWidget(sinButton);<br> buttonsLayout->addWidget(cubButton);<br><br> QVBoxLayout *widgetLayout = new QVBoxLayout;<br> widgetLayout->addLayout(plotsLayout);<br> widgetLayout->addLayout(buttonsLayout);<br><br> setLayout(widgetLayout);<br> showMaximized();<br>}

最後に、スロットの実装:
void QwtBeginner::sinToggled( bool checked )<br>{<br> sinFunCurve->setVisible( checked );<br> sinDerCurve->setVisible( checked );<br> funPlot->replot();<br> derPlot->replot();<br>} <br><br> void QwtBeginner::cubToggled( bool checked )<br>{<br> cubFunCurve->setVisible( checked );<br> cubDerCurve->setVisible( checked );<br> funPlot->replot();<br> derPlot->replot();<br>}

曲線の可視性を変更するだけでなく( setVisible() )、描画領域を再描画する必要があることに注意してください( replot() )。

Main()関数(main.cppファイル)

ここではすべてが伝統的です:
int main( int argc, char *argv[])<br>{<br> QApplication app(argc, argv);<br> QwtBeginner *wnd = new QwtBeginner;<br> wnd->show();<br> return app.exec();<br>} <br><br> * This source code was highlighted with Source Code Highlighter .


初心者向け:Qwtのコンパイルとインストール


tar.bz2およびzipアーカイブ 、公式Webサイトからダウンロードできます。 この記事の執筆時点では、最新バージョンは5.2.0です。

そのため、アーカイブをダウンロードして一時ディレクトリに解凍します。

qwtconfig.priファイルに次の変更が加えられました。

これで、アセンブリとインストールを続行できます。



Linux


おわりに


Qwtは、1つの変数の関数をプロットするための便利なクロスプラットフォームツールです。 シンプルなインターフェイスを提供し、スケーリングや軸上のラベルなどの詳細を管理する必要がなくなります。

examples/ initialサブディレクトリには別の15個のサンプルが含まれており、 examples/うちの1つがexamples/simple_plotであり、これが私のプログラムの基礎となっていることにも注意してください。

私は今のところQtの専門家ではないので、批判、コメント、追加に感謝します。

ご清聴ありがとうございました!

PS

同様のツール。

Source: https://habr.com/ru/post/J82614/


All Articles