创建嵌套环形图
注意: 这是 带有小部件库的图表集 示例的一部分。
首先创建一个 QChartView 实例并开启其上的抗锯齿功能。然后从 QChartView 实例中获取一个 QChart 对象。禁用图例并设置图表的标题。最后一行使图表启用动画效果。
auto chartView = new QChartView(this); chartView->setRenderHint(QPainter::Antialiasing); QChart *chart = chartView->chart(); chart->legend()->setVisible(false); chart->setTitle("Nested Donuts (Hover over segments to explode them)"); chart->setAnimationOptions(QChart::AllAnimations); chart->layout()->setContentsMargins(0, 0, 0, 0);
定义了三个变量,这些变量将用于定义环形图。最小和最大尺寸定义了整个环形图的大小。minSize 是最小环形图的内径大小,maxSize 是最大环形图的外径大小。
以下代码块定义了单个环形图及其切片。首先创建一个新 QPieSeries 对象。每个环形图的切片数量是随机的。内部循环创建切片,带有随机的值和标签,标签与值相同。接下来设置切片的标签为可见,并将其颜色设置为白色。为了使示例更加有趣,将切片的悬停信号连接到小部件的槽。其内部工作原理将在稍后解释。最后将切片添加到环形图中。调整环形图的大小以实现环形图的嵌套。然后将环形图添加到小部件的环形图列表和图表中。
for (int i = 0; i < donutCount; i++) { auto donut = new QPieSeries; int sliceCount = 3 + QRandomGenerator::global()->bounded(3); for (int j = 0; j < sliceCount; j++) { qreal value = 100 + QRandomGenerator::global()->bounded(100); auto slice = new QPieSlice(QString("%1").arg(value), value); slice->setLabelVisible(true); slice->setLabelColor(Qt::white); slice->setLabelPosition(QPieSlice::LabelInsideTangential); connect(slice, &QPieSlice::hovered, this, &NestedDonutsWidget::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); }
最后将小部件放置在应用程序使用的布局中。
auto mainLayout = new QGridLayout; mainLayout->addWidget(chartView, 1, 1); setLayout(mainLayout);
为了使示例更有趣,每隔 1.25 秒随机旋转环形图。
m_updateTimer = new QTimer(this); connect(m_updateTimer, &QTimer::timeout, this, &NestedDonutsWidget::updateRotation); m_updateTimer->start(1250);
以下定义了小部件的 updatedRotation 槽。它遍历所有环形图并随机修改它们的当前旋转值。
void NestedDonutsWidget::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 NestedDonutsWidget::explodeSlice(bool exploded) { auto slice = qobject_cast<QPieSlice *>(sender()); if (exploded) { m_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); } m_updateTimer->start(); } slice->setExploded(exploded); }
© 2024 Qt 公司有限公司。在此包含的文档贡献是各自所有者的版权。此处提供的文档是根据 Free Software Foundation 发布的 GNU 自由文档许可证版本 1.3 的条款发布的。Qt 及相关标志是芬兰以及/或全球其他地区的 Qt 公司有限公司的商标。所有其他商标均为其各自所有者的财产。