选定点配置

注: 这是带小工具图库的图表示例的一部分。

功能演示

在此您将学习如何

  • 在系列中提供点的点击选择。
  • 覆盖特定点的单独配置,配置:
    • 颜色
    • 尺寸
    • 标签的可见性
    • 标签的文本格式

运行示例

运行示例 Qt Creator,打开Welcome 模式,然后从Examples 中选择示例。更多信息,请参阅Qt Creator: 教程:构建并运行

子类 QMainWindow

我们首先创建QMainWindow 的子类,其中将包含图表和控件。我们还为构造函数的实现提供了模板:

PointConfigurationWidget::PointConfigurationWidget(QWidget *parent)
    : ContentWidget(parent)
{

创建线性系列

然后,我们创建一个QLineSeries ,给它一个名称,使点可见,并给它一些要绘制的点。

m_series = new QLineSeries;
m_series->setPointsVisible(true);
m_series->append({QPointF(0, 7),  QPointF(2, 4),
                  QPointF(3, 5),  QPointF(7, 4),
                  QPointF(10, 5), QPointF(11, 1),
                  QPointF(13, 3), QPointF(17, 6),
                  QPointF(18, 3), QPointF(20, 2)});

创建点配置控件

现在我们创建一些控件来配置颜色、大小、标签可见性和标签本身。我们为每个控件创建一个相关的标签,以便用户知道控件的作用。

对于颜色和大小,我们使用QComboBox ,在其中填充各种颜色和大小选择。

接下来,我们创建最后两个控件。一个复选框控制所选点的可见性。另一个控件是QLineEdit ,允许用户为点提供自定义标签。

请注意,我们不会为任何控件设置初始值,因为被选中的点始终会显示其当前设置。

auto selectedPointIndexLabel = new QLabel(tr("Selected Point: "), this);
m_selectedPointIndexLineEdit = new QLineEdit(this);
m_selectedPointIndexLineEdit->setReadOnly(true);

auto colorLabel = new QLabel(tr("Color: "), this);
m_colorCombobox = new QComboBox(this);
QStringList colorStrings = {"red", "orange", "yellow", "green", "blue",
                            "indigo", "violet", "black"};
QStringList trColorStrings = {tr("red"), tr("orange"), tr("yellow"),
                              tr("green"), tr("blue"), tr("indigo"),
                              tr("violet"), tr("black")};
for (int i = 0; i < colorStrings.size(); i++)
    m_colorCombobox->addItem(QIcon(), trColorStrings[i], QColor(colorStrings[i]));

auto sizeLabel = new QLabel(tr("Size: "), this);
m_sizeCombobox = new QComboBox(this);
for (auto size : { 2, 3, 4, 6, 8, 10, 12, 15 })
    m_sizeCombobox->addItem(QIcon(), QString::number(size), size);

auto labelVisibilityLabel = new QLabel(tr("Label Visibility: "), this);
m_labelVisibilityCheckbox = new QCheckBox(this);

auto customLabelLabel = new QLabel(tr("Custom Label: "), this);
m_customLabelLineEdit = new QLineEdit(this);

选择点后填充控件

现在我们有了控件,需要为所选点提供设置当前控件值的逻辑。请注意,如果没有对所选点进行自定义,则会使用整个系列的值。在这种情况下,如果系列设置为显示蓝色点,那么颜色组合框中就会显示蓝色值。

点击线条系列后,我们会查找所点击的点,移除先前的点选择,然后选择所点击的点。这将在图表上直观地显示所选点--使点变大以显示其选择。当前选中点的索引及其PointConfigurations 保存在一个成员变量中,以供以后使用。

查询PointConfigurations 并查找组合框中的匹配值。然后相应地设置组合框的当前索引。同样,对于复选框和行编辑,也是从PointConfigurations 中查找值,然后设置控件以与之匹配。

QObject::connect(m_series, &QXYSeries::clicked, m_series, [&](const QPointF &point) {
    int index = m_series->points().indexOf(point.toPoint());
    if (index != -1) {
        m_series->deselectAllPoints();
        m_series->selectPoint(index);
        m_selectedPointIndex = index;
        m_selectedPointConfig = m_series->pointConfiguration(index);
        const QPointF selectedPoint(m_series->at(index));
        m_selectedPointIndexLineEdit->setText("(" + QString::number(selectedPoint.x()) + ", " +
                                              QString::number(selectedPoint.y()) + ")");
        PointConfigurations config = m_series->pointConfiguration(index);

        QVariant colorVar = config[QXYSeries::PointConfiguration::Color];
        QColor color = colorVar.isValid() ? colorVar.value<QColor>() : m_series->color();
        if (m_colorCombobox->findData(color) < 0)
            m_colorCombobox->addItem(color.name(), color);
        m_colorCombobox->setCurrentIndex(m_colorCombobox->findData(color));

        QVariant sizeVar = config[QXYSeries::PointConfiguration::Size];
        qreal size = sizeVar.isValid() ? sizeVar.toReal() : m_series->markerSize();
        if (m_sizeCombobox->findData(size) < 0)
            m_sizeCombobox->addItem(QString::number(size), size);
        m_sizeCombobox->setCurrentIndex(m_sizeCombobox->findData(size));

        QVariant labelVisibilityVar = config[QXYSeries::PointConfiguration::LabelVisibility];
        bool labelVisibility = labelVisibilityVar.isValid() ? labelVisibilityVar.toBool() :
                                                              m_series->pointLabelsVisible();
        m_labelVisibilityCheckbox->setChecked(labelVisibility);

        QVariant customLabelVar = config[QXYSeries::PointConfiguration::LabelFormat];
        QString customLabel = customLabelVar.isValid() ? customLabelVar.toString() : "";
        m_customLabelLineEdit->setText(customLabel);
    }
});

提供配置选定点的逻辑

既然控件已填充了当前配置,我们就需要让它们做一些事情。我们将它们的信号连接到逻辑上,该逻辑将根据所选设置来配置所选点。只需将与控件关联的QXYSeries::PointConfiguration 值设置为m_selectedPointConfig PointConfigurations 成员变量,然后调用QXYSeries::setPointConfiguration 即可。

QObject::connect(m_colorCombobox, &QComboBox::activated, m_series, [&](const int) {
    m_selectedPointConfig[QXYSeries::PointConfiguration::Color] = m_colorCombobox->currentData();
    m_series->setPointConfiguration(m_selectedPointIndex, m_selectedPointConfig);
});
QObject::connect(m_sizeCombobox, &QComboBox::activated, m_series, [&](const int) {
    m_selectedPointConfig[QXYSeries::PointConfiguration::Size] = m_sizeCombobox->currentData();
    m_series->setPointConfiguration(m_selectedPointIndex, m_selectedPointConfig);
});
QObject::connect(m_labelVisibilityCheckbox, &QAbstractButton::clicked, m_series, [&](const bool checked) {
    m_selectedPointConfig[QXYSeries::PointConfiguration::LabelVisibility] = checked;
    m_series->setPointConfiguration(m_selectedPointIndex, m_selectedPointConfig);
});
QObject::connect(m_customLabelLineEdit, &QLineEdit::editingFinished, m_series, [&]() {
    m_selectedPointConfig[QXYSeries::PointConfiguration::LabelFormat] = m_customLabelLineEdit->text();
    m_series->setPointConfiguration(m_selectedPointIndex, m_selectedPointConfig);
});

创建图表并布置控件

最后,我们创建图表及其视图,将序列添加到图表中,并创建窗口布局。作为其中的一部分,我们连接到geometryChanged 信号,以便在图表首次绘制时捕捉信号。这样我们就能为最初选定的点获取正确的值。如果我们提前这样做,点值就会不正确。第一次触发后,该连接将被断开。

auto chart = new QChart;
chart->addSeries(m_series);
chart->createDefaultAxes();
chart->setTitle("Select points with mouse click");
chart->layout()->setContentsMargins(0, 0, 0, 0);
chart->legend()->setVisible(false);

m_selectInitialPointConnection = QObject::connect(chart, &QChart::geometryChanged, chart, [&]() {
    m_series->selectPoint(4);
    m_series->clicked(m_series->at(m_series->selectedPoints()[0]));
    disconnect(m_selectInitialPointConnection);
});

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

auto controlWidget = new QWidget(this);
auto controlLayout = new QGridLayout(controlWidget);
controlLayout->setColumnStretch(1, 1);

controlLayout->addWidget(selectedPointIndexLabel, 0, 0);
controlLayout->addWidget(m_selectedPointIndexLineEdit, 0, 1);

controlLayout->addWidget(colorLabel, 1, 0);
controlLayout->addWidget(m_colorCombobox, 1, 1);

controlLayout->addWidget(sizeLabel, 2, 0);
controlLayout->addWidget(m_sizeCombobox, 2, 1);

controlLayout->addWidget(labelVisibilityLabel, 3, 0);
controlLayout->addWidget(m_labelVisibilityCheckbox, 3, 1, 1, 2);

controlLayout->addWidget(customLabelLabel, 4, 0);
controlLayout->addWidget(m_customLabelLineEdit, 4, 1);

auto mainLayout = new QHBoxLayout(this);
mainLayout->addWidget(chartView);
mainLayout->setStretch(0, 1);
mainLayout->addWidget(controlWidget);

现在,我们有了一个功能齐全的应用程序,它演示了如何自定义单个图表点。

© 2025 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.