Add a simple widget for setting percentage values via spin and slider

This commit is contained in:
Nyall Dawson 2024-01-04 08:09:58 +10:00
parent 0215bf01a3
commit 2262aee293
9 changed files with 346 additions and 0 deletions

View File

@ -0,0 +1,69 @@
/************************************************************************
* This file has been generated automatically from *
* *
* src/gui/qgspercentagewidget.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/
class QgsPercentageWidget : QWidget
{
%Docstring(signature="appended")
A widget for setting a percentage value.
.. versionadded:: 3.36
%End
%TypeHeaderCode
#include "qgspercentagewidget.h"
%End
public:
explicit QgsPercentageWidget( QWidget *parent /TransferThis/ = 0 );
%Docstring
Constructor for QgsPercentageWidget.
%End
double value() const;
%Docstring
Returns the current percentage selected in the widget, as a factor from 0.0 to 1.0.
.. seealso:: :py:func:`setValue`
.. seealso:: :py:func:`valueChanged`
%End
public slots:
void setValue( double value );
%Docstring
Sets the current ``value`` to show in the widget, where ``value`` is a factor which ranges from 0.0 to 1.0.
.. seealso:: :py:func:`value`
.. seealso:: :py:func:`valueChanged`
%End
signals:
void valueChanged( double value );
%Docstring
Emitted when the ``value`` is changed in the widget, where ``value`` is a factor which ranges from 0.0 to 1.0.
.. seealso:: :py:func:`setValue`
.. seealso:: :py:func:`value`
%End
};
/************************************************************************
* This file has been generated automatically from *
* *
* src/gui/qgspercentagewidget.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/

View File

@ -168,6 +168,7 @@
%Include auto_generated/qgspanelwidget.sip
%Include auto_generated/qgspanelwidgetstack.sip
%Include auto_generated/qgspasswordlineedit.sip
%Include auto_generated/qgspercentagewidget.sip
%Include auto_generated/qgspixmaplabel.sip
%Include auto_generated/qgsplaybackcontrollerwidget.sip
%Include auto_generated/qgspluginmanagerinterface.sip

View File

@ -0,0 +1,69 @@
/************************************************************************
* This file has been generated automatically from *
* *
* src/gui/qgspercentagewidget.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/
class QgsPercentageWidget : QWidget
{
%Docstring(signature="appended")
A widget for setting a percentage value.
.. versionadded:: 3.36
%End
%TypeHeaderCode
#include "qgspercentagewidget.h"
%End
public:
explicit QgsPercentageWidget( QWidget *parent /TransferThis/ = 0 );
%Docstring
Constructor for QgsPercentageWidget.
%End
double value() const;
%Docstring
Returns the current percentage selected in the widget, as a factor from 0.0 to 1.0.
.. seealso:: :py:func:`setValue`
.. seealso:: :py:func:`valueChanged`
%End
public slots:
void setValue( double value );
%Docstring
Sets the current ``value`` to show in the widget, where ``value`` is a factor which ranges from 0.0 to 1.0.
.. seealso:: :py:func:`value`
.. seealso:: :py:func:`valueChanged`
%End
signals:
void valueChanged( double value );
%Docstring
Emitted when the ``value`` is changed in the widget, where ``value`` is a factor which ranges from 0.0 to 1.0.
.. seealso:: :py:func:`setValue`
.. seealso:: :py:func:`value`
%End
};
/************************************************************************
* This file has been generated automatically from *
* *
* src/gui/qgspercentagewidget.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/

View File

@ -168,6 +168,7 @@
%Include auto_generated/qgspanelwidget.sip
%Include auto_generated/qgspanelwidgetstack.sip
%Include auto_generated/qgspasswordlineedit.sip
%Include auto_generated/qgspercentagewidget.sip
%Include auto_generated/qgspixmaplabel.sip
%Include auto_generated/qgsplaybackcontrollerwidget.sip
%Include auto_generated/qgspluginmanagerinterface.sip

View File

@ -673,6 +673,7 @@ set(QGIS_GUI_SRCS
qgspanelwidget.cpp
qgspanelwidgetstack.cpp
qgspasswordlineedit.cpp
qgspercentagewidget.cpp
qgspixmaplabel.cpp
qgsplaybackcontrollerwidget.cpp
qgspluginmanagerinterface.cpp
@ -953,6 +954,7 @@ set(QGIS_GUI_HDRS
qgspanelwidget.h
qgspanelwidgetstack.h
qgspasswordlineedit.h
qgspercentagewidget.h
qgspixmaplabel.h
qgsplaybackcontrollerwidget.h
qgspluginmanagerinterface.h

View File

@ -0,0 +1,70 @@
/***************************************************************************
qgspercentagewidget.h
-----------------
Date : January 2024
Copyright : (C) 2024 Nyall Dawson
Email : nyall.dawson@gmail.com
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include "qgspercentagewidget.h"
#include "qgsdoublespinbox.h"
#include "qgis.h"
#include <QHBoxLayout>
#include <QSlider>
QgsPercentageWidget::QgsPercentageWidget( QWidget *parent )
: QWidget( parent )
{
QHBoxLayout *layout = new QHBoxLayout();
layout->setContentsMargins( 0, 0, 0, 0 );
layout->setSpacing( 3 );
setLayout( layout );
mSlider = new QSlider();
mSlider->setMinimum( 0 );
mSlider->setMaximum( 1000 );
mSlider->setSingleStep( 10 );
mSlider->setPageStep( 100 );
mSlider->setValue( 1000 );
mSlider->setOrientation( Qt::Horizontal );
layout->addWidget( mSlider, 1 );
mSpinBox = new QgsDoubleSpinBox();
mSpinBox->setMinimum( 0.0 );
mSpinBox->setMaximum( 100.0 );
mSpinBox->setValue( 100.0 );
mSpinBox->setClearValue( 100.0 );
mSpinBox->setMinimumSize( QSize( 100, 0 ) );
mSpinBox->setDecimals( 1 );
mSpinBox->setSuffix( tr( " %" ) );
layout->addWidget( mSpinBox, 0 );
setFocusProxy( mSpinBox );
connect( mSlider, &QSlider::valueChanged, this, [ = ]( int value ) { mSpinBox->setValue( value / 10.0 ); } );
connect( mSpinBox, static_cast < void ( QgsDoubleSpinBox::* )( double ) > ( &QgsDoubleSpinBox::valueChanged ), this, [ = ]( double value ) { whileBlocking( mSlider )->setValue( value * 10 ); } );
connect( mSpinBox, static_cast < void ( QgsDoubleSpinBox::* )( double ) > ( &QgsDoubleSpinBox::valueChanged ), this, &QgsPercentageWidget::spinChanged );
}
double QgsPercentageWidget::value() const
{
return mSpinBox->value() / 100.0;
}
void QgsPercentageWidget::setValue( double value )
{
mSpinBox->setValue( value * 100.0 );
}
void QgsPercentageWidget::spinChanged( double value )
{
emit valueChanged( value / 100.0 );
}

View File

@ -0,0 +1,82 @@
/***************************************************************************
qgspercentagewidget.h
-----------------
Date : January 2024
Copyright : (C) 2024 Nyall Dawson
Email : nyall.dawson@gmail.com
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#ifndef QGSPERCENTAGEWIDGET_H
#define QGSPERCENTAGEWIDGET_H
#include <QWidget>
#include "qgis_sip.h"
#include "qgis_gui.h"
class QgsDoubleSpinBox;
class QSlider;
/**
* \class QgsPercentageWidget
* \ingroup gui
* \brief A widget for setting a percentage value.
* \since QGIS 3.36
*/
class GUI_EXPORT QgsPercentageWidget : public QWidget
{
Q_OBJECT
Q_PROPERTY( double value READ value WRITE setValue NOTIFY valueChanged )
public:
/**
* Constructor for QgsPercentageWidget.
*/
explicit QgsPercentageWidget( QWidget *parent SIP_TRANSFERTHIS = nullptr );
/**
* Returns the current percentage selected in the widget, as a factor from 0.0 to 1.0.
* \see setValue()
* \see valueChanged()
*/
double value() const;
public slots:
/**
* Sets the current \a value to show in the widget, where \a value is a factor which ranges from 0.0 to 1.0.
*
* \see value()
* \see valueChanged()
*/
void setValue( double value );
signals:
/**
* Emitted when the \a value is changed in the widget, where \a value is a factor which ranges from 0.0 to 1.0.
*
* \see setValue()
* \see value()
*/
void valueChanged( double value );
private slots:
void spinChanged( double value );
private:
QgsDoubleSpinBox *mSpinBox = nullptr;
QSlider *mSlider = nullptr;
};
#endif // QGSPERCENTAGEWIDGET_H

