在最近接到的需求是这样的,画一个折线图,关键点使用空心的圆点标识出来,鼠标移动到关键点上,显示出当前数值;鼠标移走数值消失。

我们遇到这个需求的时候,第一时间就会想到使用 QLineSeries 画折线图。首先初始化

  1.  
    QChart *chart = new QChart();
  2.  
    chart->legend()->setVisible(false);
  3.  
    ui->chartView->setChart(chart);
  4.  
    ui->chartView->setRenderHint(QPainter::Antialiasing);
  5.  
     
  6.  
    chart->setBackgroundBrush(QBrush(QColor(248, 251, 255)));

将每个点添加到QLineSeries序列中。然后就会形成折线图。如下:

  1.  
    QChart *chart = ui->chartView->chart();
  2.  
    chart->removeAllSeries();
  3.  
    chart->removeAxis(chart->axisX());
  4.  
    chart->removeAxis(chart->axisY());
  5.  
     
  6.  
    //折线图
  7.  
    QLineSeries *series0 = new QLineSeries();
  8.  
     
  9.  
    QPen pen;
  10.  
    pen.setStyle(Qt::SolidLine);
  11.  
    pen.setWidth(4);
  12.  
    pen.setColor(QColor(21, 100, 255));
  13.  
    series0->setPen(pen);//折现序列的线条设置
  1.  
    QLineSeries *series0 = (QLineSeries *)ui->chartView->chart()->series().at(0);
  2.  
     
  3.  
    series0->clear();
  4.  
     
  5.  
    qsrand(QTime::currentTime().second());
  6.  
     
  7.  
    qreal t=0, y1, intv=1;
  8.  
    qreal rd;
  9.  
    int cnt=16;
  10.  
    for (int i=0; i<cnt; i++)
  11.  
    {
  12.  
    rd = (qrand() % 100);
  13.  
    y1=rd;
  14.  
    series0->append(t, y1);
  15.  
    t+=intv;
  16.  
    }

这是完成了第一步,画出来了折线图。但是对于那些圆点要显示出来的话我们可以考虑使用QScatterSeries来画一些离散的点。

  1.  
    QScatterSeries *series1 = new QScatterSeries();
  2.  
    series1->setMarkerShape(QScatterSeries::MarkerShapeCircle);//圆形的点
  3.  
    series1->setBorderColor(QColor(21, 100, 255)); //离散点边框颜色
  4.  
    series1->setBrush(QBrush(QColor(21, 100, 255)));//离散点背景色
  5.  
    series1->setMarkerSize(12); //离散点大小
  1.  
    QLineSeries *series0 = (QLineSeries *)ui->chartView->chart()->series().at(0);
  2.  
    QScatterSeries *series1 = (QScatterSeries *)ui->chartView->chart()->series().at(1);
  3.  
     
  4.  
    series0->clear();
  5.  
    series1->clear();
  6.  
     
  7.  
    qsrand(QTime::currentTime().second());
  8.  
     
  9.  
    qreal t=0, y1, intv=1;
  10.  
    qreal rd;
  11.  
    int cnt=16;
  12.  
    for (int i=0; i<cnt; i++)
  13.  
    {
  14.  
    rd = (qrand() % 100);
  15.  
    y1=rd;
  16.  
    series0->append(t, y1);
  17.  
    series1->append(t, y1);
  18.  
     
  19.  
    t+=intv;
  20.  
    }

然后我们添加了一些离散的点,效果如下图:

很显然,虽然添加了离散的圆形的点,但是并没有满足我们的需求,因为需求是空心的圆点。而且控件也没提供相关函数可以设置成空心。但是这里面有3个函数值得注意

  1.  
    series1->setBorderColor(QColor(21, 100, 255)); //离散点边框颜色
  2.  
    series1->setBrush(QBrush(QColor(21, 100, 255)));//离散点背景色
  3.  
    series1->setMarkerSize(12); //离散点大小

因为可以设置一个点的大小,边框和颜色。那我们如果想实现一个空心的离散点就可以这样做:

以同一个位置为圆心,画两个半径不同的实心圆。下面的圆半径大,颜色就是边框的颜色蓝色;上面的圆形半径小,颜色设置为白色。这样两个圆形叠加起来的效果,视觉上就是一个空心的圆形。按照这个思路,我们需要使用2个QScatterSeries序列

series0 : 半径较大,背景为蓝色,充当边框。

