选点配置

注意: это часть примера Галерея графиков с.widgetами.

展示的功能

в данном разделе вы узнаете, как

  • Provide click-selection of points in a series.
  • Override the individual configuration of specific points, configuring
    • 颜色
    • 大小
    • 标签的可见性
    • 标签的文本格式

运行示例

要从 Qt Creator 运行示例,请打开 Welcome 模式并从 Examples 中选择示例。有关更多信息,请参阅 构建和运行示例.

派生 QMainWindow

我们首先创建一个 QMainWindow 的子类,其中包含图表和控制项。并提供构造函数实现的样板代码

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

创建 Line Series

然后我们创建一个 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 并在组合框中查找匹配的值。然后 accordingly 设置组合框的当前索引。对于复选框和行编辑,也以相同的方式从 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_selectedPointConfigPointConfigurations 成员变量上,并调用 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);

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

© 2024 The Qt Company Ltd. 本文档中包含的文档贡献是各自所有者的版权。本提供的文档是根据自由软件基金会发布的 GNU自由文档许可版本1.3 的条款授予的。Qt及其相关的标志是芬兰和/或其他国家的 商标。所有其他商标属于其各自所有者。