View File

@ -203,6 +203,7 @@ ADD_PYTHON_TEST(PyQgsPalLabelingCanvas test_qgspallabeling_canvas.py)
ADD_PYTHON_TEST(PyQgsPalLabelingLayout test_qgspallabeling_layout.py)
ADD_PYTHON_TEST(PyQgsPalLabelingPlacement test_qgspallabeling_placement.py)
ADD_PYTHON_TEST(PyQgsPathResolver test_qgspathresolver.py)
ADD_PYTHON_TEST(PyQgsPercentageWidget test_qgspercentagewidget.py)
ADD_PYTHON_TEST(PyQgsPlot test_qgsplot.py)
ADD_PYTHON_TEST(PyQgsPoint test_qgspoint.py)
ADD_PYTHON_TEST(PyQgsPointCloudAttributeByRampRenderer test_qgspointcloudattributebyramprenderer.py)

View File

@ -0,0 +1,51 @@
"""QGIS Unit tests for QgsPercentageWidget
.. note:: This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
"""
from qgis.PyQt.QtTest import QSignalSpy
from qgis.gui import QgsPercentageWidget
import unittest
from qgis.testing import start_app, QgisTestCase
start_app()
class TestQgsPercentageWidget(QgisTestCase):
def testGettersSetters(self):
""" test widget getters/setters """
w = QgsPercentageWidget()
w.setValue(0.2)
self.assertEqual(w.value(), 0.2)
# bad values
w.setValue(-0.2)
self.assertEqual(w.value(), 0.0)
w.setValue(100)
self.assertEqual(w.value(), 1.0)
def test_ChangedSignals(self):
""" test that signals are correctly emitted when setting value"""
w = QgsPercentageWidget()
spy = QSignalSpy(w.valueChanged)
w.setValue(0.2)
self.assertEqual(len(spy), 1)
self.assertEqual(spy[0][0], 0.2)
# bad value
w.setValue(100)
self.assertEqual(len(spy), 2)
self.assertEqual(spy[1][0], 1.0)
if __name__ == '__main__':
unittest.main()