下图演示了图表添加防锯齿功能和标题的隐藏和显示。
提示:不会使用Qt设计师设计界面的小伙伴点击这里
本文在ui中设置了大量的动态属性,所有按钮都有对应的动态属性,ui中添加/移除动态属性操作如下。
本文使用了三个(动画组、图例组、其他)按钮组链接槽函数做操作;
在帮助中查看按钮组信号,发现其有“void buttonClicked(QAbstractButton *button)”信号,正好适用于本文,于是通过该信号与槽函数链接。按钮组链接槽函数的方法有多种,这里简述三种,如下:
(因为本文ui中包含动态属性,所以本文会留下ui代码,可复制粘贴到ui文件使用)
#ifndef CCHARTTEST_H
#define CCHARTTEST_H
#include
#include
//! 使用QChart需要使用对应的命名空间
//! 使用方法有如下两种(更改宏定义判断条件即可更换调用方法)
#if true
QT_CHARTS_USE_NAMESPACE // 定义好的宏定义使用命名空间
#else
using namespace QtCharts; // 常规使用命名空间的方法
#endif
namespace Ui {
class CChartTest;
}
class CChartTest : public QMainWindow
{
Q_OBJECT
public:
explicit CChartTest(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();
void setChartAttribute(QChart *chart, QString title);
private slots:
/**
* @brief on_comboBox_currentIndexChanged 图标类型下拉列表框索引改变槽函数
* @param index 改变后的索引值
*/
void on_comboBox_currentIndexChanged(int index);
/**
* @brief on_legendGroupButtonClicked 图例按钮组点击槽函数
* @param button 所点击按钮
*/
void on_legendGroupButtonClicked(QAbstractButton *button);
/**
* @brief on_animationGroup_buttonClicked 动画组按钮组点击槽函数
* @param button 所点击按钮
*/
void on_animationGroup_buttonClicked(QAbstractButton *button);
/**
* @brief on_otherGroup_buttonClicked 其他组按钮组点击槽函数
* @param button 所点击按钮
*/
void on_otherGroup_buttonClicked(QAbstractButton *button);
private:
Ui::CChartTest *ui;
QChartView *m_chartView; // view对象(用于显示QChart图形)
QVector<QChart *> m_chartVector; // 存储各个类型chart的容器
};
#endif // CCHARTTEST_H
#include "CChartTest.h"
#include "ui_CChartTest.h"
CChartTest::CChartTest(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::CChartTest)
{
ui->setupUi(this);
// 创建view对象控件
m_chartView = new QChartView();
// 将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];
}
// 释放view
delete m_chartView;
// 释放ui
delete ui;
}
QChart *CChartTest::createPieChart()
{
// 创建QChart对象
QChart *chart = new QChart();
// 创建饼图系列对象
QPieSeries *series = new QPieSeries(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 = new QChart();
// 添加图表值
//! 创建区域图系列对象
//! 区域图的系列对象
QLineSeries *lowerSeries = nullptr;
for(int count = 1; count != 3; ++count)
{
// 创建折线图系列对象
QLineSeries *upperSeries = new QLineSeries(chart);
for(int index = 1; index != 5; ++index)
{
upperSeries->append(index , index * count * 5 + rand() % 5);
}
// 将series添加到QChart对象中
QAreaSeries *series = new QAreaSeries(upperSeries, lowerSeries);
lowerSeries = upperSeries;
chart->addSeries(series);
}
// 设置通用属性
setChartAttribute(chart, "面积图");
// 返回QChart对象
return chart;
}
QChart *CChartTest::createLineChart()
{
// 创建QChart对象
QChart *chart = new QChart();
// 添加图表值
for(int count = 0; count != 3; ++count)
{
// 创建折线图系列对象
QLineSeries *series = new QLineSeries(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 = new QChart();
// 添加图表值
for(int count = 0; count != 3; ++count)
{
// 创建曲线图系列对象
QSplineSeries *series = new QSplineSeries(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 = new QChart();
// 创建饼图系列对象
QBarSeries *series = new QBarSeries(chart);
qsrand(QDateTime::currentMSecsSinceEpoch() % 20000);
// 添加图表值
for(int count = 0; count != 3; ++count)
{
// 创建曲线图系列对象
QBarSet *set = new QBarSet(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 = new QChart();
// 添加图表值
for(int count = 0; count != 3; ++count)
{
// 创建曲线图系列对象
QScatterSeries *series = new QScatterSeries(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())
{
case 0:
{
// 设置view的防锯齿,其还包含其他防锯齿选项,可查看帮助了解
m_chartView->setRenderHint(QPainter::Antialiasing, checked);
break;
}
case 1:
{
foreach(QChart *chart, m_chartVector)
{
// 通过三目运算符判断标题是否获取data中的值
QString title = checked? chart->data(Qt::UserRole).toString(): "";
// 设置标题
chart->setTitle(title);
}
break;
}
default:
break;
}
}
<ui version="4.0">
<class>CChartTestclass>
<widget class="QMainWindow" name="CChartTest">
<property name="geometry">
<rect>
<x>0x>
<y>0y>
<width>625width>
<height>475height>
rect>
property>
<property name="windowTitle">
<string>CChartTeststring>
property>
<widget class="QWidget" name="centralWidget">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<layout class="QVBoxLayout" name="verticalLayout" stretch="0,1,1,1">
<item>
<layout class="QHBoxLayout" name="horizontalLayout2">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>图表类型:string>
property>
widget>
item>
<item>
<widget class="QComboBox" name="comboBox">
<item>
<property name="text">
<string>饼图string>
property>
item>
<item>
<property name="text">
<string>柱状图string>
property>
item>
<item>
<property name="text">
<string>面积图string>
property>
item>
<item>
<property name="text">
<string>折线图string>
property>
item>
<item>
<property name="text">
<string>曲线图string>
property>
item>
<item>
<property name="text">
<string>散点图string>
property>
item>
widget>
item>
layout>
item>
<item>
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>动画选项string>
property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QRadioButton" name="radioButton">
<property name="text">
<string>无动画string>
property>
<property name="checked">
<bool>truebool>
property>
<property name="AnimationValue" stdset="0">
<number>0number>
property>
<attribute name="buttonGroup">
<string notr="true">animationGroupstring>
attribute>
widget>
item>
<item row="0" column="1">
<widget class="QRadioButton" name="radioButton_2">
<property name="text">
<string>栅格轴动画string>
property>
<property name="AnimationValue" stdset="0">
<number>1number>
property>
<attribute name="buttonGroup">
<string notr="true">animationGroupstring>
attribute>
widget>
item>
<item row="1" column="0">
<widget class="QRadioButton" name="radioButton_3">
<property name="text">
<string>系列动画string>
property>
<property name="AnimationValue" stdset="0">
<number>2number>
property>
<attribute name="buttonGroup">
<string notr="true">animationGroupstring>
attribute>
widget>
item>
<item row="1" column="1">
<widget class="QRadioButton" name="radioButton_4">
<property name="text">
<string>所有动画string>
property>
<property name="AnimationValue" stdset="0">
<number>3number>
property>
<attribute name="buttonGroup">
<string notr="true">animationGroupstring>
attribute>
widget>
item>
layout>
widget>
item>
<item>
<widget class="QGroupBox" name="groupBox_2">
<property name="title">
<string>图例选项string>
property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<widget class="QRadioButton" name="radioButton_9">
<property name="text">
<string>无图例string>
property>
<property name="LegendValue" stdset="0">
<number>0number>
property>
<attribute name="buttonGroup">
<string notr="true">legendGroupstring>
attribute>
widget>
item>
<item row="0" column="1">
<widget class="QRadioButton" name="radioButton_11">
<property name="text">
<string>图例靠上string>
property>
<property name="checked">
<bool>truebool>
property>
<property name="LegendValue" stdset="0">
<UInt>32UInt>
property>
<attribute name="buttonGroup">
<string notr="true">legendGroupstring>
attribute>
widget>
item>
<item row="1" column="0">
<widget class="QRadioButton" name="radioButton_12">
<property name="text">
<string>图例靠左string>
property>
<property name="LegendValue" stdset="0">
<number>1number>
property>
<attribute name="buttonGroup">
<string notr="true">legendGroupstring>
attribute>
widget>
item>
<item row="1" column="1">
<widget class="QRadioButton" name="radioButton_10">
<property name="text">
<string>图例靠右string>
property>
<property name="LegendValue" stdset="0">
<number>2number>
property>
<attribute name="buttonGroup">
<string notr="true">legendGroupstring>
attribute>
widget>
item>
<item row="1" column="2">
<widget class="QRadioButton" name="radioButton_13">
<property name="text">
<string>图例靠下string>
property>
<property name="LegendValue" stdset="0">
<number>64number>
property>
<attribute name="buttonGroup">
<string notr="true">legendGroupstring>
attribute>
widget>
item>
layout>
widget>
item>
<item>
<widget class="QGroupBox" name="groupBox_3">
<property name="title">
<string>其他选项string>
property>
<layout class="QGridLayout" name="gridLayout_3">
<item row="0" column="1">
<widget class="QCheckBox" name="checkBox_2">
<property name="text">
<string>显示标题string>
property>
<property name="checked">
<bool>truebool>
property>
<property name="btnType" stdset="0">
<number>1number>
property>
<attribute name="buttonGroup">
<string notr="true">otherGroupstring>
attribute>
widget>
item>
<item row="0" column="0">
<widget class="QCheckBox" name="checkBox">
<property name="text">
<string>防锯齿string>
property>
<property name="btnType" stdset="0">
<number>0number>
property>
<attribute name="buttonGroup">
<string notr="true">otherGroupstring>
attribute>
widget>
item>
layout>
widget>
item>
layout>
item>
layout>
widget>
<widget class="QMenuBar" name="menuBar">
<property name="geometry">
<rect>
<x>0x>
<y>0y>
<width>625width>
<height>23height>
rect>
property>
widget>
<widget class="QToolBar" name="mainToolBar">
<attribute name="toolBarArea">
<enum>TopToolBarAreaenum>
attribute>
<attribute name="toolBarBreak">
<bool>falsebool>
attribute>
widget>
<widget class="QStatusBar" name="statusBar"/>
widget>
<layoutdefault spacing="6" margin="11"/>
<resources/>
<connections/>
<buttongroups>
<buttongroup name="animationGroup"/>
<buttongroup name="legendGroup"/>
<buttongroup name="otherGroup"/>
buttongroups>
ui>
#include "CChartTest.h"
#include
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
CChartTest w;
w.show();
return a.exec();
}
本文功能不算完整,理论上说各个图表的选项独立,不是通用的更好(就是说每次点击按钮只改变当前图表的属性),有兴趣的伙伴可以优化此功能,其实除了本文的功能只是皮毛,QChart还有许多神奇操作,学无止境,就一起去发掘吧。
终于把这文章写完了,足足拖了我两周,最近实在是没时间,也太忙了,每天下了班根本不想敲代码,只想躺平,然后就拖到了现在。
最后给自己也给大家说“不做思想上的巨人行动上的矮子”,那就休息了,晚安。
Qt之QtDataVisualization各三维图表的简单使用(含源码+注释)
友情提示——哪里看不懂可私哦,让我们一起互相进步吧
(创作不易,请留下一个免费的赞叭 谢谢 ^o^/)
注:文章为作者编程过程中所遇到的问题和总结,内容仅供参考,若有错误欢迎指出。
注:如有侵权,请联系作者删除