Implement a chart registry, to be used in GUI when offering a combobox of available charts

This commit is contained in:
Mathieu Pellerin 2025-06-23 16:29:21 +07:00 committed by Nyall Dawson
parent c89b4961c8
commit d837af123f
17 changed files with 395 additions and 3 deletions

View File

@ -122,6 +122,7 @@ try:
QgsApplication.defaultStyleModel = staticmethod(QgsApplication.defaultStyleModel)
QgsApplication.fontManager = staticmethod(QgsApplication.fontManager)
QgsApplication.sensorRegistry = staticmethod(QgsApplication.sensorRegistry)
QgsApplication.chartRegistry = staticmethod(QgsApplication.chartRegistry)
QgsApplication.messageLog = staticmethod(QgsApplication.messageLog)
QgsApplication.authManager = staticmethod(QgsApplication.authManager)
QgsApplication.authConfigurationStorageRegistry = staticmethod(QgsApplication.authConfigurationStorageRegistry)

View File

@ -0,0 +1,12 @@
# The following has been generated automatically from src/core/plot/qgschartregistry.h
try:
QgsChartRegistry.__attribute_docs__ = {'chartAdded': 'Emitted whenever a new chart type is added to the registry, with the\nspecified ``type`` and visible ``name``.\n', 'chartAboutToBeRemoved': 'Emitted whenever a new chart type is added to the registry, with the\nspecified ``type`` and visible ``name``.\n'}
QgsChartRegistry.__signal_arguments__ = {'chartAdded': ['type: str', 'name: str'], 'chartAboutToBeRemoved': ['type: str']}
QgsChartRegistry.__group__ = ['plot']
except (NameError, AttributeError):
pass
try:
QgsChartAbstractMetadata.__abstract_methods__ = ['createChart']
QgsChartAbstractMetadata.__group__ = ['plot']
except (NameError, AttributeError):
pass

View File

@ -39,6 +39,8 @@ A simple bar chart class.
virtual bool readXml( const QDomElement &element, const QgsReadWriteContext &context );
static QgsBarChart *create();
};
@ -72,6 +74,8 @@ A simple line chart class.
virtual bool readXml( const QDomElement &element, const QgsReadWriteContext &context );
static QgsLineChart *create();
};
/************************************************************************

View File

@ -0,0 +1,151 @@
/************************************************************************
* This file has been generated automatically from *
* *
* src/core/plot/qgschartregistry.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.py again *
************************************************************************/
class QgsChartAbstractMetadata
{
%Docstring(signature="appended")
Stores metadata about a chart class.
.. note::
In C++ you can use :py:class:`QgsChartAbstractMetadata` convenience class.
.. versionadded:: 4.0
%End
%TypeHeaderCode
#include "qgschartregistry.h"
%End
public:
QgsChartAbstractMetadata( const QString &type, const QString &visibleName );
%Docstring
Constructor for QgsChartAbstractMetadata with the specified class
``type``.
%End
virtual ~QgsChartAbstractMetadata();
QString type() const;
%Docstring
Returns the unique type code for the chart class.
%End
QString visibleName() const;
%Docstring
Returns a translated, user visible name for the chart class.
%End
virtual QgsPlot *createChart() = 0 /TransferBack/;
%Docstring
Creates a chart of this class.
%End
};
class QgsChartRegistry : QObject
{
%Docstring(signature="appended")
Registry of available chart types.
:py:class:`QgsChartRegistry` is not usually directly created, but rather
accessed through :py:func:`QgsApplication.chartRegistry()`.
A companion class, :py:class:`QgsChartGuiRegistry`, handles the GUI
behavior of charts.
.. versionadded:: 4.0
%End
%TypeHeaderCode
#include "qgschartregistry.h"
%End
public:
QgsChartRegistry( QObject *parent = 0 );
%Docstring
Creates a new empty item registry.
QgsChartRegistry is not usually directly created, but rather accessed
through :py:func:`QgsApplication.chartRegistry()`.
.. seealso:: :py:func:`populate`
%End
~QgsChartRegistry();
bool populate();
%Docstring
Populates the registry with standard chart types. If called on a
non-empty registry then this will have no effect and will return
``False``.
%End
QgsChartAbstractMetadata *chartMetadata( const QString &type ) const;
%Docstring
Returns the metadata for the specified chart ``type``. Returns ``None``
if a corresponding type was not found in the registry.
%End
bool addChartType( QgsChartAbstractMetadata *metadata /Transfer/ );
%Docstring
Registers a new chart type.
.. note::
Takes ownership of the metadata instance.
%End
bool removeChartType( const QString &type );
%Docstring
Removes a new a chart type from the registry.
%End
QgsPlot *createChart( const QString &type ) const /TransferBack/;
%Docstring
Creates a new instance of a chart given the ``type``.
%End
QMap<QString, QString> chartTypes() const;
%Docstring
Returns a map of available charts types to translated name.
%End
signals:
void chartAdded( const QString &type, const QString &name );
%Docstring
Emitted whenever a new chart type is added to the registry, with the
specified ``type`` and visible ``name``.
%End
void chartAboutToBeRemoved( const QString &type );
%Docstring
Emitted whenever a new chart type is added to the registry, with the
specified ``type`` and visible ``name``.
%End
private:
QgsChartRegistry( const QgsChartRegistry &rh );
};
/************************************************************************
* This file has been generated automatically from *
* *
* src/core/plot/qgschartregistry.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.py again *
************************************************************************/

