上一篇文章 Qt由入门到放弃-QCustomPlot之QCPAxisTicker坐标轴类 介绍了QCustomPlot的坐标轴类的基本功能和用法,此篇文章在其基础上用实例制作一个简单的天气数据显示界面,基本的代码上篇文章已有,此篇文章的重点放在通过QToolTip控件类来实现天气曲线上的数据随鼠标移动显示的功能,先看一个简单效果图:
QCustomPlot里面已有mouseMove信号,在这里自定义一下接收槽函数myMoveEvent
connect(customPlot,SIGNAL(mouseMove(QMouseEvent *)),this,SLOT(myMoveEvent(QMouseEvent *)));
基本思路是首先通过鼠标移动事件获取鼠标所在的位置;然后转换鼠标位置获取到QCustomPlot空间的坐标系中对应的数据点,其中使用了pixelToCoord()函数---->把ui控件的坐标映射到QCustomPlot数据显示坐标;其次就是使用QToolTip来做数据显示,由于要保证QToolTip的文本框要随曲线移动,实际上需要得到鼠标移动时曲线上的点的坐标,line_y_val 就是对应的曲线y值;最后别忘了使用coordToPixel()函数把QCustomPlot的曲线坐标转成桌面坐标show出QToolTip。
void MainWindow::myMoveEvent(QMouseEvent *event)
{
//获取鼠标坐标,相对父窗体坐标
int x_pos = event->pos().x();
int y_pos = event->pos().y();
qDebug()<<"event->pos()"<pos();
//鼠标坐标转化为CustomPlot内部坐标
float x_val = customPlot->xAxis->pixelToCoord(x_pos);
float y_val = customPlot->yAxis->pixelToCoord(y_pos);
//获得x轴坐标位置对应的曲线上y的值
float line_y_val = customPlot->graph(0)->data()->at(x_val)->value;
//曲线的上点坐标位置,用来显示QToolTip提示框
float out_x = customPlot->xAxis->coordToPixel(x_val);
float out_y = customPlot->yAxis->coordToPixel(line_y_val);
QString str,strToolTip;
str = QString::number(x_val,10,3);
strToolTip += "x: ";
strToolTip += str;
strToolTip += "\n";
str = QString::number(line_y_val,10,3);
strToolTip += "y: ";
strToolTip += str;
strToolTip += "\n";
QToolTip::showText(mapToGlobal(QPoint(out_x,out_y)),strToolTip,customPlot);
}
效果看上去像那么回事,就是太。。。丑了,没办法,c++搞界面你懂得。不过好歹我们还是要继续美化一下,如把坐标轴换成QCPAxisTickerDateTime类,加上单位,控制显示。
在一的基础上我高兴的把x轴坐标换成QCPAxisTickerDateTime加上,初步判断可以实现实时显示特定时间的动态曲线,上代码:
void MainWindow::SlotToTem()
{
customPlot->setInteraction(QCP::iRangeDrag, true);
customPlot->setInteraction(QCP::iRangeZoom, true);
QDateTime dateTime = QDateTime::currentDateTime();
double now = dateTime.toTime_t();//当前时间转化为秒
//生成时间刻度对象
QSharedPointer dateTimeTicker(new QCPAxisTickerDateTime);
customPlot->xAxis->setTicker(dateTimeTicker);
//dateTimeTicker->setDateTimeSpec(Qt::UTC);//设施世界时间,即不加上时区的时间
dateTimeTicker->setTickCount(24);
dateTimeTicker->setTickStepStrategy(QCPAxisTicker::tssMeetTickCount);
customPlot->xAxis->setSubTicks(false);
customPlot->xAxis->setRange(now, now+3600*24);//x轴范围,从当前时间起往后推24小时
QVector yData, xData;//生成数据
for (int i = 0; i <= 24; i++)
{
xData.push_back(now + i * 3600.0);
}
yData = {
22,23,24,25,25.5,26,26.5,27,
27.5,28,28.5,29,30,31,32,33,
35,34,33,31,29,27,26,25,
};
dateTimeTicker->setDateTimeFormat("yyyy-M-d h:m");//设置x轴刻度显示格式
customPlot->xAxis->setTickLabelRotation(30);//设置刻度标签顺时针旋转30度
customPlot->yAxis->setRange(20,40);
customPlot->graph(0)->setData(xData, yData);//显示数据
customPlot->xAxis->setLabel("时间");
customPlot->yAxis->setLabel("温度/摄氏度");
customPlot->replot();
}
效果图:时间轴有了,数据却没了(都是自己生成的数据,没有获取在线实时数据)!仔细观察发现x轴显示的秒数,也就是说实际上坐标轴只是填充了24个数据,而QCPAxisTicker坐标轴折线图最小的辨识度为1个整数刻度,我的预期是在 QVector
void MainWindow::SlotToTem()
{
customPlot->setInteraction(QCP::iRangeDrag, true);
customPlot->setInteraction(QCP::iRangeZoom, true);
QDateTime dateTime = QDateTime::currentDateTime();
int now = dateTime.toTime_t();//当前时间转化为秒
qDebug()< dateTimeTicker(new QCPAxisTickerDateTime);
customPlot->xAxis->setTicker(dateTimeTicker);
dateTimeTicker->setTickCount(24);
dateTimeTicker->setTickStepStrategy(QCPAxisTicker::tssMeetTickCount);
customPlot->xAxis->setSubTicks(false);
customPlot->xAxis->setRange(now, now+3600*24);//x轴范围,从当前时间起往后推24小时
QVector xData,yData;
QVector xData1, yData1;//生成数据
for (int i = 0; i <= 24; i=i+1)
{
xData.push_back(now + i * 3600);
}
yData = {
22,23,24,25,25.5,26,26.5,27,
27.5,28,28.5,29,30,31,32,33,
35,34,33,31,29,27,26,25,24
};
for(int i=0;isetDateTimeFormat("yyyy-M-d h:m");//设置x轴刻度显示格式
customPlot->xAxis->setTickLabelRotation(30);//设置刻度标签顺时针旋转30度
customPlot->yAxis->setRange(20,40);
customPlot->graph(0)->addData(xData1, yData1);//显示数据
customPlot->xAxis->setLabel("时间");
customPlot->yAxis->setLabel("温度/摄氏度");
customPlot->replot();
}
效果图:我们看到还是没有数据显示,不知什么情况。。。。
由我的实验结果来看,对一般的连续数据(数据间隔一个整数单位),可以实现动态的数据显示,对于间隔天气数据本作者无法实现使用QCPAxisTickerDateTime。
相关代码点我下载,望读者看到此篇文章能给予一定的解答。