首页 > 其他分享 >qt6 chart 画k线图

qt6 chart 画k线图

时间:2023-05-27 17:11:19浏览次数:48  
标签:qt6 线图 chart pEvent pos line include ChartView

实现的基本功能:

1. 显示k线, 附赠一个close指标

2. 根据鼠标移动,画十字线

3. 跟随鼠标,显示当前k线的一个值。

4. 可以移动、缩放图形

运行环境:qt 6.5 (其他环境未测试)

 

CMakeLists文件:

cmake_minimum_required(VERSION 3.14)

project(chart5 LANGUAGES CXX)

set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

find_package(Qt6 REQUIRED COMPONENTS Charts Core Gui)

# 下面candlestickdatareader.cpp .h 不是必须的,从qt example里copy出来的
# acme_data.txt 也是。 做实验不用自己编数据
add_executable(chart5
  main.cpp
  candlestickdatareader.cpp candlestickdatareader.h
)
target_link_libraries(chart5
    Qt::Charts
    Qt::Core
    Qt::Gui
)

set_source_files_properties("acme_data.txt"
    PROPERTIES QT_RESOURCE_ALIAS "acme"
)

qt6_add_resources(chart5 "chart5data"
    PREFIX
        "/"
    FILES
       "acme_data.txt"
)

主文件:

#include <QtCharts/QBarCategoryAxis>
#include <QtCharts/QCandlestickSeries>
#include <QtCharts/QChartView>
#include <QtCharts/QValueAxis>
#include <QtCore/QDateTime>
#include <QtCore/QFile>
#include <QtWidgets/QApplication>
#include <QtWidgets/QMainWindow>
#include <QtWidgets>
#include <QtCharts>
#include <QDebug>
#include <QObject>
#include "candlestickdatareader.h"

class ChartView : public QChartView
{
public:
    ChartView(QChart* chart = nullptr);
    virtual ~ChartView();
protected:
    virtual void mouseMoveEvent(QMouseEvent *pEvent) override;
    virtual void mousePressEvent(QMouseEvent *pEvent) override;
    virtual void mouseReleaseEvent(QMouseEvent *pEvent) override;
    virtual void wheelEvent(QWheelEvent *pEvent) override;
    virtual void enterEvent(QEnterEvent *pEvent)override;
    virtual void leaveEvent(QEvent *pEvent)override;

private:
    bool leftButtonPressed;
    QPoint prePos;

    QGraphicsLineItem* x_line;
    QGraphicsLineItem* y_line;

    QGraphicsSimpleTextItem* cursor_text;
};



ChartView::ChartView(QChart *chart):
    QChartView(chart),
    leftButtonPressed(false) ,
    prePos(0, 0)
{
    // 创建线
    x_line = new QGraphicsLineItem();
    // 设置颜色
    x_line->setPen(QPen(QColor( 100, 100, 100 )));
    x_line->setZValue(2);
    y_line = new QGraphicsLineItem();
    y_line->setPen(QPen(QColor( 100, 100, 100 )));
    y_line->setZValue(2);

    // 添加到scene中。
    this->scene()->addItem(x_line);
    this->scene()->addItem(y_line);

    cursor_text = new QGraphicsSimpleTextItem;
    this->scene()->addItem(cursor_text);

}
ChartView::~ChartView()
{

}
//// 鼠标移动
void ChartView::mouseMoveEvent(QMouseEvent *pEvent)
{
    if (leftButtonPressed)
    {
        QPoint oDeltaPos = pEvent->pos() - prePos;
        this->chart()->scroll(-oDeltaPos.x(), oDeltaPos.y());
        prePos = pEvent->pos();
    }        

    // 绘制线
    x_line->setLine(pEvent->pos().rx(),0,pEvent->pos().rx(),this->height());
    y_line->setLine(0,pEvent->pos().ry(),this->width(),pEvent->pos().ry());

    // 设置显示内容
    auto valpos = chart()->mapToValue(pEvent->pos());
    int x = int(valpos.x());
    QCandlestickSeries *candle = qobject_cast<QCandlestickSeries *>(chart()->series().at(0));
    if (x<0) x = 0;
    if (x>=candle->count()) x = candle->count()-1;
    auto d = candle->sets().at(x)->close();
    cursor_text->setText(QString("sit:%1:%2").arg(x).arg(d));
    // 调整显示内容到鼠标右上
    auto pos = pEvent->pos();
    pos.setY(pos.ry()-20);
    pos.setX(pos.rx()+10);
    cursor_text->setPos(pos);

    __super::mouseMoveEvent(pEvent);
}

