Qt 是一个跨平台C++图形界面开发库,利用Qt可以快速开发跨平台窗体应用程序,在Qt中我们可以通过拖拽的方式将不同组件放到指定的位置,实现图形化开发极大的方便了开发效率,本章将重点介绍TreeWidget
与QCharts
的常用方法及灵活运用。
在之前的文章中笔者介绍了如何使用QCharts
模块来绘制简单的折线图并对通用API接口进行了概括,本章我们通过在TreeWidget
组件中提取数据,并依次实现柱状图、饼状图、堆叠图、百分比图、散点图等。
柱状图(Bar Chart)用于显示各类别之间的数量关系。它通过在一个坐标系中绘制垂直的矩形条(柱)来表示数据。每个柱的高度表示相应类别的数量或数值,柱的宽度一般是固定的,类别之间的间隔可以根据需要调整。
柱状图主要用于比较不同类别的数值或数量,帮助观察数据的分布趋势、对比不同类别的数据大小,以及发现数据之间的关系。柱状图通常在横轴上表示不同的类别,纵轴上表示数量或数值。
以下是柱状图的一些主要特点:
柱状图是数据可视化中常用的工具之一,易于理解且能够直观地传达信息。在业务、科学研究、金融等领域,柱状图被广泛用于展示数据的分布和趋势。在Qt
中柱状图的绘制离不开三个类的支持,其分别是QBarSet
、QBarSeries
、QBarCategoryAxis
这三个类提供了用于操作和管理条形图数据集的方法。
QBarSet
类主要用于创建或表示一个柱状图的集合元素。以下是关于QBarSet
的主要方法的说明和概述,以表格形式呈现:
方法 | 描述 |
---|---|
QBarSet(const QString &label = QString()) |
构造函数,创建一个空的 QBarSet 对象,可以通过提供标签进行初始化。 |
void append(qreal value) |
将一个值添加到数据集的末尾。 |
void append(const QList<qreal> &values) |
将一组值添加到数据集的末尾。 |
void replace(int index, qreal value) |
替换数据集中指定索引位置的值。 |
void replace(const QList<qreal> &values) |
用提供的一组值替换整个数据集。 |
void clear() |
清除数据集中的所有值。 |
int count() const |
返回数据集中值的数量。 |
bool isEmpty() const |
检查数据集是否为空。 |
QString label() const |
返回数据集的标签。 |
void setLabel(const QString &label) |
设置数据集的标签。 |
qreal at(int index) const |
返回数据集中指定索引位置的值。 |
QList<qreal> values() const |
返回包含数据集所有值的列表。 |
QBarSeries
用于表示条形图数据系列。以下是 QBarSeries
类的一些主要方法和概述:
方法 | 描述 |
---|---|
QBarSeries(QObject *parent = nullptr) |
构造函数,创建一个空的 QBarSeries 对象。 |
void append(QBarSet *set) |
将一个 QBarSet 对象添加到系列的末尾。 |
void append(const QList<QBarSet*> &sets) |
将一组 QBarSet 对象添加到系列的末尾。 |
void replace(int index, QBarSet *set) |
替换系列中指定索引位置的 QBarSet 对象。 |
void replace(const QList<QBarSet*> &sets) |
用提供的一组 QBarSet 对象替换整个系列。 |
void remove(int index) |
移除系列中指定索引位置的 QBarSet 对象。 |
void clear() |
清除系列中的所有 QBarSet 对象。 |
int count() const |
返回系列中 QBarSet 对象的数量。 |
bool isEmpty() const |
检查系列是否为空。 |
QBarSet* at(int index) const |
返回系列中指定索引位置的 QBarSet 对象。 |
QList<QBarSet*> barSets() const |
返回包含系列所有 QBarSet 对象的列表。 |
QBarCategoryAxis
表示条形图横坐标,用于管理和显示条形图中的分类轴,其中每个条形图都属于特定的类别。以下是 QBarCategoryAxis
类的一些主要方法和概述:
方法 | 描述 |
---|---|
QBarCategoryAxis(QObject *parent = nullptr) |
构造函数,创建一个空的 QBarCategoryAxis 对象。 |
void append(const QStringList &categories) |
将一组类别添加到轴的末尾。 |
void append(const QString &category) |
将一个类别添加到轴的末尾。 |
void insert(int index, const QString &category) |
在指定索引位置插入一个类别。 |
void insert(int index, const QStringList &categories) |
在指定索引位置插入一组类别。 |
void remove(const QString &category) |
移除指定的类别。 |
void remove(int index, int count = 1) |
从指定索引位置开始移除指定数量的类别。 |
void clear() |
清除轴中的所有类别。 |
int count() const |
返回轴中类别的数量。 |
QString categoryAt(int index) const |
返回轴中指定索引位置的类别。 |
QStringList categories() const |
返回包含轴所有类别的列表。 |
void setCategories(const QStringList &categories) |
设置轴的类别。 |
void setStartValue(qreal value) |
设置轴的起始值。 |
qreal startValue() const |
返回轴的起始值。 |
void setRange(qreal min, qreal max) |
设置轴的范围。 |
void append(const QVector<QPointF> &points) |
将一组点添加到轴的末尾,用于自动设置类别。 |
void replace(const QVector<QPointF> &points) |
用提供的一组点替换整个轴,用于自动设置类别。 |
如下代码是使用 Qt 的图表模块创建一个包含柱状图和折线图的图表,并显示在 QGraphicsView
控件中,在MainWindow::MainWindow
构造函数中我们可以使用如下代码实现柱状图的创建。
图表初始化:创建一个 QChart
对象,并设置图表的标题和动画效果。然后将图表设置给 ui->graphicsView
控件,同时启用抗锯齿渲染。
QChart *chart = new QChart(); chart->setTitle("柱状图统计"); chart->setAnimationOptions(QChart::SeriesAnimations); // 为graphicsView设置chart ui->graphicsView->setChart(chart); ui->graphicsView->setRenderHint(QPainter::Antialiasing); // 构造柱状图 chart =ui->graphicsView->chart(); chart->removeAllSeries(); // 删除所有序列 chart->removeAxis(chart->axisX()); // 删除坐标轴 chart->removeAxis(chart->axisY()); // 删除坐标轴
创建数据集:构造三个 QBarSet
对象,分别表示数学、语文、英语的数据集。同时创建一个 QLineSeries
对象,表示平均分数据集,并设置线条的颜色和宽度。
QBarSet *setMath = new QBarSet(theModel->horizontalHeaderItem(1)->text()); // 数学字段 QBarSet *setChinese = new QBarSet(theModel->horizontalHeaderItem(2)->text()); // 语文字段 QBarSet *setEnglish= new QBarSet(theModel->horizontalHeaderItem(3)->text()); // 英语字段 // 创建折线线条 QLineSeries *Line = new QLineSeries(); Line->setName(theModel->horizontalHeaderItem(4)->text()); // 表示平均分 QPen pen; pen.setColor(Qt::red); // 使用红色 pen.setWidth(2); // 设置宽度 Line->setPen(pen); // 绘制
添加数据:遍历前10个数据行,将数学、语文、英语的成绩和平均分添加到相应的数据集中。
for(int i=0;i< 10;i++) { // 从数据模型获取数据 setMath->append(theModel->item(i,1)->text().toInt()); // 数学 setChinese->append(theModel->item(i,2)->text().toInt()); // 语文 setEnglish->append(theModel->item(i,3)->text().toInt()); // 英语 Line->append(QPointF(i,theModel->item(i,4)->text().toFloat())); // 平均分 }
创建柱状图序列:使用 QBarSeries
创建一个柱状图序列,并将三个数据集添加到序列中。同时,将折线图序列也添加到图表中。
cppCopy codeQBarSeries *series = new QBarSeries(); series->append(setMath); series->append(setChinese); series->append(setEnglish); chart->addSeries(series); chart->addSeries(Line);
设置坐标轴:创建横坐标轴 axisX
和纵坐标轴 axisY
,设置它们的范围、标签等信息,然后将它们与相应的序列关联。
// 创建柱状图序列 QBarSeries 并添加三个数据集 QBarSeries *series = new QBarSeries(); series->append(setMath); series->append(setChinese); series->append(setEnglish); chart->addSeries(series); // 添加柱状图序列 chart->addSeries(Line); // 添加折线图序列 // 用于横坐标在字符串列表 即UID QStringList categories; for (int i=0;i<10;i++) { categories <<theModel->item(i,0)->text(); } // 柱状图的坐标轴 QBarCategoryAxis *axisX = new QBarCategoryAxis(); axisX->append(categories); // 添加横坐标文字列表 chart->setAxisX(axisX, series); // 设置横坐标 chart->setAxisX(axisX, Line); // 设置横坐标 // 设置坐标范围 axisX->setRange(categories.at(0), categories.at(categories.count()-1)); // 数值型坐标作为纵轴 QValueAxis *axisY = new QValueAxis; axisY->setRange(0, 100); axisY->setTitleText("分数"); axisY->setTickCount(6); axisY->setLabelFormat("%.0f");
图例显示设置:显示图例,并设置图例在底部对齐。
chart->setAxisY(axisY, series); chart->setAxisY(axisY, Line); chart->legend()->setVisible(true); chart->legend()->setAlignment(Qt::AlignBottom);
这样,你就创建了一个包含柱状图和折线图的图表,并将其显示在 QGraphicsView
控件中,运行后则可以得到如下图所示的图例;
饼状图(Pie Chart)用于展示各部分占整体的比例关系。它通过在一个圆形区域内绘制扇形来表示数据的相对大小。整个圆表示总体,而每个扇形的弧长(或面积)表示相应类别的数量或比例。
饼状图的主要特点包括:
饼状图常见的应用场景包括市场份额分析、调查结果的占比展示、资源分配比例等。然而,有时候,为了更好地表达数据,也会使用改进版的饼状图,如环形图(Donut Chart)等。
QPieSeries
是 Qt Charts 模块中用于绘制饼状图的数据序列类。它派生自 QAbstractSeries
类,用于管理和展示饼状图中的数据。以下是 QPieSeries
类的一些常用方法和属性,以表格形式概述:
方法 | 描述 |
---|---|
QPieSeries(QObject *parent = nullptr) |
构造函数,创建一个 QPieSeries 对象。 |
~QPieSeries() |
析构函数,释放 QPieSeries 对象。 |
append(QPieSlice *slice) |
向饼状图序列中追加一个饼块。 |
insert(int index, QPieSlice *slice) |
在指定位置插入一个饼块。 |
remove(QPieSlice *slice) |
从饼状图序列中移除指定的饼块。 |
clear() |
清除饼状图序列中的所有饼块。 |
slices() |
返回饼状图序列中的所有饼块。 |
count() |
返回饼状图序列中的饼块数量。 |
at(int index) |
返回饼状图序列中指定索引位置的饼块。 |
setVisible(bool visible) |
设置饼状图序列的可见性。 |
isVisible() |
返回饼状图序列的可见性。 |
setHoleSize(double size) |
设置饼状图中间空心的大小,范围为 [0.0, 1.0],0.0 表示没有空心,1.0 表示整个饼状图都是空心。 |
holeSize() |
返回饼状图中间空心的大小。 |
setPieSize(double size) |
设置饼状图的大小,范围为 [0.0, 1.0],默认为 1.0。 |
pieSize() |
返回饼状图的大小。 |
setLabelsVisible(bool visible) |
设置饼块的标签是否可见。 |
labelsVisible() |
返回饼块的标签是否可见。 |
setLabelsPosition(QPieSlice::LabelPosition position) |
设置饼块标签的位置。 |
labelsPosition() |
返回饼块标签的位置。 |
setLabelsPrecision(int precision) |
设置饼块标签显示的小数位数。 |
labelsPrecision() |
返回饼块标签显示的小数位数。 |
clicked(QPieSlice *slice) |
点击饼块时发出的信号,参数为被点击的饼块。 |
hovered(QPieSlice *slice, bool state) |
鼠标悬停在饼块上时发出的信号,参数为被悬停的饼块和悬停状态。 |
pressed(QPieSlice *slice) |
鼠标按下饼块时发出的信号,参数为被按下的饼块。 |
released(QPieSlice *slice) |
鼠标释放饼块时发出的信号,参数为被释放的饼块。 |
QPieSlice
是 Qt Charts 模块中用于表示饼状图中的单个饼块的类。每个 QPieSlice
对象都代表饼状图中的一个数据分块。
以下是关于 QPieSlice
的一些方法以及说明:
方法 | 描述 |
---|---|
QPieSlice(qreal value, QString label) |
构造函数,创建一个带有给定值和标签的 QPieSlice 对象。 |
~QPieSlice() |
析构函数,释放 QPieSlice 对象。 |
setLabel(QString label) |
设置饼块的标签文字。 |
label() |
返回饼块的标签文字。 |
setValue(qreal value) |
设置饼块的值。 |
value() |
返回饼块的值。 |
setExploded(bool exploded) |
设置饼块是否为爆炸状态,即是否与饼图分离。 |
isExploded() |
返回饼块是否为爆炸状态。 |
setPieSeries(QPieSeries *series) |
设置饼块所属的 QPieSeries 对象。 |
pieSeries() |
返回饼块所属的 QPieSeries 对象。 |
setBrush(const QBrush &brush) |
设置饼块的画刷,即填充颜色。 |
brush() |
返回饼块的画刷。 |
setLabelBrush(const QBrush &brush) |
设置饼块标签的画刷,即标签的颜色。 |
labelBrush() |
返回饼块标签的画刷。 |
setPen(const QPen &pen) |
设置饼块的画笔,即边框颜色和样式。 |
pen() |
返回饼块的画笔。 |
setLabelVisible(bool visible) |
设置饼块标签是否可见。 |
isLabelVisible() |
返回饼块标签是否可见。 |
setExplodeDistanceFactor(qreal factor) |
设置饼块爆炸时的距离因子,即与饼图分离的距离。 |
explodeDistanceFactor() |
返回饼块爆炸时的距离因子。 |
setPercentage(qreal percentage) |
设置饼块的百分比值。 |
percentage() |
返回饼块的百分比值。 |
clicked(bool state) |
鼠标点击饼块时发出的信号,参数为鼠标点击的状态(按下或释放)。 |
hovered(bool state) |
鼠标悬停在饼块上时发出的信号,参数为悬停状态。 |
pressed() |
鼠标按下饼块时发出的信号。 |
released() |
鼠标释放饼块时发出的信号。 |
QPieSlice
主要用于配置和管理饼状图中的单个数据分块,包括设置饼块的标签、值、颜色、样式等属性。
饼状图的绘制流程与柱状图一样,主要以下几个步骤:
饼图初始化: 创建一个QChart
对象,并设置其动画选项。然后将该图表对象设置为QGraphicsView
的图表,并启用反锯齿渲染。
// 饼图初始化 QChart *chart = new QChart(); chart->setAnimationOptions(QChart::SeriesAnimations); ui->graphicsView->setChart(chart); ui->graphicsView->setRenderHint(QPainter::Antialiasing); // 绘制饼图 chart->removeAllSeries();
创建饼图序列:为图表创建一个新的饼图序列(QPieSeries
),并通过循环的方式向序列中添加成绩。
// 创建饼图序列 QPieSeries *series = new QPieSeries(); // 饼图中间空心的大小 series->setHoleSize(0.30); // 添加分块数据 for (int i=0;i<=4;i++) { // 获得QTreeWidgetItem的item QTreeWidgetItem* item=ui->treeWidget->topLevelItem(i); // 获取分析对象,数学、英语、语文或平均分,添加一个饼图分块数据,标签,数值 series->append(item->text(0),item->text(1).toFloat()); }
添加分块数据到饼图: 从QTreeWidget
中获取每个分析对象(数学、英语、语文或平均分),并将其添加到饼图序列中。
// 饼图分块 QPieSlice *slice; // 设置每个分块的标签文字 for(int i=0;i<=4;i++) { // 获取分块 slice =series->slices().at(i); // 设置分块的标签 slice->setLabel(slice->label()+QString::asprintf(": %.0f人, %.1f%%", slice->value(),slice->percentage()*100)); // 信号与槽函数关联,鼠标落在某个分块上时,此分块弹出 connect(slice, SIGNAL(hovered(bool)),this, SLOT(on_PieSliceHighlight(bool))); } slice->setExploded(true); // 最后一个设置为exploded series->setLabelsVisible(true); // 只影响当前的slices,必须添加完slice之后再设置 chart->addSeries(series); // 添加饼图序列 chart->legend()->setVisible(true); // 图例 chart->legend()->setAlignment(Qt::AlignRight);
设置饼图分块的标签和槽函数关联: 对于每个分块,设置其标签文字,包括数值和百分比,并关联鼠标悬停事件的槽函数。
// 鼠标移入移出时触发hovered信号 void MainWindow::on_PieSliceHighlight(bool show) { QPieSlice *slice; slice=(QPieSlice *)sender(); // 动态设置setExploded效果 // slice->setLabelVisible(show); slice->setExploded(show); }
上述代码流程实现了在Qt中使用QPieSeries
和QPieSlice
绘制饼状图的功能,包括图表的初始化、数据的设置、分块标签的添加、饼图分块的突出显示等。在图表中,每个分块代表一种分析对象,标签包含人数和百分比信息,运行后输出如下效果;
堆叠图(Stacked Chart)用于展示多个数据系列的累积效果,即将不同系列的数据在同一数值点上进行堆叠显示。这种图表形式旨在突出整体的趋势以及各组成部分的相对贡献。
堆叠图有多种形式,其中两种常见的类型包括:
堆叠图的优势在于能够直观地显示各部分在整体中的相对比例,并清晰地展示随时间或其他维度的变化。这种图表类型通常用于比较多个系列的总体趋势,并强调各个系列之间的相对贡献。在堆叠图中,每个系列的数值贡献会在相同的数值点上叠加显示,使得读者能够更容易比较各系列的相对大小。
堆叠图的创建需要用到QStackedBarSeries
和QBarCategoryAxis
类,QStackedBarSeries
是 Qt Charts 模块中用于创建堆叠柱状图的类。堆叠柱状图显示多个柱状系列的堆叠效果,每个柱状系列由一个或多个柱状条组成,这些柱状条按照数据堆叠在一起,形成整体的柱状图。
以下是 QStackedBarSeries
的一些重要方法和属性:
方法 | 描述 |
---|---|
QStackedBarSeries(QObject *parent = nullptr) |
构造函数,创建一个 QStackedBarSeries 对象。 |
void append(QBarSet *set) |
将一个 QBarSet 添加到序列中。 |
void append(QList<QBarSet *> sets) |
将一组 QBarSet 添加到序列中。 |
QList<QBarSet *> barSets() const |
返回序列中的所有 QBarSet 。 |
void setLabelsVisible(bool visible) |
设置是否显示柱状图的标签。 |
bool labelsVisible() const |
返回柱状图的标签可见性。 |
void setLabelsFormat(const QString &format) |
设置标签的显示格式。 |
QString labelsFormat() const |
返回标签的显示格式。 |
void setLabelsPosition(QAbstractBarSeries::LabelsPosition position) |
设置标签的位置。 |
QAbstractBarSeries::LabelsPosition labelsPosition() const |
返回标签的位置。 |
QStackedBarSeries
通过添加不同的 QBarSet
对象来创建堆叠效果。每个 QBarSet
对象代表一个柱状系列,它包含了一组柱状条的数据。标签、颜色和其他样式属性可以通过 QBarSet
进行定制。使用这些方法和属性,可以方便地控制堆叠柱状图的外观和行为,如下代码则是堆叠图创建的实现;
// 初始化叠加柱状图绘制窗口 QChart *chart = new QChart(); chart->setAnimationOptions(QChart::SeriesAnimations); ui->graphicsView->setChart(chart); ui->graphicsView->setRenderHint(QPainter::Antialiasing); // 绘制叠加柱状图 chart->removeAllSeries(); chart->removeAxis(chart->axisX()); chart->removeAxis(chart->axisY()); // 创建三门课程的数据集 QBarSet *setMath = new QBarSet(theModel->horizontalHeaderItem(1)->text()); QBarSet *setChinese = new QBarSet(theModel->horizontalHeaderItem(2)->text()); QBarSet *setEnglish= new QBarSet(theModel->horizontalHeaderItem(3)->text()); // 添加前十个分数数据到数据集 for(int i=0;i<20;i++) { setMath->append(theModel->item(i,1)->text().toInt()); setChinese->append(theModel->item(i,2)->text().toInt()); setEnglish->append(theModel->item(i,3)->text().toInt()); } // 创建QStackedBarSeries对象并添加数据集 QStackedBarSeries *series = new QStackedBarSeries(); series->append(setMath); series->append(setChinese); series->append(setEnglish); series->setLabelsVisible(true); // 添加序列到图表 chart->addSeries(series); QStringList categories; // 绘制前十个数据 for (int i=0;i<10;i++) { categories <<theModel->item(i,0)->text(); } // 类别坐标轴 作为横轴 QBarCategoryAxis *axisX = new QBarCategoryAxis(); axisX->append(categories); chart->setAxisX(axisX, series); axisX->setRange(categories.at(0), categories.at(categories.count()-1)); // 数值坐标轴 作为纵轴 QValueAxis *axisY = new QValueAxis; axisY->setRange(0, 300); axisY->setTitleText("总分"); axisY->setTickCount(6); axisY->setLabelFormat("%.0f"); chart->setAxisY(axisY, series); // 设置图表属性 chart->legend()->setVisible(true); chart->legend()->setAlignment(Qt::AlignBottom);
运行后,通过QBarSet
保存课程数据集,最后增加横轴纵轴区间,当数据被加载后,图表则会输出如下所示的数据集;
百分比图(Percentage Chart)用于显示各部分占整体的百分比关系的图表。这种图表通过以百分比形式展示每个部分在总体中所占比例,提供了一种直观的方式来比较不同部分的相对大小。
百分比图有多种形式,其中一些常见的类型包括:
这些图表形式在不同情境下用于展示数据的占比关系,特别适用于需要强调相对比例的场景。百分比图通常能够帮助观众更容易地理解各部分在整体中的贡献,是一种有力的数据可视化工具。
使用百分比图时,注意确保数据的总和为100%。百分比图在市场份额分析、调查结果的占比展示、资源分配比例等方面得到广泛应用。
QPercentBarSeries
是 Qt Charts 模块中用于绘制百分比柱状图的类。它派生自 QAbstractBarSeries
类,表示一个二维坐标系中的数据系列,其中的数据以百分比柱状图的形式呈现。
以下是关于 QPercentBarSeries
的一些方法以及说明:
方法 | 描述 |
---|---|
QPercentBarSeries() |
构造函数,创建一个 QPercentBarSeries 对象。 |
~QPercentBarSeries() |
析构函数,释放 QPercentBarSeries 对象。 |
setLabelsVisible(bool) |
设置百分比柱状图上的数据标签是否可见。 |
labelsVisible() |
返回百分比柱状图上的数据标签是否可见的状态。 |
setLabelsPosition(Position) |
设置百分比柱状图上的数据标签位置,Position 是一个枚举类型,表示标签的位置,如上方、下方、内部等。 |
labelsPosition() |
返回百分比柱状图上的数据标签位置。 |
setLabelsFormat(QString) |
设置百分比柱状图上的数据标签的格式,使用字符串指定标签的显示格式。 |
labelsFormat() |
返回百分比柱状图上的数据标签的显示格式。 |
setPercentageVisible(bool) |
设置百分比柱状图上的百分比标签是否可见。 |
percentageVisible() |
返回百分比柱状图上的百分比标签是否可见的状态。 |
setStackingGap(qreal) |
设置百分比柱状图中堆叠的百分比柱之间的间隙。 |
stackingGap() |
返回百分比柱状图中堆叠的百分比柱之间的间隙。 |
append(QBarSet*) |
在百分比柱状图中追加一个数据集。 |
insert(int, QBarSet*) |
在百分比柱状图中插入一个数据集,参数为位置索引和 QBarSet 对象。 |
remove(QBarSet*) |
从百分比柱状图中移除指定的数据集。 |
take(int) |
从百分比柱状图中移除并返回指定位置的数据集。 |
take(QBarSet*) |
从百分比柱状图中移除指定的数据集并返回。 |
count() |
返回百分比柱状图中数据集的数量。 |
barSets() |
返回百分比柱状图中所有数据集的列表。 |
barWidth() |
返回百分比柱状图中百分比柱的宽度。 |
barWidthChanged(qreal) |
当百分比柱状图中百分比柱的宽度发生变化时发出的信号,参数为新的宽度值。 |
QPercentBarSeries
类主要用于在图表中绘制百分比柱状图,其中的数据集可以包含多个柱子,每个柱子表示一个百分比。
// 百分比柱状图初始化 QChart *chart = new QChart(); chart->setAnimationOptions(QChart::SeriesAnimations); ui->graphicsView->setChart(chart); ui->graphicsView->setRenderHint(QPainter::Antialiasing); // 绘制百分比柱状图 chart->removeAllSeries(); chart->removeAxis(chart->axisX()); chart->removeAxis(chart->axisY()); // 创建数据集 QBarSet *setMath = new QBarSet(theModel->horizontalHeaderItem(1)->text()); QBarSet *setChinese = new QBarSet(theModel->horizontalHeaderItem(2)->text()); QBarSet *setEnglish= new QBarSet(theModel->horizontalHeaderItem(3)->text()); QTreeWidgetItem *item; QStringList categories; for (int i=0;i<=4;i++) { // 从分数段统计数据表里获取数据添加到数据集 item=ui->treeWidget->topLevelItem(i); // 横坐标的标签 categories<<item->text(0); // 添加数据到QBarSet中 setMath->append(item->text(1).toFloat()); setChinese->append(item->text(2).toFloat()); setEnglish->append(item->text(3).toFloat()); } // 添加序列 QPercentBarSeries *series = new QPercentBarSeries(); series->append(setMath); series->append(setChinese); series->append(setEnglish); series->setLabelsVisible(true); series->setLabelsFormat("@value人"); chart->addSeries(series); // 添加横坐标 QBarCategoryAxis *axisX = new QBarCategoryAxis(); axisX->append(categories); chart->setAxisX(axisX, series); axisX->setRange(categories.at(0), categories.at(categories.count()-1)); // 添加纵坐标 QValueAxis *axisY = new QValueAxis; axisY->setRange(0, 100); axisY->setTitleText("百分比"); axisY->setTickCount(6); axisY->setLabelFormat("%.1f"); chart->setAxisY(axisY, series); // 设置属性 chart->legend()->setVisible(true); chart->legend()->setAlignment(Qt::AlignRight);
运行后则可输出不同分数段每一门成绩的百分比分布情况,如下图所示;
散点图(Scatter Plot)是一种二维图表,用于显示两个变量之间的关系。散点图的每个数据点由两个数值组成,分别对应于图表的横轴和纵轴。通过在图表中绘制这些点,可以观察和分析变量之间的关联性、趋势、聚集程度等。
散点图的特点包括:
散点图的应用场景非常广泛,常见的用途包括:
总体而言,散点图是一种简单而强大的工具,可用于初步探索和理解两个变量之间的关系。
QSplineSeries
是 Qt Charts 模块中用于绘制光滑曲线的类。它表示图表中的一条曲线,通过一系列的数据点来定义曲线的形状。
以下是关于 QSplineSeries
的一些方法以及说明:
方法 | 描述 |
---|---|
QSplineSeries(QObject *parent = nullptr) |
构造函数,创建一个 QSplineSeries 对象。 |
~QSplineSeries() |
析构函数,释放 QSplineSeries 对象。 |
append(QPointF point) |
向曲线中追加一个数据点。 |
append(QList<QPointF> points) |
向曲线中追加一组数据点。 |
replace(int index, QPointF point) |
替换指定索引处的数据点。 |
replace(QList<QPointF> points) |
替换曲线中的所有数据点。 |
remove(int index) |
移除指定索引处的数据点。 |
remove(int index, int count) |
移除从指定索引开始的指定数量的数据点。 |
clear() |
清空曲线中的所有数据点。 |
pointsVector() |
返回曲线的数据点。 |
setUseOpenGL(bool enable) |
设置是否使用 OpenGL 进行绘制。 |
useOpenGL() |
返回是否使用 OpenGL 进行绘制。 |
setPen(const QPen &pen) |
设置曲线的画笔,即曲线的颜色和样式。 |
pen() |
返回曲线的画笔。 |
setBrush(const QBrush &brush) |
设置曲线的画刷,即填充颜色。 |
brush() |
返回曲线的画刷。 |
setPointLabelsVisible(bool visible) |
设置是否显示数据点的标签。 |
isPointLabelsVisible() |
返回数据点的标签是否可见。 |
setPointLabelsFormat(const QString &format) |
设置数据点标签的显示格式,支持使用占位符。 |
pointLabelsFormat() |
返回数据点标签的显示格式。 |
setPointLabelsColor(const QColor &color) |
设置数据点标签的颜色。 |
pointLabelsColor() |
返回数据点标签的颜色。 |
setPointLabelsFont(const QFont &font) |
设置数据点标签的字体。 |
pointLabelsFont() |
返回数据点标签的字体。 |
setPointsVisible(bool visible) |
设置是否显示数据点。 |
arePointsVisible() |
返回数据点是否可见。 |
setPointLabelsClipping(bool clipping) |
设置是否裁剪超出绘图区域的数据点标签。 |
isPointLabelsClipping() |
返回数据点标签是否裁剪超出绘图区域。 |
clicked(QPointF point) |
鼠标点击曲线时发出的信号,参数为鼠标点击的数据点坐标。 |
hovered(QPointF point, bool state) |
鼠标悬停在曲线上时发出的信号,参数为悬停状态以及悬停位置的数据点坐标。 |
pressed(QPointF point) |
鼠标按下曲线时发出的信号,参数为鼠标按下的数据点坐标。 |
released(QPointF point) |
鼠标释放曲线时发出的信号,参数为鼠标释放的数据点坐标。 |
doubleClicked(QPointF point) |
鼠标双击曲线时发出的信号,参数为鼠标双击的数据点坐标。 |
QSplineSeries
主要用于绘制光滑曲线,通过添加一系列的数据点,可以在图表中呈现出相应的曲线形状。
QScatterSeries
是 Qt Charts 模块中用于绘制散点图的类。它派生自 QXYSeries
类,用于表示图表中的一组散点数据,通过一系列的坐标点来显示离散的数据分布。
以下是关于 QScatterSeries
的一些方法以及说明:
方法 | 说明 |
---|---|
QScatterSeries(QObject *parent = nullptr) |
构造函数,创建一个 QScatterSeries 对象。 |
~QScatterSeries() |
析构函数,释放 QScatterSeries 对象。 |
append(QPointF point) |
向散点图中追加一个数据点。 |
append(QList<QPointF> points) |
向散点图中追加一组数据点。 |
replace(int index, QPointF point) |
替换指定索引处的数据点。 |
replace(QList<QPointF> points) |
替换散点图中的所有数据点。 |
remove(int index) |
移除指定索引处的数据点。 |
remove(int index, int count) |
移除从指定索引开始的指定数量的数据点。 |
clear() |
清空散点图中的所有数据点。 |
pointsVector() |
返回散点图的数据点。 |
setMarkerShape(QScatterSeries::MarkerShape shape) |
设置散点的形状,可以是圆形、方形等。 |
markerShape() |
返回散点的形状。 |
setMarkerSize(qreal size) |
设置散点的大小。 |
markerSize() |
返回散点的大小。 |
setPen(const QPen &pen) |
设置散点图的画笔,即散点的边框颜色和样式。 |
pen() |
返回散点图的画笔。 |
setBrush(const QBrush &brush) |
设置散点图的画刷,即散点的填充颜色。 |
brush() |
返回散点图的画刷。 |
setBorderColor(const QColor &color) |
设置散点的边框颜色。 |
borderColor() |
返回散点的边框颜色。 |
setBackgroundColor(const QColor &color) |
设置散点的背景颜色。 |
backgroundColor() |
返回散点的背景颜色。 |
setBorderColor(const QColor &color) |
设置散点的边框颜色。 |
borderColor() |
返回散点的边框颜色。 |
setBrush(const QBrush &brush) |
设置散点的画刷,即填充颜色。 |
brush() |
返回散点的画刷。 |
setPen(const QPen &pen) |
设置散点的画笔,即边框颜色和样式。 |
pen() |
返回散点的画笔。 |
setUseOpenGL(bool enable) |
设置是否使用 OpenGL 进行绘制。 |
useOpenGL() |
返回是否使用 OpenGL 进行绘制。 |
setMarkerShape(QScatterSeries::MarkerShape shape) |
设置散点的形状,可以是圆形、方形等。 |
markerShape() |
返回散点的形状。 |
setMarkerSize(qreal size) |
设置散点的大小。 |
markerSize() |
返回散点的大小。 |
setMarkerColor(const QColor &color) |
设置散点的颜色。 |
markerColor() |
返回散点的颜色。 |
clicked(QPointF point) |
鼠标点击散点时发出的信号,参数为鼠标点击的数据点坐标。 |
hovered(QPointF point, bool state) |
鼠标悬停在散点上时发出的信 |
绘制散点图实现代码如下所示;
// 散点图初始化 QChart *chart = new QChart(); chart->setAnimationOptions(QChart::SeriesAnimations); ui->graphicsView->setChart(chart); ui->graphicsView->setRenderHint(QPainter::Antialiasing); // 清空绘图区 chart->removeAllSeries(); chart->removeAxis(chart->axisX()); chart->removeAxis(chart->axisY()); // 光滑曲线序列 QSplineSeries *seriesLine = new QSplineSeries(); seriesLine->setName("曲线"); QPen pen; pen.setColor(Qt::blue); pen.setWidth(2); seriesLine->setColor(Qt::blue); seriesLine->setPen(pen); // 散点序列 QScatterSeries *series0 = new QScatterSeries(); series0->setName("散点"); series0->setMarkerShape(QScatterSeries::MarkerShapeCircle); series0->setBorderColor(Qt::black); series0->setBrush(QBrush(Qt::red)); series0->setMarkerSize(12); // 随机数种子 qsrand(QTime::currentTime().second()); // 设置曲线随机数 for (int i=0;i<10;i++) { int x=(qrand() % 20); // 0到20之间的随机数 int y=(qrand() % 20); series0->append(x,y); // 散点序列 seriesLine->append(x,y); // 光滑曲线序列 } chart->addSeries(series0); chart->addSeries(seriesLine); // 增加Y坐标轴(可注释) QValueAxis *axisY = new QValueAxis; axisY->setRange(0, 20); axisY->setTitleText("Y坐标"); axisY->setTickCount(11); axisY->setLabelFormat("%.0f"); axisY->setGridLineVisible(true); chart->setAxisY(axisY, series0); chart->setAxisY(axisY, seriesLine); // 增加X坐标轴(可注释) QValueAxis *axisX = new QValueAxis; axisX->setRange(0, 20); axisX->setTitleText("X"); axisX->setTickCount(11); axisX->setLabelFormat("%.0f"); axisX->setGridLineVisible(true); chart->setAxisX(axisX, series0); chart->setAxisX(axisX, seriesLine); // 创建缺省的坐标轴(默认缺省值) chart->createDefaultAxes(); chart->axisX()->setTitleText("X 轴"); chart->axisX()->setRange(-2,22); chart->axisY()->setTitleText("Y 轴"); chart->axisY()->setRange(-2,22); chart->legend()->setVisible(true); chart->legend()->setAlignment(Qt::AlignRight); // 绑定槽函数,用于点击图例显示与隐藏数据 foreach (QLegendMarker* marker, chart->legend()->markers()) { QObject::disconnect(marker, SIGNAL(clicked()), this, SLOT(on_chartBarLegendMarkerClicked())); QObject::connect(marker, SIGNAL(clicked()), this, SLOT(on_chartBarLegendMarkerClicked())); }
运行上述代码则可实现输出随机散点图,其中右侧散点与曲线可以进行自定义隐藏与显示,如下图所示;