series1:半径较小,北京为白色,充电圆心。

  1.  
    //散点图(用于边框)
  2.  
    QScatterSeries *series1 = new QScatterSeries();
  3.  
    series1->setMarkerShape(QScatterSeries::MarkerShapeCircle);//圆形的点
  4.  
    series1->setBorderColor(QColor(21, 100, 255)); //边框颜色
  5.  
    series1->setBrush(QBrush(QColor(21, 100, 255)));//背景颜色
  6.  
    series1->setMarkerSize(12); //点大小
  7.  
     
  8.  
    //散点图(用于中心)
  9.  
    QScatterSeries *series2 = new QScatterSeries();
  10.  
    series2->setMarkerShape(QScatterSeries::MarkerShapeCircle);//圆形的点
  11.  
    series2->setBorderColor(Qt::white);//边框颜色
  12.  
    series2->setBrush(QBrush(Qt::white));//背景颜色
  13.  
    series2->setMarkerSize(6);//点大小
  14.  
     
  15.  
    chart->addSeries(series1);
  16.  
    chart->addSeries(series2);
  1.  
    QLineSeries *series0 = (QLineSeries *)ui->chartView->chart()->series().at(0);
  2.  
    QScatterSeries *series1 = (QScatterSeries *)ui->chartView->chart()->series().at(1);
  3.  
    QScatterSeries *series2 = (QScatterSeries *)ui->chartView->chart()->series().at(2);
  4.  
     
  5.  
    series0->clear();
  6.  
    series1->clear();
  7.  
    series2->clear();
  8.  
     
  9.  
    qsrand(QTime::currentTime().second());
  10.  
     
  11.  
    qreal t=0, y1, intv=1;
  12.  
    qreal rd;
  13.  
    int cnt=16;
  14.  
    for (int i=0; i<cnt; i++)
  15.  
    {
  16.  
    rd = (qrand() % 100);
  17.  
    y1=rd;
  18.  
    series0->append(t, y1);
  19.  
    series1->append(t, y1);
  20.  
    series2->append(t, y1);
  21.  
     
  22.  
    t+=intv;
  23.  
    }

效果如下:

做完这些,我们还有最后一个需求就是鼠标移动到这些离散的点上,要显示出当前点的数值。由于框架并没有提供相关的api,所以我们要自己完成这项工作。我们可以想象,显示的数值需要使用QLabel承载,当鼠标移动到这些点上,QLabel就show,移开就hide。那么怎么确定鼠标是否移动到这些离散点上呢?查阅文档,我们发现QCatterSeries有这样一个信号

他的意思就是,这是一个信号,当鼠标移动到上面,或者从上面移开就会发射这个信号,其中point是移动到哪个点上,当移动到上面,state=true;否则state就为false。

我们可以连接这个信号到我们自己的槽函数

connect(series2, &QScatterSeries::hovered, this, &TDMTrendChartForm::slotPointHoverd);//用于鼠标移动到点上显示数值
 
  1.  
    void TDMTrendChartForm::slotPointHoverd(const QPointF &point, bool state)
  2.  
    {
  3.  
    if (state) {
  4.  
    m_valueLabel->setText(QString::asprintf("%1.0f%", point.y()));
  5.  
     
  6.  
    QPoint curPos = mapFromGlobal(QCursor::pos());
  7.  
    m_valueLabel->move(curPos.x() - m_valueLabel->width() / 2, curPos.y() - m_valueLabel->height() * 1.5);//移动数值
  8.  
     
  9.  
    m_valueLabel->show();//显示出来
  10.  
    }
  11.  
    else
  12.  
    m_valueLabel->hide();//进行隐藏
  13.  
     
  14.  
    }

======================================================================================

补充:完善了代码。增加鼠标悬浮在离散点上,应该显示渐变的边框。

这样我们就完成了相关功能。完整代码可以在这里下载:https://download.csdn.net/download/xiezhongyuan07/10675931

======================================================================================

--------------------- 本文来自 漫步繁华街 的CSDN 博客 ,全文地址请点击:https://blog.csdn.net/xiezhongyuan07/article/details/82760103?utm_source=copy

