以下是一个使用 Qt 实现图表交互操作的示例,涵盖了自定义图表视图类、不同类型的柱状图和饼图等内容。
实现思路
- 自定义图表视图类:创建一个从
QChartView
派生的自定义类,用于处理图表的交互操作。 - 主窗口设计初始化:在主窗口中使用
QVBoxLayout
或QHBoxLayout
等布局管理器放置自定义图表视图类。 - 数据准备:使用
QBarSet
和QBarSeries
准备柱状图的数据,使用QPieSeries
准备饼图的数据。 - 交互操作功能的实现:重写
mousePressEvent
或mouseMoveEvent
等事件处理函数,在自定义的图表视图类中实现交互操作。
代码示例
#include <QtWidgets/QApplication>
#include <QtWidgets/QMainWindow>
#include <QtCharts/QChartView>
#include <QtCharts/QBarSeries>
#include <QtCharts/QBarSet>
#include <QtCharts/QBarCategoryAxis>
#include <QtCharts/QValueAxis>
#include <QtCharts/QPieSeries>
#include <QtCharts/QPieSlice>
#include <QtCharts/QAbstractBarSeries>
#include <QtCharts/QStackedBarSeries>
#include <QtCharts/QPercentBarSeries>
#include <QtWidgets/QVBoxLayout>
#include <QtWidgets/QWidget>
#include <QtCore/QDebug>
QT_CHARTS_USE_NAMESPACE
// 自定义图表视图类
class TChartView : public QChartView {
public:
TChartView(QChart *chart, QWidget *parent = nullptr) : QChartView(chart, parent) {
setRenderHint(QPainter::Antialiasing);
}
protected:
void mousePressEvent(QMouseEvent *event) override {
qDebug() << "Mouse pressed at: " << event->pos();
QChartView::mousePressEvent(event);
}
void mouseMoveEvent(QMouseEvent *event) override {
qDebug() << "Mouse moved to: " << event->pos();
QChartView::mouseMoveEvent(event);
}
};
int main(int argc, char *argv[]) {
QApplication a(argc, argv);
// 创建主窗口
QMainWindow mainWindow;
QWidget *centralWidget = new QWidget(&mainWindow);
mainWindow.setCentralWidget(centralWidget);
QVBoxLayout *layout = new QVBoxLayout(centralWidget);
// 柱状图
QBarSet *set0 = new QBarSet("Bar Set 1");
*set0 << 1 << 2 << 3 << 4 << 5 << 6;
QBarSet *set1 = new QBarSet("Bar Set 2");
*set1 << 5 << 4 << 3 << 2 << 1 << 0;
QBarSeries *barSeries = new QBarSeries();
barSeries->append(set0);
barSeries->append(set1);
QChart *barChart = new QChart();
barChart->addSeries(barSeries);
barChart->setTitle("Bar Chart");
QStringList categories;
categories << "Jan" << "Feb" << "Mar" << "Apr" << "May" << "Jun";
QBarCategoryAxis *axisX = new QBarCategoryAxis();
axisX->append(categories);
barChart->addAxis(axisX, Qt::AlignBottom);
barSeries->attachAxis(axisX);
QValueAxis *axisY = new QValueAxis();
barChart->addAxis(axisY, Qt::AlignLeft);
barSeries->attachAxis(axisY);
TChartView *barChartView = new TChartView(barChart);
layout->addWidget(barChartView);
// 堆叠柱状图
QStackedBarSeries *stackedBarSeries = new QStackedBarSeries();
stackedBarSeries->append(set0);
stackedBarSeries->append(set1);
QChart *stackedBarChart = new QChart();
stackedBarChart->addSeries(stackedBarSeries);
stackedBarChart->setTitle("Stacked Bar Chart");
QBarCategoryAxis *stackedAxisX = new QBarCategoryAxis();
stackedAxisX->append(categories);
stackedBarChart->addAxis(stackedAxisX, Qt::AlignBottom);
stackedBarSeries->attachAxis(stackedAxisX);
QValueAxis *stackedAxisY = new QValueAxis();
stackedBarChart->addAxis(stackedAxisY, Qt::AlignLeft);
stackedBarSeries->attachAxis(stackedAxisY);
TChartView *stackedBarChartView = new TChartView(stackedBarChart);
layout->addWidget(stackedBarChartView);
// 百分比柱状图
QPercentBarSeries *percentBarSeries = new QPercentBarSeries();
percentBarSeries->append(set0);
percentBarSeries->append(set1);
QChart *percentBarChart = new QChart();
percentBarChart->addSeries(percentBarSeries);
percentBarChart->setTitle("Percent Bar Chart");
QBarCategoryAxis *percentAxisX = new QBarCategoryAxis();
percentAxisX->append(categories);
percentBarChart->addAxis(percentAxisX, Qt::AlignBottom);
percentBarSeries->attachAxis(percentAxisX);
QValueAxis *percentAxisY = new QValueAxis();
percentBarChart->addAxis(percentAxisY, Qt::AlignLeft);
percentBarSeries->attachAxis(percentAxisY);
TChartView *percentBarChartView = new TChartView(percentBarChart);
layout->addWidget(percentBarChartView);
// 饼图
QPieSeries *pieSeries = new QPieSeries();
pieSeries->append("Slice 1", 10);
pieSeries->append("Slice 2", 20);
pieSeries->append("Slice 3", 30);
QChart *pieChart = new QChart();
pieChart->addSeries(pieSeries);
pieChart->setTitle("Pie Chart");
TChartView *pieChartView = new TChartView(pieChart);
layout->addWidget(pieChartView);
mainWindow.show();
return a.exec();
}
代码解释
-
自定义图表视图类
TChartView
:- 继承自
QChartView
,在构造函数中设置抗锯齿渲染。 - 重写
mousePressEvent
和mouseMoveEvent
函数,用于输出鼠标按下和移动的位置信息,你可以根据需要扩展这些函数,实现更复杂的交互操作,如选择数据点、显示提示信息等。
- 继承自
-
主窗口设计初始化:
- 创建
QMainWindow
和QWidget
作为中央部件。 - 使用
QVBoxLayout
布局管理器来管理多个图表视图。
- 创建
-
柱状图:
- 创建
QBarSet
表示柱状图的数据集合。 - 使用
QBarSeries
将多个QBarSet
组合起来。 - 使用
QBarCategoryAxis
作为 x 轴,QValueAxis
作为 y 轴。 - 创建
QChart
并添加系列和坐标轴,然后使用TChartView
显示图表。
- 创建
-
堆叠柱状图和百分比柱状图:
- 与柱状图类似,但使用
QStackedBarSeries
和QPercentBarSeries
代替QBarSeries
以实现不同的显示效果。
- 与柱状图类似,但使用
-
饼图:
- 使用
QPieSeries
存储饼图的数据,每个QPieSlice
代表一个扇区,设置扇区的名称和大小。
- 使用
使用说明
- 复制上述代码到一个
.cpp
文件中,确保你已经正确配置了 Qt 开发环境,并且包含了必要的模块,如QtWidgets
和QtCharts
。 - 在
.pro
文件中添加以下内容:
QT += charts widgets
CONFIG += c++11
- 编译并运行程序,你将看到一个包含柱状图、堆叠柱状图、百分比柱状图和饼图的窗口,并且可以在控制台中看到鼠标的交互信息。