QT QCharts QScatterSeries 空心點陣圖,鼠標移動到上面顯示數值,鼠標移開數值消失

在最近接到的需求是這樣的,畫一個折線圖,關鍵點使用空心的圓點標識出來,鼠標移動到關鍵點上,顯示出當前數值;鼠標移走數值消失。api

咱們遇到這個需求的時候,第一時間就會想到使用 QLineSeries 畫折線圖。首先初始化app

  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來畫一些離散的點。ide

  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個函數值得注意ui

  1.  
    series1->setBorderColor(QColor( 21, 100, 255)); //離散點邊框顏色
  2.  
    series1->setBrush(QBrush(QColor( 21, 100, 255)));//離散點背景色
  3.  
    series1->setMarkerSize( 12); //離散點大小

由於能夠設置一個點的大小,邊框和顏色。那咱們若是想實現一個空心的離散點就能夠這樣作:this

以同一個位置爲圓心,畫兩個半徑不一樣的實心圓。下面的圓半徑大,顏色就是邊框的顏色藍色;上面的圓形半徑小,顏色設置爲白色。這樣兩個圓形疊加起來的效果,視覺上就是一個空心的圓形。按照這個思路,咱們須要使用2個QScatterSeries序列url

series0 : 半徑較大,背景爲藍色,充當邊框。spa

series1:半徑較小,北京爲白色,充電圓心。.net

  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 

相關文章
相關標籤/搜索