summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKeith Kyzivat <keith.kyzivat@qt.io>2021-06-02 13:43:37 -0400
committerKeith Kyzivat <keith.kyzivat@qt.io>2021-06-08 18:57:24 -0400
commit282f9aa1a5ca6cf2c853f20018a8cd6671f2934f (patch)
tree0ef1cd8278dd301df1fc6afc699f95049ad990a8
parent7f940ae44f96be4228efb4620ab1d26dbf8a51e1 (diff)
Update Qt Charts legend example to illustrate interactivity
Example cleaned up and organized, and interactive checkbox is added to allow user to see how an interactive legend works. Task-number: QTBUG-93477 Change-Id: I855283ad8fffd61b23cf021ab41530255abfbd47 Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
-rw-r--r--examples/charts/legend/mainwidget.cpp254
-rw-r--r--examples/charts/legend/mainwidget.h45
-rw-r--r--src/charts/doc/images/examples_legend_detach.pngbin61273 -> 78304 bytes
-rw-r--r--src/charts/doc/images/examples_legend_detach2.pngbin75296 -> 80767 bytes
-rw-r--r--src/charts/doc/src/examples-legend.qdoc48
5 files changed, 205 insertions, 142 deletions
diff --git a/examples/charts/legend/mainwidget.cpp b/examples/charts/legend/mainwidget.cpp
index e44d8304..286ca959 100644
--- a/examples/charts/legend/mainwidget.cpp
+++ b/examples/charts/legend/mainwidget.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2021 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt Charts module of the Qt Toolkit.
@@ -30,49 +30,39 @@
#include "mainwidget.h"
#include <QtCharts/QChart>
#include <QtCharts/QChartView>
-#include <QtWidgets/QPushButton>
-#include <QtWidgets/QLabel>
-#include <QtCore/QDebug>
#include <QtCharts/QBarSet>
#include <QtCharts/QBarSeries>
#include <QtCharts/QLegend>
+#include <QtWidgets/QGridLayout>
#include <QtWidgets/QFormLayout>
+#include <QtWidgets/QGroupBox>
+#include <QtWidgets/QCheckBox>
+#include <QtWidgets/QPushButton>
+#include <QtWidgets/QDoubleSpinBox>
QT_USE_NAMESPACE
MainWidget::MainWidget(QWidget *parent) :
QWidget(parent)
{
- // Create buttons for ui
- m_buttonLayout = new QGridLayout();
- QPushButton *detachLegendButton = new QPushButton("Toggle attached");
- connect(detachLegendButton, &QPushButton::clicked, this, &MainWidget::toggleAttached);
- m_buttonLayout->addWidget(detachLegendButton, 0, 0);
-
- QPushButton *addSetButton = new QPushButton("add barset");
- connect(addSetButton, &QPushButton::clicked, this, &MainWidget::addBarset);
- m_buttonLayout->addWidget(addSetButton, 2, 0);
- QPushButton *removeBarsetButton = new QPushButton("remove barset");
- connect(removeBarsetButton, &QPushButton::clicked, this, &MainWidget::removeBarset);
- m_buttonLayout->addWidget(removeBarsetButton, 3, 0);
-
- QPushButton *alignButton = new QPushButton("Align (Bottom)");
- connect(alignButton, &QPushButton::clicked, this, &MainWidget::setLegendAlignment);
- m_buttonLayout->addWidget(alignButton, 4, 0);
-
- QPushButton *boldButton = new QPushButton("Toggle bold");
- connect(boldButton, &QPushButton::clicked, this, &MainWidget::toggleBold);
- m_buttonLayout->addWidget(boldButton, 8, 0);
-
- QPushButton *italicButton = new QPushButton("Toggle italic");
- connect(italicButton, &QPushButton::clicked, this, &MainWidget::toggleItalic);
- m_buttonLayout->addWidget(italicButton, 9, 0);
+ // Create chart view with the chart
+ m_chart = new QChart();
+ m_chartView = new QChartView(m_chart, this);
- m_legendPosX = new QDoubleSpinBox();
- m_legendPosY = new QDoubleSpinBox();
- m_legendWidth = new QDoubleSpinBox();
- m_legendHeight = new QDoubleSpinBox();
+ m_chart->setTitle("Legend detach example");
+
+ createUi();
+ connect(m_toggleAttachedButton, &QPushButton::clicked, this, &MainWidget::toggleAttached);
+ connect(m_interactiveButton, &QPushButton::clicked, this, &MainWidget::toggleInteractive);
+ connect(m_boldButton, &QPushButton::clicked, this, &MainWidget::toggleBold);
+ connect(m_italicButton, &QPushButton::clicked, this, &MainWidget::toggleItalic);
+ connect(m_addSetButton, &QPushButton::clicked, this, &MainWidget::addBarset);
+ connect(m_removeSetButton, &QPushButton::clicked, this, &MainWidget::removeBarset);
+ connect(m_alignmentButton, &QPushButton::clicked, this, &MainWidget::setLegendAlignment);
+ connect(m_fontSize,
+ static_cast<void (QDoubleSpinBox::*)(double)>(&QDoubleSpinBox::valueChanged),
+ this, &MainWidget::fontSizeChanged);
connect(m_legendPosX,
static_cast<void (QDoubleSpinBox::*)(double)>(&QDoubleSpinBox::valueChanged),
this, &MainWidget::updateLegendLayout);
@@ -86,38 +76,95 @@ MainWidget::MainWidget(QWidget *parent) :
static_cast<void (QDoubleSpinBox::*)(double)>(&QDoubleSpinBox::valueChanged),
this, &MainWidget::updateLegendLayout);
+ QLegend *legend = m_chart->legend();
+ legend->setShowToolTips(true);
+ legend->setBrush(QBrush(QColor(128, 128, 128, 128)));
+ legend->setPen(QPen(QColor(192, 192, 192, 192)));
+//![5]
+ legend->setInteractive(true);
+//![5]
+
+//![4]
+ connect(legend, &QLegend::attachedToChartChanged, [legend, this](bool attachedToChart) {
+ m_toggleAttachedButton->setChecked(attachedToChart);
+ legend->setBackgroundVisible(!attachedToChart);
+ m_geometrySettings->setDisabled(attachedToChart);
+ });
+//![4]
+ connect(legend, &QGraphicsWidget::geometryChanged, this, &MainWidget::updateLegendSpinbox);
+
+ createSeries();
+ m_chart->createDefaultAxes();
+
+//![1]
+ m_chart->legend()->setVisible(true);
+ m_chart->legend()->setAlignment(Qt::AlignBottom);
+//![1]
+
+ m_chartView->setRenderHint(QPainter::Antialiasing);
+}
+
+void MainWidget::createUi()
+{
+ QLegend *legend = m_chart->legend();
+ // Create buttons for ui
+ QGridLayout *buttonLayout = new QGridLayout();
+ m_toggleAttachedButton = new QCheckBox("Attached");
+ m_toggleAttachedButton->setChecked(true);
+ buttonLayout->addWidget(m_toggleAttachedButton, 0, 0);
+
+ m_interactiveButton = new QCheckBox("Interactive");
+ m_interactiveButton->setChecked(true);
+ buttonLayout->addWidget(m_interactiveButton, 1, 0);
+
+ m_boldButton = new QCheckBox("Bold");
+ buttonLayout->addWidget(m_boldButton, 2, 0);
+
+ m_italicButton = new QCheckBox("Italic");
+ buttonLayout->addWidget(m_italicButton, 3, 0);
+
+ m_addSetButton = new QPushButton("Add Barset");
+ buttonLayout->addWidget(m_addSetButton, 4, 0);
+
+ m_removeSetButton = new QPushButton("Remove Barset");
+ buttonLayout->addWidget(m_removeSetButton, 5, 0);
+
+ m_alignmentButton = new QPushButton("Align (Bottom)");
+ buttonLayout->addWidget(m_alignmentButton, 6, 0);
+
+ buttonLayout->setRowStretch(7, 1);
+
+ m_legendPosX = new QDoubleSpinBox();
+ m_legendPosY = new QDoubleSpinBox();
+ m_legendWidth = new QDoubleSpinBox();
+ m_legendHeight = new QDoubleSpinBox();
+
QFormLayout *legendLayout = new QFormLayout();
legendLayout->addRow("HPos", m_legendPosX);
legendLayout->addRow("VPos", m_legendPosY);
legendLayout->addRow("Width", m_legendWidth);
legendLayout->addRow("Height", m_legendHeight);
- m_legendSettings = new QGroupBox("Detached legend");
- m_legendSettings->setLayout(legendLayout);
- m_buttonLayout->addWidget(m_legendSettings);
- m_legendSettings->setVisible(false);
-
- // Create chart view with the chart
- m_chart = new QChart();
- m_chartView = new QChartView(m_chart, this);
+ m_geometrySettings = new QGroupBox("Detached legend");
+ m_geometrySettings->setLayout(legendLayout);
+ buttonLayout->addWidget(m_geometrySettings, 8, 0);
+ m_geometrySettings->setDisabled(true);
// Create spinbox to modify font size
m_fontSize = new QDoubleSpinBox();
- m_fontSize->setValue(m_chart->legend()->font().pointSizeF());
- connect(m_fontSize,
- static_cast<void (QDoubleSpinBox::*)(double)>(&QDoubleSpinBox::valueChanged),
- this, &MainWidget::fontSizeChanged);
+ QFont lfont = legend->font();
+ lfont.setPointSizeF(12.0);
+ legend->setFont(lfont);
+ m_fontSize->setValue(legend->font().pointSizeF());
QFormLayout *fontLayout = new QFormLayout();
fontLayout->addRow("Legend font size", m_fontSize);
// Create layout for grid and detached legend
- m_mainLayout = new QGridLayout();
- m_mainLayout->addLayout(m_buttonLayout, 0, 0);
- m_mainLayout->addLayout(fontLayout, 1, 0);
- m_mainLayout->addWidget(m_chartView, 0, 1, 3, 1);
- setLayout(m_mainLayout);
-
- createSeries();
+ QGridLayout *mainLayout = new QGridLayout();
+ mainLayout->addLayout(buttonLayout, 0, 0);
+ mainLayout->addLayout(fontLayout, 1, 0);
+ mainLayout->addWidget(m_chartView, 0, 1, 3, 1);
+ setLayout(mainLayout);
}
void MainWidget::createSeries()
@@ -129,41 +176,22 @@ void MainWidget::createSeries()
addBarset();
m_chart->addSeries(m_series);
- m_chart->setTitle("Legend detach example");
- m_chart->createDefaultAxes();
-//![1]
- m_chart->legend()->setVisible(true);
- m_chart->legend()->setAlignment(Qt::AlignBottom);
-//![1]
-
- m_chartView->setRenderHint(QPainter::Antialiasing);
-}
-
-void MainWidget::showLegendSpinbox()
-{
- m_legendSettings->setVisible(true);
- QRectF chartViewRect = m_chartView->rect();
-
- m_legendPosX->setMinimum(0);
- m_legendPosX->setMaximum(chartViewRect.width());
- m_legendPosX->setValue(150);
-
- m_legendPosY->setMinimum(0);
- m_legendPosY->setMaximum(chartViewRect.height());
- m_legendPosY->setValue(150);
-
- m_legendWidth->setMinimum(0);
- m_legendWidth->setMaximum(chartViewRect.width());
- m_legendWidth->setValue(150);
-
- m_legendHeight->setMinimum(0);
- m_legendHeight->setMaximum(chartViewRect.height());
- m_legendHeight->setValue(75);
}
-void MainWidget::hideLegendSpinbox()
+void MainWidget::updateLegendSpinbox()
{
- m_legendSettings->setVisible(false);
+ QLegend *legend = m_chart->legend();
+ double newPosX = legend->x();
+ double newPosY = legend->y();
+ QSizeF newSize = legend->size();
+ if (!qFuzzyCompare(m_legendPosX->value(), newPosX))
+ m_legendPosX->setValue(newPosX);
+ if (!qFuzzyCompare(m_legendPosY->value(), newPosY))
+ m_legendPosY->setValue(newPosY);
+ if (!qFuzzyCompare(m_legendWidth->value(), newSize.width()))
+ m_legendWidth->setValue(newSize.width());
+ if (!qFuzzyCompare(m_legendHeight->value(), newSize.height()))
+ m_legendHeight->setValue(newSize.height());
}
@@ -173,22 +201,34 @@ void MainWidget::toggleAttached()
if (legend->isAttachedToChart()) {
//![2]
legend->detachFromChart();
- m_chart->legend()->setBackgroundVisible(true);
- m_chart->legend()->setBrush(QBrush(QColor(128, 128, 128, 128)));
- m_chart->legend()->setPen(QPen(QColor(192, 192, 192, 192)));
//![2]
- showLegendSpinbox();
- updateLegendLayout();
} else {
//![3]
legend->attachToChart();
- legend->setBackgroundVisible(false);
//![3]
- hideLegendSpinbox();
}
update();
}
+void MainWidget::toggleInteractive()
+{
+ m_chart->legend()->setInteractive(!m_chart->legend()->isInteractive());
+}
+
+void MainWidget::toggleBold()
+{
+ QFont font = m_chart->legend()->font();
+ font.setBold(!font.bold());
+ m_chart->legend()->setFont(font);
+}
+
+void MainWidget::toggleItalic()
+{
+ QFont font = m_chart->legend()->font();
+ font.setItalic(!font.italic());
+ m_chart->legend()->setFont(font);
+}
+
void MainWidget::addBarset()
{
QBarSet *barSet = new QBarSet(QString("set ") + QString::number(m_series->count()));
@@ -233,20 +273,6 @@ void MainWidget::setLegendAlignment()
}
}
-void MainWidget::toggleBold()
-{
- QFont font = m_chart->legend()->font();
- font.setBold(!font.bold());
- m_chart->legend()->setFont(font);
-}
-
-void MainWidget::toggleItalic()
-{
- QFont font = m_chart->legend()->font();
- font.setItalic(!font.italic());
- m_chart->legend()->setFont(font);
-}
-
void MainWidget::fontSizeChanged()
{
QFont font = m_chart->legend()->font();
@@ -256,11 +282,27 @@ void MainWidget::fontSizeChanged()
void MainWidget::updateLegendLayout()
{
-//![4]
+//![6]
+ QRectF geom = m_chart->legend()->geometry();
+ if (qFuzzyCompare(geom.x(), m_legendPosX->value())
+ && qFuzzyCompare(geom.y(), m_legendPosY->value())
+ && qFuzzyCompare(geom.width(), m_legendWidth->value())
+ && qFuzzyCompare(geom.height(), m_legendHeight->value()))
+ return;
+
m_chart->legend()->setGeometry(QRectF(m_legendPosX->value(),
m_legendPosY->value(),
m_legendWidth->value(),
m_legendHeight->value()));
m_chart->legend()->update();
-//![4]
+//![6]
+}
+
+void MainWidget::resizeEvent(QResizeEvent *)
+{
+ QRectF chartViewRect = m_chartView->rect();
+ m_legendPosX->setMaximum(chartViewRect.width());
+ m_legendPosY->setMaximum(chartViewRect.height());
+ m_legendWidth->setMaximum(chartViewRect.width());
+ m_legendHeight->setMaximum(chartViewRect.height());
}
diff --git a/examples/charts/legend/mainwidget.h b/examples/charts/legend/mainwidget.h
index 29c8864c..022f9d34 100644
--- a/examples/charts/legend/mainwidget.h
+++ b/examples/charts/legend/mainwidget.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2021 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt Charts module of the Qt Toolkit.
@@ -30,16 +30,14 @@
#ifndef MAINWIDGET_H
#define MAINWIDGET_H
-#include <QtCharts/QChartGlobal>
+#include <QtWidgets/QWidget>
#include <QtCharts/QChart>
#include <QtCharts/QChartView>
-#include <QtWidgets/QWidget>
-#include <QtWidgets/QGraphicsWidget>
-#include <QtWidgets/QGridLayout>
-#include <QtWidgets/QGraphicsGridLayout>
+#include <QtCharts/QBarSeries>
+#include <QtWidgets/QCheckBox>
+#include <QtWidgets/QPushButton>
#include <QtWidgets/QDoubleSpinBox>
#include <QtWidgets/QGroupBox>
-#include <QtCharts/QBarSeries>
QT_USE_NAMESPACE
@@ -47,37 +45,40 @@ class MainWidget : public QWidget
{
Q_OBJECT
public:
- explicit MainWidget(QWidget *parent = 0);
+ explicit MainWidget(QWidget *parent = nullptr);
+ void createUi();
void createSeries();
- void showLegendSpinbox();
- void hideLegendSpinbox();
+ void updateLegendSpinbox();
public Q_SLOTS:
void toggleAttached();
+ void toggleInteractive();
+ void toggleBold();
+ void toggleItalic();
void addBarset();
void removeBarset();
-
void setLegendAlignment();
-
- void toggleBold();
- void toggleItalic();
void fontSizeChanged();
-
void updateLegendLayout();
+protected:
+ void resizeEvent(QResizeEvent *) override;
+
private:
QChart *m_chart;
- QBarSeries *m_series;
-
QChartView *m_chartView;
- QGridLayout *m_mainLayout;
- QGridLayout *m_buttonLayout;
- QGridLayout *m_fontLayout;
+ QBarSeries *m_series;
+ QCheckBox *m_toggleAttachedButton;
+ QCheckBox *m_interactiveButton;
+ QCheckBox *m_boldButton;
+ QCheckBox *m_italicButton;
+ QPushButton *m_addSetButton;
+ QPushButton *m_removeSetButton;
+ QPushButton *m_alignmentButton;
QDoubleSpinBox *m_fontSize;
- // For detached layout
- QGroupBox *m_legendSettings;
+ QGroupBox *m_geometrySettings;
QDoubleSpinBox *m_legendPosX;
QDoubleSpinBox *m_legendPosY;
QDoubleSpinBox *m_legendWidth;
diff --git a/src/charts/doc/images/examples_legend_detach.png b/src/charts/doc/images/examples_legend_detach.png
index 3376a4a0..867c17a6 100644
--- a/src/charts/doc/images/examples_legend_detach.png
+++ b/src/charts/doc/images/examples_legend_detach.png
Binary files differ
diff --git a/src/charts/doc/images/examples_legend_detach2.png b/src/charts/doc/images/examples_legend_detach2.png
index 5cc33819..5efe0d84 100644
--- a/src/charts/doc/images/examples_legend_detach2.png
+++ b/src/charts/doc/images/examples_legend_detach2.png
Binary files differ
diff --git a/src/charts/doc/src/examples-legend.qdoc b/src/charts/doc/src/examples-legend.qdoc
index c9d976d9..0d543c7d 100644
--- a/src/charts/doc/src/examples-legend.qdoc
+++ b/src/charts/doc/src/examples-legend.qdoc
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2021 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the documentation of the Qt Toolkit.
@@ -32,16 +32,24 @@
\brief This example shows how to detach the legend from the chart and how to attach it back.
- By default the chart draws the legend inside the same view with the chart. In some cases the
- user may want to draw the legend to somewhere else. To make this possible the legend can be
- detached from the chart. Detaching means that the chart doesn't draw the legend or try to
- change its layout. Detached legend can then be drawn wherever the user wishes, for example,
- in a different graphics scene. The behavior of the legend can be inspected by running the
- legend example.
- In the example we use the bar series where we add or remove the bar sets. The legend reflects
- the changes in series. The legend can be detached or attached back to the chart and its
- alignment can be modified.
- When the legend is detached, it can be resized and positioned freely.
+ By default, the chart draws the legend inside the same graphics view the chart is contained
+ within. In some cases, the user may want to draw the legend somewhere else. To make this
+ possible, the legend can be detached from the chart. Detaching means that the legend is no
+ longer fixed to an edge of the chart, and the chart no longer controls the legend's layout.
+ Instead, the legend geometry is controlled by the user, allowing free control of the location
+ and size of the legend. This can be floating atop the content of the chart, or even drawn in a
+ different graphics scene. The behavior of the legend can be tested by running this example.
+
+ In this example we show a bar series, allowing bar sets to be added or removed interactively.
+ The legend reflects the changes in series as bar sets are added and/or removed. The attachment
+ of the legend, its alignment, and its ability to be moved and resized can be controlled using
+ methods in \c QLegend.
+
+ When the legend is detached, it can be resized and positioned freely. If the interactive
+ feature of the legend is enabled, the legend can be freely dragged and resized by the user.
+ If the user drags the legend off of any side of the chart, it will automatically re-attach to
+ that side of the chart.
+
\image examples_legend_detach.png
\image examples_legend_detach2.png
@@ -54,15 +62,27 @@
\snippet legend/mainwidget.cpp 1
- This snippet shows how to detach the legend from the chart. After detaching, we turn its background to visible and set a different color to it. This makes it easier to see how the items inside the legend are arranged in detached mode.
+ This snippet shows how to detach the legend from the chart.
\snippet legend/mainwidget.cpp 2
- Here we attach the legend back to the chart. The background is turned invisible.
+ Here we reattach the legend to the chart. The background is turned invisible.
\snippet legend/mainwidget.cpp 3
- This shows how we set the detached legend dimensions. After setting the new values, we call update to show changes on screen.
+ Here we connect to the signal emitted when the legend is detached or attached, turning its
+ background on when detached and off when attached. This makes it easier to see how the
+ items inside the legend are arranged when it is detached.
\snippet legend/mainwidget.cpp 4
+
+ This shows how to make the legend interactive to the user using a pointing device such as a
+ mouse.
+
+ \snippet legend/mainwidget.cpp 5
+
+ This shows how we set the detached legend dimensions if the legend is not interactive. After
+ setting the new values, we call update to show changes on screen.
+
+ \snippet legend/mainwidget.cpp 6
*/