在学习中经常到CSND来搜索相关的知识学习,一直也有着想写自己第一篇关于自己编程的博客。今天留着上班时间偷空写了属于自己的博客。关于这段实习时间花费了不少时间学习的Qwt库调用,在VS2010下实现了这一程序。
配置为vs2010+Qt4.0+Qwt4.8.6
QwtPlot中包含有很多组件,是用来绘制二维图像的widget。在它的画板上可以无限制的显示绘画组件。绘画组件可以是曲线(QwtPlotCurve)、标记(QwtPlotMarker)、网格(QwtPlotGrid)、或者其它从QwtPlotItem继承的组件。
BarChart实现在qwt库中的例子example里也有事例可以参考实现,相对只要读懂其中widget机制,在窗口绘制组件时就相对比较简单,基本就是调用库里的函数,或者稍微重载库了的函数进行调用。
完整代码可以点击这里下载或者联系本人
运行图片:
首先我们实现可以从文本读取数据在窗口的canvas上形成条形图:
using namespace std;
class DistroChartItem;
class QMouseEvent;
class QwtPlotMarker;
class Data{
public:
string m_name;
double m_d;
Data(string name,double d){m_name=name;m_d=d;}
};
class BarChart: public QwtPlot
{
Q_OBJECT
signals:
double setMaxYValue(double m_max);
double setMinYValue(double m_min);
public:
BarChart(QWidget *parent = NULL);
vectorm_data;
virtual bool eventFilter( QObject *, QEvent * );
public slots:
void setOrientation(int value);
void setColor(int num);
void exportChart();
// mouseEvent
void mouseMoveEvent ( QMouseEvent * event );
void mousePressEvent ( QMouseEvent * event );
void mouseReleaseEvent ( QMouseEvent * event );
void marker(QwtPlotMarker *mX,double yvalue);
void setCanvasColor( const QColor &c );
void setMarkerColor(const QColor &d);
void maxChanged(double m_max);
void minChanged(double m_min);
public:
double setMaxMarker(){return MaxMarker->value().y();}
double setMinMarker(){return MinMarker->value().y();}
private:
DistroChartItem *d_barChartItem;
QStringList d_distros;
QwtPlotCanvas *canvas;
QwtPlotMarker *MaxMarker; //marker
QwtPlotMarker *MinMarker;
double yvalue;
bool m_pressedMax;
bool m_pressedMin;
ColorBar *d_colorBar;
};
在barchart的构造函数中去创建画布和读取数据转变成条形图显示在画布上
BarChart::BarChart(QWidget *parent):
QwtPlot(parent)
{
m_pressedMax = false;
m_pressedMin = false;
fstream ifile;
ifile.open("D:/2013/qwt/qwt6.1/test5/text.txt");
while(1){
string name;
double d;
ifile>>name>>d;
Data temp(name,d);
if(ifile.eof()!=0)break;
m_data.push_back(temp);
}
setAutoFillBackground(true);
setPalette(QColor("Linen"));
setTitle("排行榜");
//canvas Attributes
canvas = new QwtPlotCanvas();
canvas->setLineWidth(2);
canvas->setFrameStyle(QFrame::Box | QFrame::Sunken);
canvas->setBorderRadius(10);
QPalette canvasPalette(QColor(255,0,0,0.1));
canvas->setPalette(canvasPalette);
setCanvas(canvas);
d_barChartItem = new DistroChartItem();
QVectorsamples;
for (int i = 0; i < m_data.size(); i++)
{
d_distros += QString::fromStdString(m_data[i].m_name);
samples += m_data[i].m_d;
d_barChartItem->addDistro(QString::fromStdString(m_data[i].m_name));
}
d_barChartItem->setSamples(samples);
d_barChartItem->attach(this);
insertLegend(new QwtLegend());
setOrientation(0);
setAutoReplot(false);
MaxMarker=new QwtPlotMarker; //创建marker线和初始化
MaxMarker->setLabel(QString::fromLatin1("max"));
MaxMarker->setLinePen(QPen(Qt::black, 3, Qt::SolidLine));
marker(MaxMarker,500);
MinMarker=new QwtPlotMarker;
MinMarker->setLabel(QString::fromLatin1("min"));
MinMarker->setLinePen(QPen(Qt::black, 3, Qt::SolidLine));
marker(MinMarker,300);
QwtScaleWidget *scaleWidget = axisWidget( QwtPlot::yLeft); //彩色条
scaleWidget->setMargin( 10 );
d_colorBar=new ColorBar(Qt::Vertical,scaleWidget);
d_colorBar->setRange( Qt::white, Qt::darkBlue );
d_colorBar->setFocusPolicy( Qt::TabFocus );
scaleWidget->installEventFilter( this ); // we need the resize events, to lay out the color bar
}
还是调用qwt其值库中的QwtPlotmarker去绘制参考线,并重载鼠标事件可以让参考线在y轴上平移,并在doublespinbox上显示。
void BarChart::marker(QwtPlotMarker *mX,double yvalue){
mX->setLabelOrientation(Qt::Horizontal);
mX->setLineStyle(QwtPlotMarker::HLine);
mX->setYValue(yvalue);
mX->attach(this);
}
void BarChart::mousePressEvent ( QMouseEvent * event ) //鼠标点击移动事件
{
QPoint point=this->canvas->mapFromGlobal(QCursor::pos());
double d_max=transform(QwtPlot::yLeft,MaxMarker->value().y());
double pairMax=qAbs(point.y()-d_max);
double d_min=transform(QwtPlot::yLeft,MinMarker->value().y());
double pairMin=qAbs(point.y()-d_min);
if(pairMaxaxisScaleDiv(QwtPlot::yLeft).interval();
double ymin=m_scale.minValue();
double ymax=m_scale.maxValue();
double moveY;
if(m_pressedMax==true&&(event->buttons() & Qt::LeftButton)){
//QPoint pos=event->pos();
QPoint point=this->canvas->mapFromGlobal(QCursor::pos());
moveY=invTransform(QwtPlot::yLeft,point.y());
//double moveY = invTransform(MaxMarker->yAxis(), pos.y());
if(moveY>MinMarker->value().y()&&moveYbuttons() & Qt::LeftButton)){
QPoint point=this->canvas->mapFromGlobal(QCursor::pos());
moveY=invTransform(QwtPlot::yLeft,point.y());
if(moveYvalue().y()&&moveY>ymin){
marker(MinMarker,moveY);
replot();
emit setMinYValue(moveY);
}
}
}
void BarChart::mouseReleaseEvent ( QMouseEvent * event )
{
if (event->button() == Qt::LeftButton && (m_pressedMax||m_pressedMin)) {
m_pressedMax = false;
m_pressedMin = false;
}
}
画布和marker的心信号槽,可以转变窗口上的彩色条是对于着哪一个的,以便可以调节颜色。
void BarChart::setColor(int num){ //画布和marker线的信号槽连接
if(num==0){
disconnect(d_colorBar,0,0,0);
connect( d_colorBar, SIGNAL( selected( const QColor & ) ),
SLOT( setCanvasColor( const QColor & ) ) );
}
else {
disconnect(d_colorBar,0,0,0);
connect( d_colorBar, SIGNAL( selected( const QColor & ) ),
SLOT( setMarkerColor( const QColor & ) ) );
}
}
void BarChart::maxChanged(double m_max){
if(m_max>MinMarker->value().y()){
marker(MaxMarker,m_max);
replot();
}
}
void BarChart::minChanged(double m_min){
if(m_minvalue().y()){
marker(MinMarker,m_min);
replot();
}
}
main文件就在mainwindow是中设置一些组件菜单
#include "test5.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
class MainWindow: public QMainWindow
{
public:
MainWindow(QWidget *parent = NULL);
private:
BarChart *d_chart;
};
MainWindow::MainWindow(QWidget *parent):
QMainWindow(parent)
{
d_chart = new BarChart(this);
setCentralWidget(d_chart);
QToolBar *toolBar = new QToolBar(this);
QComboBox *orientationBox = new QComboBox(toolBar); //窗体的菜单栏的小组件
orientationBox->addItem("Vertical");
orientationBox->addItem("Horizontal");
orientationBox->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
QComboBox *m_color=new QComboBox(toolBar);
m_color->addItem("canvas_color");
m_color->addItem("marker_color");
m_color->setSizePolicy(QSizePolicy::Fixed,QSizePolicy::Fixed);
QToolButton *btnExport = new QToolButton(toolBar); //文件一键输出
btnExport->setText("Export");
btnExport->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
connect(btnExport, SIGNAL(clicked()), d_chart, SLOT(exportChart()));
toolBar->addWidget(orientationBox);
toolBar->addWidget(m_color);
toolBar->addWidget(btnExport);
addToolBar(toolBar);
d_chart->setOrientation(orientationBox->currentIndex());
connect(orientationBox, SIGNAL(currentIndexChanged(int)), d_chart, SLOT(setOrientation(int)));
d_chart->setColor(m_color->currentIndex());
connect(m_color,SIGNAL(currentIndexChanged(int)),d_chart,SLOT(setColor(int)));
QDoubleSpinBox *MaxSpinbox=new QDoubleSpinBox;
QwtInterval m_scale=d_chart->axisScaleDiv(QwtPlot::yLeft).interval();
MaxSpinbox->setRange(m_scale.minValue(),m_scale.maxValue());
MaxSpinbox->setValue(d_chart->setMaxMarker());
MaxSpinbox->setPrefix("max:");
toolBar->addWidget(MaxSpinbox);
connect(d_chart,SIGNAL(setMaxYValue(double)),MaxSpinbox,SLOT(setValue(double)));
connect(MaxSpinbox,SIGNAL(valueChanged(double)),d_chart,SLOT(maxChanged(double)));
QDoubleSpinBox *MinSpinbox=new QDoubleSpinBox;
MinSpinbox->setRange(m_scale.minValue(),m_scale.maxValue());
MinSpinbox->setValue(d_chart->setMinMarker());
MinSpinbox->setPrefix("min:");
toolBar->addWidget(MinSpinbox);
connect(d_chart,SIGNAL(setMinYValue(double)),MinSpinbox,SLOT(setValue(double)));
connect(MinSpinbox,SIGNAL(valueChanged(double)),d_chart,SLOT(minChanged(double)));
}
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QTextCodec::setCodecForCStrings(QTextCodec::codecForLocale());
QTextCodec::setCodecForTr(QTextCodec::codecForName("utf-8"));
MainWindow mainWindow;
mainWindow.resize(600, 500);
mainWindow.show();
return a.exec();
}
渣渣的程序员,真是一如IT深似海,从此秃顶便可期。来京实习的一个月,果真当个程序员也是不容易,写的第一篇博客,也是想记录记录自己的一些小收获吧,希望自己能够经常更新写下去,忘记一些东西时也可以回来看看。有什么不足也希望大家可以多多指出,写得比较粗糙。
看了一下一去二三里博客