View File

@ -924,6 +924,13 @@ font installation for the QGIS instance.
Returns the application's sensor registry, used for sensor types.
.. versionadded:: 3.32
%End
static QgsChartRegistry *chartRegistry() /KeepReference/;
%Docstring
Returns the application's chart registry, used for chart types.
.. versionadded:: 4.0
%End
static QgsMessageLog *messageLog();

View File

@ -519,6 +519,7 @@
%Include auto_generated/painting/qgspainting.sip
%Include auto_generated/pdf/qgspdfrenderer.sip
%Include auto_generated/plot/qgschart.sip
%Include auto_generated/plot/qgschartregistry.sip
%Include auto_generated/plot/qgsplot.sip
%Include auto_generated/pointcloud/qgspointcloudattribute.sip
%Include auto_generated/pointcloud/qgspointcloudattributebyramprenderer.sip

View File

@ -111,6 +111,7 @@ try:
QgsApplication.defaultStyleModel = staticmethod(QgsApplication.defaultStyleModel)
QgsApplication.fontManager = staticmethod(QgsApplication.fontManager)
QgsApplication.sensorRegistry = staticmethod(QgsApplication.sensorRegistry)
QgsApplication.chartRegistry = staticmethod(QgsApplication.chartRegistry)
QgsApplication.messageLog = staticmethod(QgsApplication.messageLog)
QgsApplication.authManager = staticmethod(QgsApplication.authManager)
QgsApplication.authConfigurationStorageRegistry = staticmethod(QgsApplication.authConfigurationStorageRegistry)

View File

@ -0,0 +1,12 @@
# The following has been generated automatically from src/core/plot/qgschartregistry.h
try:
QgsChartRegistry.__attribute_docs__ = {'chartAdded': 'Emitted whenever a new chart type is added to the registry, with the\nspecified ``type`` and visible ``name``.\n', 'chartAboutToBeRemoved': 'Emitted whenever a new chart type is added to the registry, with the\nspecified ``type`` and visible ``name``.\n'}
QgsChartRegistry.__signal_arguments__ = {'chartAdded': ['type: str', 'name: str'], 'chartAboutToBeRemoved': ['type: str']}
QgsChartRegistry.__group__ = ['plot']
except (NameError, AttributeError):
pass
try:
QgsChartAbstractMetadata.__abstract_methods__ = ['createChart']
QgsChartAbstractMetadata.__group__ = ['plot']
except (NameError, AttributeError):
pass

View File