QT QCharts QScatterSeries 空心点阵图,鼠标移动到上面显示数值,鼠标移开数值消失的更多相关文章

  1. jq实现鼠标移动到 图片上放大,移开图片缩小效果(打算封装成插件)

    先看代码 <script> $(function() { $('div').mouseover(function() { $('img').animate({ opacity: '0.9' ...

  2. WPF 鼠标移动到图片变大,移开还原,单击触发事件效果

    <Grid>         <Canvas x:Name="LayoutRoot">             <Image Cursor=" ...

  3. 鼠标划过用户名时在鼠标右下角显示div展示用户资料

    最近做一个网站论坛,为了方便会员之间相互了解,又不想再做一个页面展示用户资料,就想到了鼠标划过用户名时在鼠标右下角显示div展示用户资料这个效果, 这里要注意的该方法不是给每个用户名的旁边都绑定一个d ...

  4. 一个用 js 实现点阵图的编辑器演示

    这是个客户的需求,具体大概是可以在一个 24*8 的点阵图上自由绘制图形,然后数据的存储是按列依次记录,用0和1分别表示是否选中,最终串成一个字符串. 整体需求难度并不复杂,所以在写demo的时候就尽 ...

  5. Qt实战之开发软件数据获取助手(eventFilter处理鼠标按下,event处理鼠标松开)

    前段时间,受朋友委托,需要做一个能够获取别人软件文本框中内容的助手.当然这需要调用win api来解决问题.一开始,我想都没想,就用getWindowText()....居然没用,好郁闷.于是查msd ...

  6. 自己定义View之Chart图标系列(1)——点阵图

    近期要做一些图表类的需求,一開始就去github上看了看,发现开源的图表框架还是蛮多的.可是非常少有全然符合我的需求的.另外就是使用起来比較麻烦.所以就决定自己来造轮子了~~~ 今天要介绍的就是And ...

  7. Android实现二值点阵图识别

    好好学习,天天向上 本文已收录至我的Github仓库DayDayUP:github.com/RobodLee/DayDayUP,欢迎Star 前言 我这几天在做一个东西,就是一张像二维码这样的 n*n ...

  8. 小问题总结:鼠标点击到输入框(input)里的时候,输入框的提示消失,鼠标再移开,输入框提示出现

    问题如标题: 鼠标点击到输入框(input)里的时候,输入框的提示消失,鼠标再移开,输入框提示出现.如图所示:   做法如下: <input type="text" name ...

  9. CSS3鼠标悬停图片上浮显示描述代码

    效果:http://hovertree.com/texiao/css3/20/ 效果图: 代码如下: <!doctype html> <html lang="zh" ...

随机推荐

  1. CSUOJ 1270 Swap Digits

    Description ) in the first line, which has the same meaning as above. And the number is in the next ...

  2. 【原创】MySQL Replay线上流量压测工具

    一. 背景 去年做过一次mysql trace 重放的测试,由于performance schema本身采集样本的长度等限制,实际回放的成功率比较低. 最近找到一款开源的工具,基于TCPCopy实现了 ...

  3. Tensorflow学习:(二)搭建神经网络

    一.神经网络的实现过程 1.准备数据集,提取特征,作为输入喂给神经网络       2.搭建神经网络结构,从输入到输出       3.大量特征数据喂给 NN,迭代优化 NN 参数       4.使 ...

  4. 《jQuery基础教程》读书笔记

    最近在看<jQuery基础教程>这本书,做了点读书笔记以备回顾,不定期更新. 第一章第二章比较基础,就此略过了... 第三章 事件 jQuery中$(document).ready()与j ...

  5. luoguP3185 [HNOI2007]分裂游戏 枚举 + 博弈论

    每个位置的瓶子中的每个石子是一个独立的游戏 只要计算出他们的\(sg\)值即可 至于方案数,反正不多\(n^3\)暴力枚举即可 反正怎么暴力都能过啊 复杂度\(O(Tn^3)\) #include & ...

  6. CentOS7安装GNOME可视化界面和如何配置IP地址

    本人在虚拟机安装 CentOS7 1,检查一下我们已经安装的软件以及可以安装的软件,用命令 yum grouplist 2,然后安装我们需要的图形界面软件,GNOME(GNOME Desktop) 这 ...

  7. ZOJ 3632 K - Watermelon Full of Water 优先队列优化DP

    K - Watermelon Full of Water Time Limit:3000MS     Memory Limit:65536KB     64bit IO Format:%lld &am ...

  8. request.setAttribute()、session.setAttribute()和request.getParameter()的联系与区别(记录)

    1.session.setAttribute()和session.getAttribute()配对使用,作用域是整个会话期间,在所有的页面都使用这些数据的时候使用. 2.request.setAttr ...

  9. 封装libsvm成可程序调用的C/C++类

    libsvm很早之前就用了,现在封装一下方便自己使用,也方便大家更快的使用这个库,这个库一个挺有用的特性就是对测试样本的概率估计.源码在随笔的最后.liblinear的版本也是类似移植,主要是处理好数 ...

  10. 【Go入门教程7】面向对象(method、指针作为receiver、method继承、method重写)

    前面两章我们介绍了函数和struct,那你是否想过函数当作struct的字段一样来处理呢?今天我们就讲解一下函数的另一种形态,带有接收者(receiver)的函数,我们称为method method ...