在条形图中使用数据模型

注意:这是 “带小部件的图表图库”示例的一部分。

显示行数据如何转换为柱状图的截图

首先,我们创建一个 CustomTableModel 类的实例。CustomTableModel 类继承自QAbstractTableModel ,是专为本示例而创建的。该类的构造函数会将图表示例所需的数据填充到模型的内部数据存储中。

auto model = new BarModelMapperModel(this);

现在,我们有一个包含数据的模型,希望将这些数据同时显示在图表和QTableView 中。首先,我们创建QTableView ,并指定其使用该模型作为数据源。为了美观地呈现数据,我们设置了表格视图的最小宽度,并将标题栏的调整大小模式改为“拉伸”。

// create table view and add model to it
auto tableView = new QTableView(this);
tableView->setModel(model);
tableView->setMinimumWidth(300);
tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
tableView->verticalHeader()->setSectionResizeMode(QHeaderView::Stretch);
model->setParent(tableView);

现在,我们需要一个 QChart 实例来在图表上显示相同的数据。同时,我们还启用了动画效果,这有助于更直观地观察模型数据的修改如何影响图表。

auto chart = new QChart;
chart->setAnimationOptions(QChart::AllAnimations);

下面代码的第一行创建了新的柱形图系列。变量 firstRow 和 rowCount 用于定义自定义模型映射。自定义映射允许仅从模型中提取部分数据。在此示例中,从索引为 3 的行开始提取 5 行数据。 接下来的三行代码创建了 QVBarModelMapper 类的实例,并指定条形图系列的数据应从模型中索引为 1 到 4(含)的列中获取。为了在系列和模型之间建立连接,我们将这两个对象都设置为 QVBarModelMapper。

最后,将该系列添加到图表中。

auto series = new QBarSeries;

int first = 3;
int count = 5;
auto mapper = new QVBarModelMapper(this);
mapper->setFirstBarSetColumn(1);
mapper->setLastBarSetColumn(4);
mapper->setFirstRow(first);
mapper->setRowCount(count);
mapper->setSeries(series);
mapper->setModel(model);
chart->addSeries(series);

为了在QTableView 中显示哪些数据对应哪些柱状集,本示例使用了表格着色。当系列被添加到图表时,系统会根据当前选定的主题为其分配一种颜色。下面的代码从系列中提取该颜色,并用它来创建彩色QTableView 。视图的着色功能不属于QChart的核心功能。

// for storing color hex from the series
QString seriesColorHex = "#000000";

// get the color of the series and use it for showing the mapped area
QList<QBarSet *> barsets = series->barSets();
for (int i = 0; i < barsets.count(); i++) {
    seriesColorHex = "#" + QString::number(barsets.at(i)->brush().color().rgb(), 16).right(6).toUpper();
    model->addMapping(seriesColorHex, QRect(1 + i, first, 1, barsets.at(i)->count()));
}

我们希望在图表轴上放置类别标签,以说明数据的含义。下面的代码片段展示了如何实现这一点。

QStringList categories {"April",  "May", "June", "July", "August"};
auto axisX = new QBarCategoryAxis;
axisX->append(categories);
chart->addAxis(axisX, Qt::AlignBottom);
series->attachAxis(axisX);
auto axisY = new QValueAxis;
chart->addAxis(axisY, Qt::AlignLeft);
series->attachAxis(axisY);

为了避免手动配置QGraphicsScene ,我们使用QChartView类来代为处理。QChart对象指针作为QChartView构造函数的参数传入。为了使渲染效果更美观,我们启用了抗锯齿功能,并设置了chartView小部件的最小尺寸。

auto chartView = new QChartView(chart, this);
chartView->setRenderHint(QPainter::Antialiasing);

最后,我们将这两个控件放置在一个布局中,并将该布局设为应用程序的布局。

// create main layout
auto mainLayout = new QGridLayout;
mainLayout->setHorizontalSpacing(10);
mainLayout->addWidget(tableView, 1, 0);
mainLayout->addWidget(chartView, 1, 1);
mainLayout->setColumnStretch(1, 1);
mainLayout->setColumnStretch(0, 0);
setLayout(mainLayout);

应用程序已准备就绪。请尝试修改表格视图中的数据,观察其对图表的影响。

© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.