@ -39,6 +39,8 @@ A simple bar chart class.
virtual bool readXml( const QDomElement &element, const QgsReadWriteContext &context );
static QgsBarChart *create();
};
@ -72,6 +74,8 @@ A simple line chart class.
virtual bool readXml( const QDomElement &element, const QgsReadWriteContext &context );
static QgsLineChart *create();
};
/************************************************************************

View File

@ -0,0 +1,151 @@
/************************************************************************
* This file has been generated automatically from *
* *
* src/core/plot/qgschartregistry.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.py again *
************************************************************************/
class QgsChartAbstractMetadata
{
%Docstring(signature="appended")
Stores metadata about a chart class.
.. note::
In C++ you can use :py:class:`QgsChartAbstractMetadata` convenience class.
.. versionadded:: 4.0
%End
%TypeHeaderCode
#include "qgschartregistry.h"
%End
public:
QgsChartAbstractMetadata( const QString &type, const QString &visibleName );
%Docstring
Constructor for QgsChartAbstractMetadata with the specified class
``type``.
%End
virtual ~QgsChartAbstractMetadata();
QString type() const;
%Docstring
Returns the unique type code for the chart class.
%End
QString visibleName() const;
%Docstring
Returns a translated, user visible name for the chart class.
%End
virtual QgsPlot *createChart() = 0 /TransferBack/;
%Docstring
Creates a chart of this class.
%End
};
class QgsChartRegistry : QObject
{
%Docstring(signature="appended")
Registry of available chart types.
:py:class:`QgsChartRegistry` is not usually directly created, but rather
accessed through :py:func:`QgsApplication.chartRegistry()`.
A companion class, :py:class:`QgsChartGuiRegistry`, handles the GUI
behavior of charts.
.. versionadded:: 4.0
%End
%TypeHeaderCode
#include "qgschartregistry.h"
%End
public:
QgsChartRegistry( QObject *parent = 0 );
%Docstring
Creates a new empty item registry.
QgsChartRegistry is not usually directly created, but rather accessed
through :py:func:`QgsApplication.chartRegistry()`.
.. seealso:: :py:func:`populate`
%End
~QgsChartRegistry();
bool populate();
%Docstring
Populates the registry with standard chart types. If called on a
non-empty registry then this will have no effect and will return
``False``.
%End
QgsChartAbstractMetadata *chartMetadata( const QString &type ) const;
%Docstring
Returns the metadata for the specified chart ``type``. Returns ``None``
if a corresponding type was not found in the registry.
%End
bool addChartType( QgsChartAbstractMetadata *metadata /Transfer/ );
%Docstring
Registers a new chart type.
.. note::
Takes ownership of the metadata instance.
%End
bool removeChartType( const QString &type );
%Docstring
Removes a new a chart type from the registry.
%End
QgsPlot *createChart( const QString &type ) const /TransferBack/;
%Docstring
Creates a new instance of a chart given the ``type``.
%End
QMap<QString, QString> chartTypes() const;
%Docstring
Returns a map of available charts types to translated name.
%End
signals:
void chartAdded( const QString &type, const QString &name );
%Docstring
Emitted whenever a new chart type is added to the registry, with the
specified ``type`` and visible ``name``.
%End
void chartAboutToBeRemoved( const QString &type );
%Docstring
Emitted whenever a new chart type is added to the registry, with the
specified ``type`` and visible ``name``.
%End
private:
QgsChartRegistry( const QgsChartRegistry &rh );
};
/************************************************************************
* This file has been generated automatically from *
* *
* src/core/plot/qgschartregistry.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.py again *
************************************************************************/

View File

@ -924,6 +924,13 @@ font installation for the QGIS instance.
Returns the application's sensor registry, used for sensor types.
.. versionadded:: 3.32
%End
static QgsChartRegistry *chartRegistry() /KeepReference/;
%Docstring
Returns the application's chart registry, used for chart types.
.. versionadded:: 4.0
%End
static QgsMessageLog *messageLog();

View File

@ -519,6 +519,7 @@
%Include auto_generated/painting/qgspainting.sip
%Include auto_generated/pdf/qgspdfrenderer.sip
%Include auto_generated/plot/qgschart.sip
%Include auto_generated/plot/qgschartregistry.sip
%Include auto_generated/plot/qgsplot.sip
%Include auto_generated/pointcloud/qgspointcloudattribute.sip
%Include auto_generated/pointcloud/qgspointcloudattributebyramprenderer.sip

View File

