QwtPolar 是Qt的一个第三方扩展控件,提供了极坐标下函数图形绘制的功能。我上一篇博客介绍了如何安装QwtPolar ,这次就写写如何使用QwtPolar 。
如果只是简单的用QwtPolar 显示个极坐标下的图形,只要会使用下面三个类就可以了。
QwtPolarPlot A plotting widget, displaying a polar coordinate system QwtPolarGrid An item which draws scales and grid lines on a polar plot QwtPolarCurve An item, that represents a series of pointsQwtPolarPlot 是绘图控件,最终的图形都绘制在它上面。下面是个最简单的代码:
#include <QApplication> #include <qwt_polar_plot.h> int main(int argc, char **argv) { QApplication app(argc, argv); QwtPolarPlot plot; plot.resize( 600, 600 ); plot.show(); return app.exec(); }
编译运行之后的效果如下。可以看到窗口中白色区域就是QwtPolarPlot 控件的绘制区域。
QwtPolarPlot 有一些基本的接口,比如setPlotBackground (const QBrush &c)、setTitle (const QString &)、setAutoScale (int scaleId)、setScale (int scaleId, double min, double max, double step=0)、insertLegend (QwtAbstractLegend *, LegendPosition=RightLegend, double ratio=-1.0) 等。
下面将上面的代码扩展一点。
#include <QApplication> #include <QTextCodec> #include <qwt_polar_plot.h> int main(int argc, char **argv) { QApplication app(argc, argv); QwtPolarPlot plot; QTextCodec::setCodecForTr(QTextCodec::codecForName("UTF-8")); plot.setTitle(QObject::tr("这是一个简单的例子")); plot.setPlotBackground (QBrush( Qt::red, Qt::SolidPattern )); plot.setScale( QwtPolar::ScaleAzimuth, 0, 360, 30); plot.setScale( QwtPolar::ScaleRadius, 0, 10, 5); plot.resize( 600, 600 ); plot.show(); return app.exec(); }
显示结果如下:
其中有两行代码的效果是看不到的:
plot.setScale( QwtPolar::ScaleAzimuth, 0, 360, 30); plot.setScale( QwtPolar::ScaleRadius, 0, 10, 5);
如果我们在极坐标区域添加了网格,就能看出上面代码的作用了。
QwtPolar将网格相关的功能收归到QwtPolarGrid 类。
下面是扩展后的代码,增加了网格。
#include <QApplication> #include <QTextCodec> #include <qwt_polar_plot.h> #include <qwt_polar_grid.h> int main(int argc, char **argv) { QApplication app(argc, argv); QwtPolarPlot plot; QTextCodec::setCodecForTr(QTextCodec::codecForName("UTF-8")); plot.setTitle(QObject::tr("这是一个简单的例子")); plot.setPlotBackground (QBrush( Qt::red, Qt::SolidPattern )); plot.setScale( QwtPolar::ScaleAzimuth, 0, 360, 30); plot.setScale( QwtPolar::ScaleRadius, 0, 10, 5); QwtPolarGrid grid; grid.setFont (QFont("Times", 16, QFont::Bold)); grid.setPen ( QPen(Qt::blue, 1, Qt::DashDotLine) ); grid.setAxisPen ( QwtPolar::AxisAzimuth, QPen(Qt::black, 1) ); //grid.setAxisPen ( QwtPolar::AxisLeft, QPen(Qt::black, 1) ); grid.showGrid (QwtPolar::AxisAzimuth, true); grid.showGrid (QwtPolar::AxisLeft, true); grid.showGrid (QwtPolar::AxisRight, false); grid.showGrid (QwtPolar::AxisTop, false); grid.showGrid (QwtPolar::AxisBottom, false); grid.attach(&plot); plot.resize( 600, 600 ); plot.show(); return app.exec(); }
最后是最重要的,绘制具体的函数图形了。QwtPolarCurve 用来绘制曲线图,QwtPolarSpectrogram 用来绘制颜色映射的三位等高图。这里只简单的介绍QwtPolarCurve ,QwtPolarSpectrogram 的用法类似。
QwtPolarCurve 有个成员函数setData (QwtSeriesData< QwtPointPolar > *data),用它就可以将待绘图的数据传进来。传进来的data 是个QwtSeriesData< QwtPointPolar >型的指针。
QwtSeriesData< QwtPointPolar >类是个纯虚类,它只提供了接口,却没有具体实现这些接口。
因此我们需要将数据封装成QwtSeriesData< QwtPointPolar > 型的派生类,在派生类中将接口函数具体实现。
我们在这里画一个简单的心形线。心形线的参数方程最初由 de Castillon 在1741年的《Philosophical Transactions of the Royal Society》发表的;意为“像心脏的”。 极坐标系下的参数方程可以写为:r=a(1-cosθ),我们这里设定 a= 2.
查看QwtSeriesData< QwtPointPolar >的定义可知,QwtSeriesData< QwtPointPolar >中有三个纯虚函数需要我们来实现。
virtual size_t size () const =0 virtual QwtPointPolar sample (size_t i) const =0 virtual QRectF boundingRect () const =0
这里我定义了一个新的类MyData,代码如下:
class MyData: public QwtSeriesData< QwtPointPolar > { virtual size_t size() const { return 360; } virtual QwtPointPolar sample(size_t i) const { double theta; double r; theta = i / 180.0 * M_PI; r = 2.0 * (1 - cos(theta)); return QwtPointPolar(i, r); } virtual QRectF boundingRect() const { //return qwtBoundingRect(); return QRectF(-2.0, -2.0, 4, 4); } };
有了这个代码后就可以实现全部的程序了。最后完整的代码如下:
#include <QApplication> #include <QTextCodec> #include <qwt_polar_plot.h> #include <qwt_polar_grid.h> #include <qwt_polar_curve.h> #include <qwt_series_data.h> class MyData: public QwtSeriesData< QwtPointPolar > { virtual size_t size() const { return 360; } virtual QwtPointPolar sample(size_t i) const { double theta; double r; theta = i / 180.0 * M_PI; r = 2.0 * (1 - cos(theta)); return QwtPointPolar(i, r); } virtual QRectF boundingRect() const { //return qwtBoundingRect(); return QRectF(-2.0, -2.0, 4, 4); } }; int main(int argc, char **argv) { QApplication app(argc, argv); QwtPolarPlot plot; QTextCodec::setCodecForTr(QTextCodec::codecForName("UTF-8")); plot.setTitle(QObject::tr("这是一个简单的例子")); plot.setPlotBackground (QBrush( Qt::red, Qt::SolidPattern )); plot.setScale( QwtPolar::ScaleAzimuth, 0, 360, 30); plot.setScale( QwtPolar::ScaleRadius, 0, 4, 2); QwtPolarGrid grid; grid.setFont (QFont("Times", 12, QFont::Bold)); grid.setPen ( QPen(Qt::blue, 1, Qt::DashDotLine) ); //grid.setAxisFont (QwtPolar::AxisLeft, QFont("Times", 6)); grid.setAxisPen ( QwtPolar::AxisAzimuth, QPen(Qt::black, 1) ); //grid.setAxisPen ( QwtPolar::AxisLeft, QPen(Qt::black, 1) ); grid.showMinorGrid (QwtPolar::AxisLeft, false); grid.showMinorGrid (QwtPolar::AxisRight, false); grid.showMinorGrid (QwtPolar::AxisTop, false); grid.showMinorGrid (QwtPolar::AxisBottom, false); grid.showGrid (QwtPolar::AxisAzimuth, true); grid.showGrid (QwtPolar::AxisLeft, true); grid.showGrid (QwtPolar::AxisRight, false); grid.showGrid (QwtPolar::AxisTop, false); grid.showGrid (QwtPolar::AxisBottom, false); grid.attach(&plot); QwtPolarCurve curve; curve.setPen (QPen(Qt::green, 3)); MyData data; curve.setData (&data); curve.attach(&plot); plot.resize( 600, 600 ); plot.show(); return app.exec(); }
至此,QwtPolar 基本的用法就介绍完了。希望对大家有用。