Create new QgsOpacityWidget widget

Allows consistent behavior and appearance across all opacity controls
This commit is contained in:
Nyall Dawson 2017-05-30 11:36:24 +10:00
parent a3262240fe
commit e58f25dbb9
11 changed files with 433 additions and 0 deletions

View File

@ -128,6 +128,7 @@
%Include qgsnewnamedialog.sip
%Include qgsnewvectorlayerdialog.sip
%Include qgsnewgeopackagelayerdialog.sip
%Include qgsopacitywidget.sip
%Include qgsoptionsdialogbase.sip
%Include qgsoptionswidgetfactory.sip
%Include qgsorderbydialog.sip

View File

@ -0,0 +1,66 @@
/************************************************************************
* This file has been generated automatically from *
* *
* src/gui/qgsopacitywidget.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/
class QgsOpacityWidget : QWidget
{
%Docstring
A widget for setting an opacity value.
.. versionadded:: 3.0
%End
%TypeHeaderCode
#include "qgsopacitywidget.h"
%End
public:
explicit QgsOpacityWidget( QWidget *parent /TransferThis/ = 0 );
%Docstring
Constructor for QgsOpacityWidget.
%End
double opacity() const;
%Docstring
Returns the current opacity selected in the widget, where opacity ranges from 0.0 (transparent)
to 1.0 (opaque).
.. seealso:: setOpacity()
.. seealso:: opacityChanged()
:rtype: float
%End
public slots:
void setOpacity( double opacity );
%Docstring
Sets the current ``opacity`` to show in the widget, where ``opacity`` ranges from 0.0 (transparent)
to 1.0 (opaque).
.. seealso:: opacity()
.. seealso:: opacityChanged()
%End
signals:
void opacityChanged( double opacity );
%Docstring
Emitted when the ``opacity`` is changed in the widget, where ``opacity`` ranges from 0.0 (transparent)
to 1.0 (opaque).
.. seealso:: setOpacity()
.. seealso:: opacity()
%End
};
/************************************************************************
* This file has been generated automatically from *
* *
* src/gui/qgsopacitywidget.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/

View File

@ -26,6 +26,7 @@ SET (QGIS_CUSTOMWIDGETS_SRCS
qgsfilewidgetplugin.cpp
qgsfilterlineeditplugin.cpp
qgsmaplayercomboboxplugin.cpp
qgsopacitywidgetplugin.cpp
qgspasswordlineeditplugin.cpp
qgsprojectionselectionwidgetplugin.cpp
qgspropertyoverridebuttonplugin.cpp
@ -54,6 +55,7 @@ SET (QGIS_CUSTOMWIDGETS_MOC_HDRS
qgsfilewidgetplugin.h
qgsfilterlineeditplugin.h
qgsmaplayercomboboxplugin.h
qgsopacitywidgetplugin.h
qgspasswordlineeditplugin.h
qgsprojectionselectionwidgetplugin.h
qgspropertyoverridebuttonplugin.h
@ -87,6 +89,7 @@ SET(QGIS_CUSTOMWIDGETS_HDRS
qgsfilewidgetplugin.h
qgsfilterlineeditplugin.h
qgsmaplayercomboboxplugin.h
qgsopacitywidgetplugin.h
qgsprojectionselectionwidgetplugin.h
qgspropertyoverridebuttonplugin.h
qgsrasterbandcomboboxplugin.h

View File

@ -28,6 +28,7 @@
#include "qgsfilewidgetplugin.h"
#include "qgsfilterlineeditplugin.h"
#include "qgsmaplayercomboboxplugin.h"
#include "qgsopacitywidgetplugin.h"
#include "qgsprojectionselectionwidgetplugin.h"
#include "qgspropertyoverridebuttonplugin.h"
#include "qgsrasterbandcomboboxplugin.h"
@ -53,6 +54,7 @@ QgisCustomWidgets::QgisCustomWidgets( QObject *parent )
mWidgets.append( new QgsFileWidgetPlugin( this ) );
mWidgets.append( new QgsFilterLineEditPlugin( this ) );
mWidgets.append( new QgsMapLayerComboBoxPlugin( this ) );
mWidgets.append( new QgsOpacityWidgetPlugin( this ) );
mWidgets.append( new QgsProjectionSelectionWidgetPlugin( this ) );
mWidgets.append( new QgsPropertyOverrideButtonPlugin( this ) );
mWidgets.append( new QgsRasterBandComboBoxPlugin( this ) );

View File

@ -0,0 +1,97 @@
/***************************************************************************
qgsopacitywidgetplugin.cpp
-------------------------
Date : 30.05.2017
Copyright : (C) 2017 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 "qgiscustomwidgets.h"
#include "qgsopacitywidget.h"
#include "qgsopacitywidgetplugin.h"
QgsOpacityWidgetPlugin::QgsOpacityWidgetPlugin( QObject *parent )
: QObject( parent )
, mInitialized( false )
{
}
QString QgsOpacityWidgetPlugin::name() const
{
return "QgsOpacityWidget";
}
QString QgsOpacityWidgetPlugin::group() const
{
return QgisCustomWidgets::groupName();
}
QString QgsOpacityWidgetPlugin::includeFile() const
{
return "qgsopacitywidget.h";
}
QIcon QgsOpacityWidgetPlugin::icon() const
{
return QIcon( ":/images/icons/qgis-icon-60x60.png" );
}
bool QgsOpacityWidgetPlugin::isContainer() const
{
return false;
}
QWidget *QgsOpacityWidgetPlugin::createWidget( QWidget *parent )
{
return new QgsOpacityWidget( parent );
}
bool QgsOpacityWidgetPlugin::isInitialized() const
{
return mInitialized;
}
void QgsOpacityWidgetPlugin::initialize( QDesignerFormEditorInterface *core )
{
Q_UNUSED( core );
if ( mInitialized )
return;
mInitialized = true;
}
QString QgsOpacityWidgetPlugin::toolTip() const
{
return tr( "A widget for specifying an opacity value." );
}
QString QgsOpacityWidgetPlugin::whatsThis() const
{
return tr( "A widget for specifying an opacity value." );
}
QString QgsOpacityWidgetPlugin::domXml() const
{
return QString( "<ui language=\"c++\">\n"
" <widget class=\"%1\" name=\"mOpacityWidget\">\n"
" <property name=\"geometry\">\n"
" <rect>\n"
" <x>0</x>\n"
" <y>0</y>\n"
" <width>160</width>\n"
" <height>27</height>\n"
" </rect>\n"
" </property>\n"
" </widget>\n"
"</ui>\n" )
.arg( name() );
}

View File

@ -0,0 +1,51 @@
/***************************************************************************
qgsopacitywidgetplugin.h
-----------------------
Date : 30.05.2017
Copyright : (C) 2017 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 QGSOPACITYWIDGETPLUGIN_H
#define QGSOPACITYWIDGETPLUGIN_H
#include <QtGlobal>
#include <QtUiPlugin/QDesignerCustomWidgetInterface>
#include <QtUiPlugin/QDesignerExportWidget>
#include "qgis_customwidgets.h"
class CUSTOMWIDGETS_EXPORT QgsOpacityWidgetPlugin : public QObject, public QDesignerCustomWidgetInterface
{
Q_OBJECT
Q_INTERFACES( QDesignerCustomWidgetInterface )
public:
explicit QgsOpacityWidgetPlugin( QObject *parent = 0 );
private:
bool mInitialized;
// QDesignerCustomWidgetInterface interface
public:
QString name() const override;
QString group() const override;
QString includeFile() const override;
QIcon icon() const override;
bool isContainer() const override;
QWidget *createWidget( QWidget *parent ) override;
bool isInitialized() const override;
void initialize( QDesignerFormEditorInterface *core ) override;
QString toolTip() const override;
QString whatsThis() const override;
QString domXml() const override;
};
#endif // QGSOPACITYWIDGETPLUGIN_H

View File

@ -273,6 +273,7 @@ SET(QGIS_GUI_SRCS
qgsnewnamedialog.cpp
qgsnewvectorlayerdialog.cpp
qgsnewgeopackagelayerdialog.cpp
qgsopacitywidget.cpp
qgsoptionsdialogbase.cpp
qgsorderbydialog.cpp
qgsowssourceselect.cpp
@ -421,6 +422,7 @@ SET(QGIS_GUI_MOC_HDRS
qgsnewnamedialog.h
qgsnewvectorlayerdialog.h
qgsnewgeopackagelayerdialog.h
qgsopacitywidget.h
qgsoptionsdialogbase.h
qgsoptionswidgetfactory.h
qgsorderbydialog.h

View File

@ -0,0 +1,69 @@
/***************************************************************************
qgsopacitywidget.cpp
-------------------
Date : May 2017
Copyright : (C) 2017 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 "qgsopacitywidget.h"
#include "qgsdoublespinbox.h"
#include <QHBoxLayout>
#include <QSlider>
QgsOpacityWidget::QgsOpacityWidget( QWidget *parent )
: QWidget( parent )
{
QHBoxLayout *layout = new QHBoxLayout();
layout->setContentsMargins( 0, 0, 0, 0 );
layout->setSpacing( 0 );
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, &QgsOpacityWidget::spinChanged );
}
double QgsOpacityWidget::opacity() const
{
return mSpinBox->value() / 100.0;
}
void QgsOpacityWidget::setOpacity( double opacity )
{
mSpinBox->setValue( opacity * 100.0 );
}
void QgsOpacityWidget::spinChanged( double value )
{
emit opacityChanged( value / 100.0 );
}

View File

@ -0,0 +1,83 @@
/***************************************************************************
qgsopacitywidget.h
-----------------
Date : May 2017
Copyright : (C) 2017 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 QGSOPACITYWIDGET_H
#define QGSOPACITYWIDGET_H
#include <QWidget>
#include "qgis.h"
#include "qgis_gui.h"
class QgsDoubleSpinBox;
class QSlider;
/**
* \class QgsOpacityWidget
* \ingroup gui
* \brief A widget for setting an opacity value.
* \since QGIS 3.0
*/
class GUI_EXPORT QgsOpacityWidget : public QWidget
{
Q_OBJECT
Q_PROPERTY( double opacity READ opacity WRITE setOpacity NOTIFY opacityChanged )
public:
/**
* Constructor for QgsOpacityWidget.
*/
explicit QgsOpacityWidget( QWidget *parent SIP_TRANSFERTHIS = nullptr );
/**
* Returns the current opacity selected in the widget, where opacity ranges from 0.0 (transparent)
* to 1.0 (opaque).
* \see setOpacity()
* \see opacityChanged()
*/
double opacity() const;
public slots:
/**
* Sets the current \a opacity to show in the widget, where \a opacity ranges from 0.0 (transparent)
* to 1.0 (opaque).
* \see opacity()
* \see opacityChanged()
*/
void setOpacity( double opacity );
signals:
/**
* Emitted when the \a opacity is changed in the widget, where \a opacity ranges from 0.0 (transparent)
* to 1.0 (opaque).
* \see setOpacity()
* \see opacity()
*/
void opacityChanged( double opacity );
private slots:
void spinChanged( double value );
private:
QgsDoubleSpinBox *mSpinBox = nullptr;
QSlider *mSlider = nullptr;
};
#endif // QGSOPACITYWIDGET_H

