❝本示例演示如何使用QPieSeries API创建嵌套的甜甜圈图。 ❞
创建嵌套甜甜圈图
先创建一个QChartView实例并启用抗锯齿。然后从QChartView实例获得一个QChart对象。
代码语言:javascript复制QChartView *chartView = new QChartView;
/* 启用抗锯齿 */
chartView->setRenderHint(QPainter::Antialiasing);
QChart *chart = chartView->chart();
/* 禁用图例 */
chart->legend()->setVisible(false);
/* 设置标题 */
chart->setTitle("Nested donuts demo");
/* 启用动画 */
chart->setAnimationOptions(QChart::AllAnimations);
定义了三个变量,这些变量将用于定义甜甜圈图。最小和最大尺寸定义整个甜甜圈的相对尺寸。minSize是最小甜甜圈的相对内部大小。maxSize是最大甜甜圈的相对外部尺寸。
代码语言:javascript复制qreal minSize = 0.1;
qreal maxSize = 0.9;
int donutCount = 5;
下列代码块定义了各个甜甜圈及其切片。首先,创建一个新的QPieSeries对象。每个甜甜圈中的切片数量是随机的。内部的for循环使用随机值创建切片,并为其标记相同的值。
然后,将切片的标签设置为可见,并将其颜色设置为白色。为了使示例更有趣,将切片的悬停信号连接到小部件的槽函数(explodeSlice
)中,稍后将解释其内部工作原理。最后,将切片添加到甜甜圈。调整甜甜圈的大小以实现甜甜圈的嵌套。然后,将甜甜圈添加到小部件的甜甜圈列表和图表中。
for (int i = 0; i < donutCount; i ) {
QPieSeries *donut = new QPieSeries;
int sliceCount = 3 QRandomGenerator::global()->bounded(3);
for (int j = 0; j < sliceCount; j ) {
qreal value = 100 QRandomGenerator::global()->bounded(100);
QPieSlice *slice = new QPieSlice(QString("%1").arg(value), value);
slice->setLabelVisible(true);
slice->setLabelColor(Qt::white);
slice->setLabelPosition(QPieSlice::LabelInsideTangential);
connect(slice, &QPieSlice::hovered, this, &Widget::explodeSlice);
donut->append(slice);
donut->setHoleSize(minSize i * (maxSize - minSize) / donutCount);
donut->setPieSize(minSize (i 1) * (maxSize - minSize) / donutCount);
}
m_donuts.append(donut);
chartView->chart()->addSeries(donut);
}
最后,将小部件放置在应用程序使用的布局中。
代码语言:javascript复制QGridLayout *mainLayout = new QGridLayout;
mainLayout->addWidget(chartView, 1, 1);
setLayout(mainLayout);
为了使示例更有趣,甜甜圈每1.25秒随机旋转一次。
代码语言:javascript复制updateTimer = new QTimer(this);
connect(updateTimer, &QTimer::timeout, this, &Widget::updateRotation);
updateTimer->start(1250);
小部件的updatedRotation
槽函数如下定义。它遍历所有甜甜圈,并以随机值修改其当前的旋转。
void Widget::updateRotation()
{
for (int i = 0; i < m_donuts.count(); i ) {
QPieSeries *donut = m_donuts.at(i);
qreal phaseShift = -50 QRandomGenerator::global()->bounded(100);
donut->setPieStartAngle(donut->pieStartAngle() phaseShift);
donut->setPieEndAngle(donut->pieEndAngle() phaseShift);
}
}
下面提供了前面提到的explodeSlice
槽函数代码。「如果切片设置为爆炸,则停止控制甜甜圈旋转的计时器。」 然后从切片获得切片的起始角度和终止角度。为了突出显示选定的切片,从包含选定的切片的甜甜圈向外放置的所有其他甜甜圈都需要修改其起始角度和结束角度,以使它们不会"阻碍"突出显示的切片。如果不再选择切片,则返回原始状态。
void Widget::explodeSlice(bool exploded)
{
QPieSlice *slice = qobject_cast<QPieSlice *>(sender());
if (exploded) {
updateTimer->stop();
qreal sliceStartAngle = slice->startAngle();
qreal sliceEndAngle = slice->startAngle() slice->angleSpan();
QPieSeries *donut = slice->series();
qreal seriesIndex = m_donuts.indexOf(donut);
for (int i = seriesIndex 1; i < m_donuts.count(); i ) {
m_donuts.at(i)->setPieStartAngle(sliceEndAngle);
m_donuts.at(i)->setPieEndAngle(360 sliceStartAngle);
}
} else {
for (int i = 0; i < m_donuts.count(); i ) {
m_donuts.at(i)->setPieStartAngle(0);
m_donuts.at(i)->setPieEndAngle(360);
}
updateTimer->start();
}
slice->setExploded(exploded);
}
关于更多
- 在「QtCreator软件」可以找到:
- 或在以下「Qt安装目录」找到:
C:Qt{你的Qt版本}Examples{你的Qt版本}chartsnesteddonuts
- 「相关链接」
https://doc.qt.io/qt-5/qtcharts-nesteddonuts-example.html