文章目录
一、图表操作示例图
1.图表选择示例
下图演示了通过下拉列表框切换图表的操作。
2.动画选项操作
下图演示了动画选项中三种动画的效果。
3.图例选项操作
下图演示了图例选项中四种图例的显示位置。
4.其他选项操作
下图演示了图表添加防锯齿功能和标题的隐藏和显示。
提示:不会使用Qt设计师设计界面的小伙伴点击这里
二、QChart(个人理解)
- 使用前需要在pro文件中添加“QT +=charts”;
- 在头文件中添加了对应的QChart头文件还不够还需要使用对应的命名空间可通过宏定义或者using使用QChart的命名空间(详情请看代码);
- QChart的数据分装层次大概为 QChartView -> QChart -> Series -> Value,就是说view装chart,chart装series, series装对应类型的值,一些图表值中可能还会细分,只要记住这个顺序,一般都不会漏掉;
- 在开发过程中,发现QChart有时还是不那么灵活,在使用过程中就得考虑灵活性这些了。
三、部分源码讲解
ui中添加动态属性
本文在ui中设置了大量的动态属性,所有按钮都有对应的动态属性,ui中添加/移除动态属性操作如下。
按钮组的使用
本文使用了三个(动画组、图例组、其他)按钮组链接槽函数做操作;
在帮助中查看按钮组信号,发现其有“void buttonClicked(QAbstractButton *button)”信号,正好适用于本文,于是通过该信号与槽函数链接。按钮组链接槽函数的方法有多种,这里简述三种,如下:
- 定义参数为(QAbstractButton *button)的槽函数,通过connect手动链接信号槽(详情查看源码)
- 根据Qt槽函数标准定义槽函数,在构建时会自动链接,构建格式为:“on_Object Name_Signal”(Object Name:对象名, Signal:触发槽函数的信号,详情看源码)。
四、源码
(因为本文ui中包含动态属性,所以本文会留下ui代码,可复制粘贴到ui文件使用)
CChartTest.h
#ifndef CCHARTTEST_H#define CCHARTTEST_H#include<QMainWindow>#include<QtCharts>//! 使用QChart需要使用对应的命名空间//! 使用方法有如下两种(更改宏定义判断条件即可更换调用方法)#if true
QT_CHARTS_USE_NAMESPACE // 定义好的宏定义使用命名空间#elseusingnamespace QtCharts;// 常规使用命名空间的方法#endifnamespace Ui {classCChartTest;}classCChartTest:public QMainWindow
{
Q_OBJECT
public:explicitCChartTest(QWidget *parent =nullptr);~CChartTest();/**
* @brief createPieChart 创建饼图指针
* @return 返回饼图QChart指针
*/
QChart *createPieChart();/**
* @brief createAreaChart 创建区域图指针
* @return 返回区域图QChart指针
*/
QChart *createAreaChart();/**
* @brief createLineChart 创建折线图指针
* @return 返回折线图QChart指针
*/
QChart *createLineChart();/**
* @brief createSpLineChart 创建曲线图指针
* @return 返回曲线图QChart指针
*/
QChart *createSpLineChart();/**
* @brief createBarChart 创建柱状图指针
* @return 返回柱状图QChart指针
*/
QChart *createBarChart();/**
* @brief createScatterChart 创建散点图指针
* @return 返回散点图QChart指针
*/
QChart *createScatterChart();voidsetChartAttribute(QChart *chart, QString title);private slots:/**
* @brief on_comboBox_currentIndexChanged 图标类型下拉列表框索引改变槽函数
* @param index 改变后的索引值
*/voidon_comboBox_currentIndexChanged(int index);/**
* @brief on_legendGroupButtonClicked 图例按钮组点击槽函数
* @param button 所点击按钮
*/voidon_legendGroupButtonClicked(QAbstractButton *button);/**
* @brief on_animationGroup_buttonClicked 动画组按钮组点击槽函数
* @param button 所点击按钮
*/voidon_animationGroup_buttonClicked(QAbstractButton *button);/**
* @brief on_otherGroup_buttonClicked 其他组按钮组点击槽函数
* @param button 所点击按钮
*/voidon_otherGroup_buttonClicked(QAbstractButton *button);private:
Ui::CChartTest *ui;
QChartView *m_chartView;// view对象(用于显示QChart图形)
QVector<QChart *> m_chartVector;// 存储各个类型chart的容器};#endif// CCHARTTEST_H
CChartTest.cpp
#include"CChartTest.h"#include"ui_CChartTest.h"
CChartTest::CChartTest(QWidget *parent):QMainWindow(parent),ui(new Ui::CChartTest){
ui->setupUi(this);// 创建view对象控件
m_chartView =newQChartView();// 将view空间添加到ui中
ui->horizontalLayout->addWidget(m_chartView);// 添加饼图
m_chartVector.append(createPieChart());// 设置默认显示饼图
m_chartView->setChart(m_chartVector.at(0));// 添加柱状图
m_chartVector.append(createBarChart());// 添加面积图
m_chartVector.append(createAreaChart());// 添加折线图
m_chartVector.append(createLineChart());// 添加曲线图
m_chartVector.append(createSpLineChart());// 添加散点图
m_chartVector.append(createScatterChart());// 手动连接信号槽connect(ui->legendGroup,SIGNAL(buttonClicked(QAbstractButton *)),this,SLOT(on_legendGroupButtonClicked(QAbstractButton *)));
ui->otherGroup->setExclusive(false);// 设置其他选项组可复选}
CChartTest::~CChartTest(){// 逆向释放图表空间(保证构造顺序和析构顺序相反)for(int index = m_chartVector.size()-1; index !=-1;--index){delete m_chartVector[index];}// 释放viewdelete m_chartView;// 释放uidelete ui;}
QChart *CChartTest::createPieChart(){// 创建QChart对象
QChart *chart =newQChart();// 创建饼图系列对象
QPieSeries *series =newQPieSeries(chart);// 遍历假数据容器将数据添加到series对象中qsrand(QDateTime::currentMSecsSinceEpoch()%20000);// 添加图表值for(int index =0; index !=5;++index){
series->append(QString(65+ index),rand()%100);}// 将series添加到QChart对象中
chart->addSeries(series);// 设置通用属性setChartAttribute(chart,"饼图");// 返回QChart对象return chart;}
QChart *CChartTest::createAreaChart(){// 创建QChart对象
QChart *chart =newQChart();// 添加图表值//! 创建区域图系列对象//! 区域图的系列对象
QLineSeries *lowerSeries =nullptr;for(int count =1; count !=3;++count){// 创建折线图系列对象
QLineSeries *upperSeries =newQLineSeries(chart);for(int index =1; index !=5;++index){
upperSeries->append(index , index * count *5+rand()%5);}// 将series添加到QChart对象中
QAreaSeries *series =newQAreaSeries(upperSeries, lowerSeries);
lowerSeries = upperSeries;
chart->addSeries(series);}// 设置通用属性setChartAttribute(chart,"面积图");// 返回QChart对象return chart;}
QChart *CChartTest::createLineChart(){// 创建QChart对象
QChart *chart =newQChart();// 添加图表值for(int count =0; count !=3;++count){// 创建折线图系列对象
QLineSeries *series =newQLineSeries(chart);for(int index =0; index !=5;++index){
series->append(index * count, index * count -rand()%3);}// 将series添加到QChart对象中
chart->addSeries(series);}// 设置通用属性setChartAttribute(chart,"折线图");// 返回QChart对象return chart;}
QChart *CChartTest::createSpLineChart(){// 创建QChart对象
QChart *chart =newQChart();// 添加图表值for(int count =0; count !=3;++count){// 创建曲线图系列对象
QSplineSeries *series =newQSplineSeries(chart);for(int index =0; index !=5;++index){
series->append(index * count, index * count -rand()%8);}// 将series添加到QChart对象中
chart->addSeries(series);}// 设置通用属性setChartAttribute(chart,"曲线图");// 返回QChart对象return chart;}
QChart *CChartTest::createBarChart(){// 创建QChart对象
QChart *chart =newQChart();// 创建饼图系列对象
QBarSeries *series =newQBarSeries(chart);qsrand(QDateTime::currentMSecsSinceEpoch()%20000);// 添加图表值for(int count =0; count !=3;++count){// 创建曲线图系列对象
QBarSet *set =newQBarSet(QString(65+ count));for(int index =0; index !=5;++index){
set->append(rand()%100);}
series->append(set);}// 将series添加到QChart对象中
chart->addSeries(series);// 设置通用属性setChartAttribute(chart,"柱状图");// 返回QChart对象return chart;}
QChart *CChartTest::createScatterChart(){// 创建QChart对象
QChart *chart =newQChart();// 添加图表值for(int count =0; count !=3;++count){// 创建曲线图系列对象
QScatterSeries *series =newQScatterSeries(chart);for(int index =0; index !=5;++index){
series->append(index , index * count *5+rand()%5);}// 将series添加到QChart对象中
chart->addSeries(series);}// 设置通用属性setChartAttribute(chart,"散点图");// 返回QChart对象return chart;}void CChartTest::setChartAttribute(QChart *chart, QString title){// 创建默认坐标轴
chart->createDefaultAxes();// 设置标题
chart->setTitle(title);// 设置data,在设置标题时使用
chart->setData(Qt::UserRole, title);}void CChartTest::on_comboBox_currentIndexChanged(int index){// 拿到chart容器中相同索引位置的QChart对象,并将其设置到view对象上
QChart *chart = m_chartVector[index];
m_chartView->setChart(chart);}void CChartTest::on_legendGroupButtonClicked(QAbstractButton *button){// 拿到发送信号的单选按钮
QRadioButton *btn =dynamic_cast<QRadioButton *>(button);// 遍历图表容器,将legend的aign属性设为当前按钮对应的属性状态foreach(QChart *chart, m_chartVector){//! 拿到当前单选按钮的属性值并强转为Qt::Alignment类型//!
Qt::Alignment align =static_cast<Qt::Alignment>(btn->property("LegendValue").toUInt());// 将类型值设置到当前图表上
chart->legend()->setAlignment(align);}}void CChartTest::on_animationGroup_buttonClicked(QAbstractButton *button){// 拿到发送信号的单选按钮
QRadioButton *btn =dynamic_cast<QRadioButton *>(button);// 遍历图表容器,将chart的动画设为当前按钮对应的属性状态foreach(QChart *chart, m_chartVector){//! 拿到当前单选按钮的属性值并强转为Qt::AnimationOption//! 其属性值为对应动画的int值,可通过帮助查看具体值
QChart::AnimationOption animation =static_cast<QChart::AnimationOption>(btn->property("AnimationValue").toUInt());// 将类型值设置到当前图表上
chart->setAnimationOptions(animation);}}void CChartTest::on_otherGroup_buttonClicked(QAbstractButton *button){// 拿到发送信号的复选按钮
QCheckBox *btn =dynamic_cast<QCheckBox *>(button);// 判断所点击按钮的勾选状态bool checked = btn->isChecked();// 通过按钮动态属性判断按钮操作switch(btn->property("btnType").toInt()){case0:{// 设置view的防锯齿,其还包含其他防锯齿选项,可查看帮助了解
m_chartView->setRenderHint(QPainter::Antialiasing, checked);break;}case1:{foreach(QChart *chart, m_chartVector){// 通过三目运算符判断标题是否获取data中的值
QString title = checked? chart->data(Qt::UserRole).toString():"";// 设置标题
chart->setTitle(title);}break;}default:break;}}
CChartTest.ui
<?xml version="1.0" encoding="UTF-8"?><uiversion="4.0"><class>CChartTest</class><widgetclass="QMainWindow"name="CChartTest"><propertyname="geometry"><rect><x>0</x><y>0</y><width>625</width><height>475</height></rect></property><propertyname="windowTitle"><string>CChartTest</string></property><widgetclass="QWidget"name="centralWidget"><layoutclass="QHBoxLayout"name="horizontalLayout"><item><layoutclass="QVBoxLayout"name="verticalLayout"stretch="0,1,1,1"><item><layoutclass="QHBoxLayout"name="horizontalLayout2"><item><widgetclass="QLabel"name="label"><propertyname="text"><string>图表类型:</string></property></widget></item><item><widgetclass="QComboBox"name="comboBox"><item><propertyname="text"><string>饼图</string></property></item><item><propertyname="text"><string>柱状图</string></property></item><item><propertyname="text"><string>面积图</string></property></item><item><propertyname="text"><string>折线图</string></property></item><item><propertyname="text"><string>曲线图</string></property></item><item><propertyname="text"><string>散点图</string></property></item></widget></item></layout></item><item><widgetclass="QGroupBox"name="groupBox"><propertyname="title"><string>动画选项</string></property><layoutclass="QGridLayout"name="gridLayout"><itemrow="0"column="0"><widgetclass="QRadioButton"name="radioButton"><propertyname="text"><string>无动画</string></property><propertyname="checked"><bool>true</bool></property><propertyname="AnimationValue"stdset="0"><number>0</number></property><attributename="buttonGroup"><stringnotr="true">animationGroup</string></attribute></widget></item><itemrow="0"column="1"><widgetclass="QRadioButton"name="radioButton_2"><propertyname="text"><string>栅格轴动画</string></property><propertyname="AnimationValue"stdset="0"><number>1</number></property><attributename="buttonGroup"><stringnotr="true">animationGroup</string></attribute></widget></item><itemrow="1"column="0"><widgetclass="QRadioButton"name="radioButton_3"><propertyname="text"><string>系列动画</string></property><propertyname="AnimationValue"stdset="0"><number>2</number></property><attributename="buttonGroup"><stringnotr="true">animationGroup</string></attribute></widget></item><itemrow="1"column="1"><widgetclass="QRadioButton"name="radioButton_4"><propertyname="text"><string>所有动画</string></property><propertyname="AnimationValue"stdset="0"><number>3</number></property><attributename="buttonGroup"><stringnotr="true">animationGroup</string></attribute></widget></item></layout></widget></item><item><widgetclass="QGroupBox"name="groupBox_2"><propertyname="title"><string>图例选项</string></property><layoutclass="QGridLayout"name="gridLayout_2"><itemrow="0"column="0"><widgetclass="QRadioButton"name="radioButton_9"><propertyname="text"><string>无图例</string></property><propertyname="LegendValue"stdset="0"><number>0</number></property><attributename="buttonGroup"><stringnotr="true">legendGroup</string></attribute></widget></item><itemrow="0"column="1"><widgetclass="QRadioButton"name="radioButton_11"><propertyname="text"><string>图例靠上</string></property><propertyname="checked"><bool>true</bool></property><propertyname="LegendValue"stdset="0"><UInt>32</UInt></property><attributename="buttonGroup"><stringnotr="true">legendGroup</string></attribute></widget></item><itemrow="1"column="0"><widgetclass="QRadioButton"name="radioButton_12"><propertyname="text"><string>图例靠左</string></property><propertyname="LegendValue"stdset="0"><number>1</number></property><attributename="buttonGroup"><stringnotr="true">legendGroup</string></attribute></widget></item><itemrow="1"column="1"><widgetclass="QRadioButton"name="radioButton_10"><propertyname="text"><string>图例靠右</string></property><propertyname="LegendValue"stdset="0"><number>2</number></property><attributename="buttonGroup"><stringnotr="true">legendGroup</string></attribute></widget></item><itemrow="1"column="2"><widgetclass="QRadioButton"name="radioButton_13"><propertyname="text"><string>图例靠下</string></property><propertyname="LegendValue"stdset="0"><number>64</number></property><attributename="buttonGroup"><stringnotr="true">legendGroup</string></attribute></widget></item></layout></widget></item><item><widgetclass="QGroupBox"name="groupBox_3"><propertyname="title"><string>其他选项</string></property><layoutclass="QGridLayout"name="gridLayout_3"><itemrow="0"column="1"><widgetclass="QCheckBox"name="checkBox_2"><propertyname="text"><string>显示标题</string></property><propertyname="checked"><bool>true</bool></property><propertyname="btnType"stdset="0"><number>1</number></property><attributename="buttonGroup"><stringnotr="true">otherGroup</string></attribute></widget></item><itemrow="0"column="0"><widgetclass="QCheckBox"name="checkBox"><propertyname="text"><string>防锯齿</string></property><propertyname="btnType"stdset="0"><number>0</number></property><attributename="buttonGroup"><stringnotr="true">otherGroup</string></attribute></widget></item></layout></widget></item></layout></item></layout></widget><widgetclass="QMenuBar"name="menuBar"><propertyname="geometry"><rect><x>0</x><y>0</y><width>625</width><height>23</height></rect></property></widget><widgetclass="QToolBar"name="mainToolBar"><attributename="toolBarArea"><enum>TopToolBarArea</enum></attribute><attributename="toolBarBreak"><bool>false</bool></attribute></widget><widgetclass="QStatusBar"name="statusBar"/></widget><layoutdefaultspacing="6"margin="11"/><resources/><connections/><buttongroups><buttongroupname="animationGroup"/><buttongroupname="legendGroup"/><buttongroupname="otherGroup"/></buttongroups></ui>
main.cpp
#include"CChartTest.h"#include<QApplication>intmain(int argc,char*argv[]){
QApplication a(argc, argv);
CChartTest w;
w.show();return a.exec();}
总结
本文功能不算完整,理论上说各个图表的选项独立,不是通用的更好(就是说每次点击按钮只改变当前图表的属性),有兴趣的伙伴可以优化此功能,其实除了本文的功能只是皮毛,QChart还有许多神奇操作,学无止境,就一起去发掘吧。
终于把这文章写完了,足足拖了我两周,最近实在是没时间,也太忙了,每天下了班根本不想敲代码,只想躺平,然后就拖到了现在😂。
最后给自己也给大家说“不做思想上的巨人行动上的矮子”,那就休息了,晚安😁。
相关文章
Qt之QtDataVisualization各三维图表的简单使用(含源码+注释)
友情提示——哪里看不懂可私哦,让我们一起互相进步吧
(创作不易,请留下一个免费的赞叭 谢谢 ^o^/)
注:文章为作者编程过程中所遇到的问题和总结,内容仅供参考,若有错误欢迎指出。
注:如有侵权,请联系作者删除
版权归原作者 lw只吃亿点. 所有, 如有侵权,请联系我们删除。