View File

@ -91,6 +91,7 @@ ADD_PYTHON_TEST(PyQgsNewGeoPackageLayerDialog test_qgsnewgeopackagelayerdialog.p
ADD_PYTHON_TEST(PyQgsNoApplication test_qgsnoapplication.py)
ADD_PYTHON_TEST(PyQgsOGRProviderGpkg test_provider_ogr_gpkg.py)
ADD_PYTHON_TEST(PyQgsOGRProviderSqlite test_provider_ogr_sqlite.py)
ADD_PYTHON_TEST(PyQgsOpacityWidget test_qgsopacitywidget.py)
ADD_PYTHON_TEST(PyQgsOptional test_qgsoptional.py)
ADD_PYTHON_TEST(PyQgsPalLabelingBase test_qgspallabeling_base.py)
ADD_PYTHON_TEST(PyQgsPalLabelingCanvas test_qgspallabeling_canvas.py)

View File

@ -0,0 +1,58 @@
# -*- coding: utf-8 -*-
"""QGIS Unit tests for QgsOpacityWidget
.. 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.
"""
__author__ = 'Nyall Dawson'
__date__ = '30/05/2017'
__copyright__ = 'Copyright 2017, The QGIS Project'
# This will get replaced with a git SHA1 when you do a git archive
__revision__ = '$Format:%H$'
import qgis # NOQA
from qgis.gui import QgsOpacityWidget
from qgis.PyQt.QtTest import QSignalSpy
from qgis.testing import start_app, unittest
start_app()
class TestQgsOpacityWidget(unittest.TestCase):
def testGettersSetters(self):
""" test widget getters/setters """
w = qgis.gui.QgsOpacityWidget()
w.setOpacity(0.2)
self.assertEqual(w.opacity(), 0.2)
# bad values
w.setOpacity(-0.2)
self.assertEqual(w.opacity(), 0.0)
w.setOpacity(100)
self.assertEqual(w.opacity(), 1.0)
def test_ChangedSignals(self):
""" test that signals are correctly emitted when setting opacity"""
w = qgis.gui.QgsOpacityWidget()
spy = QSignalSpy(w.opacityChanged)
w.setOpacity(0.2)
self.assertEqual(len(spy), 1)
self.assertEqual(spy[0][0], 0.2)
# bad value
w.setOpacity(100)
self.assertEqual(len(spy), 2)
self.assertEqual(spy[1][0], 1.0)
if __name__ == '__main__':
unittest.main()