//// 鼠标按键
void ChartView::mousePressEvent(QMouseEvent *pEvent)
{
    if (pEvent->button() == Qt::LeftButton)
    {
        leftButtonPressed = true;
        prePos = pEvent->pos();
        this->setCursor(Qt::OpenHandCursor);
    }
    __super::mousePressEvent(pEvent);
}
//// 鼠标抬起
void ChartView::mouseReleaseEvent(QMouseEvent *pEvent)
{
    if (pEvent->button() == Qt::LeftButton)
    {
        leftButtonPressed = false;
        this->setCursor(Qt::ArrowCursor);
    }
    __super::mouseReleaseEvent(pEvent);
}

void ChartView::wheelEvent(QWheelEvent *pEvent)
{
    qreal rVal;
    if (pEvent->angleDelta().y() > 0)
        rVal = 0.99;
    else
        rVal = 1.01;


    // 1. 读取视图基本信息
    QRectF oPlotAreaRect = this->chart()->plotArea();
    QPointF oCenterPoint = oPlotAreaRect.center();
    // 2. 水平调整
    oPlotAreaRect.setWidth(oPlotAreaRect.width() * rVal);
    // 3. 竖直调整
    oPlotAreaRect.setHeight(oPlotAreaRect.height() * rVal);
    // 4.1 计算视点,视点不变,围绕中心缩放
    //QPointF oNewCenterPoint(oCenterPoint);
    // 4.2 计算视点,让鼠标点击的位置移动到窗口中心
    //QPointF oNewCenterPoint(pEvent->pos());
    // 4.3 计算视点,让鼠标点击的位置尽量保持不动(等比换算,存在一点误差)
    QPointF oNewCenterPoint(2 * oCenterPoint - pEvent->position() - (oCenterPoint - pEvent->position()) / rVal);
    // 5. 设置视点
    oPlotAreaRect.moveCenter(oNewCenterPoint);
    // 6. 提交缩放调整
    this->chart()->zoomIn(oPlotAreaRect);

    __super::wheelEvent(pEvent);
}

void ChartView::enterEvent(QEnterEvent *pEvent)
{
    x_line->setVisible(true);
    y_line->setVisible(true);
    cursor_text->setVisible(true);
    __super::enterEvent(pEvent);
}

void ChartView::leaveEvent(QEvent *pEvent)
{
    x_line->setVisible(false);
    y_line->setVisible(false);
    cursor_text->setVisible(false);
    __super::leaveEvent(pEvent);
}

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    QCandlestickSeries *acmeSeries = new QCandlestickSeries();
    acmeSeries->setName("Acme Ltd");
    acmeSeries->setIncreasingColor(QColor(Qt::green));
    acmeSeries->setDecreasingColor(QColor(Qt::red));

    QLineSeries *closeSeries = new QLineSeries();
    closeSeries->setName("close");
    closeSeries->setColor(QColor(Qt::black));

    // 示例数据
    QFile acmeData(":acme");
    if (!acmeData.open(QIODevice::ReadOnly | QIODevice::Text))
        return 1;

    QStringList categories;

    CandlestickDataReader dataReader(&acmeData);
    int i = 0;
    while (!dataReader.atEnd()) {
        QCandlestickSet *set = dataReader.readCandlestickSet();
        if (set) {
            acmeSeries->append(set);
            closeSeries->append(QPointF(i++, set->close()));
            categories << QDateTime::fromMSecsSinceEpoch(set->timestamp()).toString("dd");            
        }
    }

    QChart *chart = new QChart();
    chart->addSeries(acmeSeries);
    chart->addSeries(closeSeries);
    chart->setTitle("Acme Ltd Historical Data (July 2015)");
    chart->setAnimationOptions(QChart::SeriesAnimations);


    chart->createDefaultAxes();

    QBarCategoryAxis *axisX = qobject_cast<QBarCategoryAxis *>(chart->axes(Qt::Horizontal).at(0));
    axisX->setCategories(categories);

    QValueAxis *axisY = qobject_cast<QValueAxis *>(chart->axes(Qt::Vertical).at(0));
    axisY->setMax(axisY->max() * 1.01);
    axisY->setMin(axisY->min() * 0.99);

    chart->legend()->setVisible(true);
    chart->legend()->setAlignment(Qt::AlignBottom);

    QChartView *chartView = new ChartView(chart);
    // 抗锯齿
    chartView->setRenderHint(QPainter::Antialiasing);

    QMainWindow window;
    window.setCentralWidget(chartView);
    window.resize(800, 600);
    window.show();

    return a.exec();
}

 

