Qwt是用于绘制科学图形的Qt库。Qwt中的Picker是一个拾取器,通俗的说就是用户的鼠标指到哪里就获得哪里的信息(往往是x,y坐标)。QwtPicker类所获得的坐标信息是依赖于窗口的。而在Qwt中,用户所见的科学坐标系是绘制在Plot上的。Plot坐标不与窗口坐标相比,不但原点位置不同,而且方向也不一定相同(见图1)。但是Plot坐标与窗口坐标是有一定相对关系的,为此,Qwt提供了QwtPlotPicker来获取Plot坐标信息。
图1.Plot坐标与窗口坐标
QwtPicker以及QwtPlotPicker的继承、派生关系如图2所示。
图2.QwtPlotPicker的继承、派生关系
QwtPlotPicker能够获得Plot中的坐标并通过跟随于鼠标的Label显示出来,但是这个坐标是以原点为起点来显示的,例如:(100.1,50.9)这样的数字表示相对于原点的一个点。这在Plot的坐标的是数值型的时候还是比较给力的。但是Plot坐标可以为日期型的,例如:(2013-10-18 星期五 9:06:15:666),并且这个时间是CTU(Coordinated Universal Time)时间,也就是从1970年1月1日 8:00:00:000开始计时的,。这个时候,QwtPlotPicker所获得的坐标表示以CTU时间为起点的毫秒数,无疑这个数值是很大的。那能否让Picker与Plot的坐标一样,让紧跟鼠标的Label以日期格式显示出来呢?
这就要编写一个类来继承QwtPlot类。所幸的是Qwt是一个开源的项目,只要将QwtPlotPicker类复制出来改写为自己的类即可。新类命名为“PlotPickerByTime”,除了对应的类名要修改外,其余要修改的地方非常少。
主要修改的是PlotPickerByTime中的trackerTextF()方法,该方法用于获得紧跟鼠标的Label中所显示的文本(Text)。这是一个protected virtual方法,因此也可以派生QwtPlotPicker类,并重写该虚函数。新的trackerTextF()代码如下:
QwtText PlotPickerByTime::trackerTextF(constQPointF&pos)const
{
QString text;
QDateTime time = toDateTime(double(pos.x()));
switch ( rubberBand() )
{
case HLineRubberBand:
text.sprintf( "%.4f", pos.y() ); //此处笔者没有使用,没有修改,建议根据自己需求进行修改
break;
case VLineRubberBand:
text.sprintf( "%.4f", pos.x() ); //此处笔者没有使用,没有修改,建议根据自己需求进行修改
break;
default:
//text.sprintf( "%.4f, %.4f", pos.x(), pos.y() ); // 原代码
text.append(QString::number(pos.y(),'f',2)); // 新增代码
text.append('('+time.toString("yyyy-MM-dd HH:mm:ss:zzz")+')'); // 新增代码,将按照“年-月-日 时:分:秒:毫秒”的格式显示QDateTime默认不显示毫秒
}
return QwtText( text );
}
接着从Qwt中复制出
toDateTime()方法的代码并进行修改。
QDateTime PlotPickerByTime::toDateTime(doublevalue)const
{// 注意以下代码中对应部分修改成了Qt::LocalTime,使用时应根据自己需要进行修改
QDateTime dt = QwtDate::toDateTime( value, Qt::LocalTime );
if ( !dt.isValid() )
{
const QDate date = ( value <= 0.0 )
? QwtDate::minDate() : QwtDate::maxDate();
dt = QDateTime( date, QTime( 0, 0 ), Qt::LocalTime );
}// 注释掉以下原始代码,如果使用到Qt::OffsetFromUTC类型,则不可以简单注释,而需对下面代码进行修改
/*if ( d_data->timeSpec == Qt::OffsetFromUTC )
{
dt = dt.addSecs( d_data->utcOffset );
dt.setUtcOffset( d_data->utcOffset );
}*/
return dt;
}
这样最终显示的效果便如图3所示。
图3.PlotPickerByTime的效果
示例参见博文:http://blog.csdn.net/desert187/article/details/47780001