@ -91,6 +91,7 @@ set(QGIS_CORE_SRCS
gps/qgsvectorlayergpslogger.cpp
plot/qgschart.cpp
plot/qgschartregistry.cpp
plot/qgsplot.cpp
symbology/qgs25drenderer.cpp
@ -1741,6 +1742,7 @@ set(QGIS_CORE_HDRS
pdf/qgspdfrenderer.h
plot/qgschart.h
plot/qgschartregistry.h
plot/qgsplot.h
pointcloud/qgspointcloudattribute.h

View File

@ -31,7 +31,7 @@ void QgsBarChart::renderContent( QgsRenderContext &context, const QRectF &plotAr
}
const QStringList categories = plotData.categories();
if ( xAxis().type() == Qgis::PlotAxisType::ValueType && categories.isEmpty() )
if ( xAxis().type() == Qgis::PlotAxisType::CategoryType && categories.isEmpty() )
{
return;
}
@ -104,6 +104,15 @@ bool QgsBarChart::readXml( const QDomElement &element, const QgsReadWriteContext
return true;
}
QgsBarChart *QgsBarChart::create()
{
return new QgsBarChart();
}
//
// QgsLineChart
//
void QgsLineChart::renderContent( QgsRenderContext &context, const QRectF &plotArea, const QgsPlotData &plotData )
{
const QList<QgsAbstractPlotSeries *> seriesList = plotData.series();
@ -113,7 +122,7 @@ void QgsLineChart::renderContent( QgsRenderContext &context, const QRectF &plotA
}
const QStringList categories = plotData.categories();
if ( xAxis().type() == Qgis::PlotAxisType::ValueType && categories.isEmpty() )
if ( xAxis().type() == Qgis::PlotAxisType::CategoryType && categories.isEmpty() )
{
return;
}
@ -185,3 +194,8 @@ bool QgsLineChart::readXml( const QDomElement &element, const QgsReadWriteContex
Qgs2DXyPlot::readXml( element, context );
return true;
}
QgsLineChart *QgsLineChart::create()
{
return new QgsLineChart();
}

View File

@ -44,6 +44,8 @@ class CORE_EXPORT QgsBarChart : public Qgs2DXyPlot
bool writeXml( QDomElement &element, QDomDocument &document, const QgsReadWriteContext &context ) const override;
bool readXml( const QDomElement &element, const QgsReadWriteContext &context ) override;
static QgsBarChart *create();
private:
};
@ -71,8 +73,9 @@ class CORE_EXPORT QgsLineChart : public Qgs2DXyPlot
bool writeXml( QDomElement &element, QDomDocument &document, const QgsReadWriteContext &context ) const override;
bool readXml( const QDomElement &element, const QgsReadWriteContext &context ) override;
private:
static QgsLineChart *create();
private:
};

View File

@ -53,6 +53,7 @@
#include "qgssymbollayerregistry.h"
#include "qgssymbollayerutils.h"
#include "qgscalloutsregistry.h"
#include "qgschartregistry.h"
#include "qgspluginlayerregistry.h"
#include "qgsclassificationmethodregistry.h"
#include "qgsmessagelog.h"
@ -2537,6 +2538,11 @@ QgsSensorRegistry *QgsApplication::sensorRegistry()
return members()->mSensorRegistry.get();
}
QgsChartRegistry *QgsApplication::chartRegistry()
{
return members()->mChartRegistry.get();
}
QgsGpsConnectionRegistry *QgsApplication::gpsConnectionRegistry()
{
return members()->mGpsConnectionRegistry.get();
@ -2835,6 +2841,12 @@ QgsApplication::ApplicationMembers::ApplicationMembers()
mSensorRegistry->populate();
profiler->end();
}
{
profiler->start( tr( "Setup chart registry" ) );
mChartRegistry = std::make_unique<QgsChartRegistry>();
mChartRegistry->populate();
profiler->end();
}
{
profiler->start( tr( "Setup 3D symbol registry" ) );
m3DSymbolRegistry = std::make_unique<Qgs3DSymbolRegistry>();
@ -2909,6 +2921,7 @@ QgsApplication::ApplicationMembers::~ApplicationMembers()
mPageSizeRegistry.reset();
mAnnotationItemRegistry.reset();
mSensorRegistry.reset();
mChartRegistry.reset();
mLayoutItemRegistry.reset();
mPointCloudRendererRegistry.reset();
mTiledSceneRendererRegistry.reset();

View File

@ -63,6 +63,7 @@ class QgsNetworkContentFetcherRegistry;
class QgsValidityCheckRegistry;
class QTranslator;
class QgsCalloutRegistry;
class QgsChartRegistry;
class QgsBookmarkManager;
class QgsStyleModel;
class QgsNumericFormatRegistry;
@ -871,6 +872,12 @@ class CORE_EXPORT QgsApplication : public QApplication
*/
static QgsSensorRegistry *sensorRegistry() SIP_KEEPREFERENCE;
/**
* Returns the application's chart registry, used for chart types.
* \since QGIS 4.0
*/
static QgsChartRegistry *chartRegistry() SIP_KEEPREFERENCE;
/**
* Returns the application's message log.
*/
@ -1204,6 +1211,7 @@ class CORE_EXPORT QgsApplication : public QApplication
std::unique_ptr<QgsLayoutItemRegistry > mLayoutItemRegistry;
std::unique_ptr<QgsAnnotationItemRegistry > mAnnotationItemRegistry;
std::unique_ptr<QgsSensorRegistry > mSensorRegistry;
std::unique_ptr<QgsChartRegistry > mChartRegistry;
std::unique_ptr<QgsBookmarkManager > mBookmarkManager;
std::unique_ptr<QgsTileDownloadManager > mTileDownloadManager;
std::unique_ptr<QgsStyleModel > mStyleModel;