标签:qt6,线图,chart,pEvent,pos,line,include,ChartView
From: https://www.cnblogs.com/kingkaixuan/p/17437006.html

相关文章

  • FLEX实践—PieChart综合应用(颜色渐变、显示选中值、选中部分突出、数据钻探等)
    代码如下:(代码中附加了注释,每一种方法对应的效果均有注释)<?xmlversion="1.0"encoding="utf-8"?><mx:Applicationxmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creationComplete="init()"> <mx:Scr......
  • Python竖版大屏2 | 用pyecharts开发可视化的奇妙探索!
    目录1、SHINE主题2、LIGHT主题3、MACARONS主题4、INFOGRAPHIC主题5、WALDEN主题6、WESTEROS主题7、WHITE主题8、WONDERLAND主题你好!我是@马哥python说,一名10年程序猿,正在试错用pyecharts开发可视化大屏的非常规排版。以下,我用8种ThemeType展示的同一个可视化数据大屏,可视化主题......
  • echart 隐秘的坑 => 传值类型
    前言最近整个大屏项目,期间遇到奇葩的问题:如下代码,发现legend的icon与文字老是有一段距离,也没报错legend={data:series.map(i=>i.name),//data:['预计曲线','实际曲线'],icon:'rect',right:'14',it......
  • 怎么做产品路线图规划?
    ​产品路线图规划•产品路线图是一个高层次的战略计划,它描述了产品在未来一段时间可能会如何发展和壮大,产品路线图确保整个产品团队持续关注产品的目标,帮助产品负责人把握产品的战略方向,调整产品的优先级和产品规划。里程碑•里程碑是产品路线图上达成产品愿景的一个个阶段性目......
  • chartpdt教我写代码
    string类型的非空判断用string.IsNullOrWhiteSpace if(barCode==null||!barCode.Any())一起用在确认对象有值的情况下取第一个用First()而非FirstOrDefault()对象需要用到时才创建,避免不必要的对象创建和初始化避免使用!=null的判断方式将计算过程分离出来,使代码更......
  • ubuntu系统安装的firefox浏览器 echarts图表显示有问题,但是window版的firefox浏览器是
    如果在Ubuntu系统上安装的Firefox浏览器不能正确显示ECharts图表,有几种可能的原因和解决方法:1.缺少字体在Ubuntu系统中,可能会缺少浏览器所需的字体文件,导致无法正确显示图表。可以通过以下命令安装所需的字体:```sudoapt-getinstallttf-wqy-zenhei```安装后,重启Fi......
  • 【echarts】柱状图上方显示数值
    <!DOCTYPEhtml><head> <metacharset="utf-8"> <title>ECharts</title></head><body> <!--为ECharts准备一个具备大小(宽高)的Dom--> <divid="main"style="width:900px;height:300px"&......
  • 最新版本firefox浏览器 显示echarts图表会卡死,但是Chrome浏览器或者Edge浏览器是正常
    如果您的Firefox浏览器最新版本也出现了无法正常显示Echarts图表的问题,可以尝试以下几个方法:1.禁用硬件加速:在一些特定的系统或者硬件环境下,启用Firefox的硬件加速功能可能会导致Echarts图表卡死。您可以尝试通过以下步骤禁用硬件加速:-在Firefox的地址栏中输入abou......
  • echarts 两个标题 主标题 和副标题 分开设置
    1title:[2{3text:'模型类型',4left:40,5top:20,67textStyle:{8......
  • Python竖版大屏 | 用pyecharts开发可视化的奇妙探索!
    你好!我是@马哥python说,一枚10年程序猿......