mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-15 00:04:00 -04:00
Allow setting width/height spin boxes to link to QgsRatioLockButton
When set, these spin boxes will automatically be updated when their accompanying spin box changes value so that the ratio is maintained.
This commit is contained in:
parent
eb5ac44b27
commit
38c8268400
@ -9,6 +9,7 @@
|
||||
|
||||
|
||||
|
||||
|
||||
class QgsRatioLockButton : QToolButton
|
||||
{
|
||||
%Docstring
|
||||
@ -42,6 +43,30 @@ class QgsRatioLockButton : QToolButton
|
||||
:rtype: bool
|
||||
%End
|
||||
|
||||
void setWidthSpinBox( QDoubleSpinBox *widget );
|
||||
%Docstring
|
||||
Registers a spin box ``widget`` as the linked "width" spin box.
|
||||
|
||||
If both a width and height spin box are linked to the button, they will automatically
|
||||
have their values updates when if the other spin box value is changed. I.e. changing the
|
||||
width spin box will automatically update the height spin box to a value which keeps the
|
||||
same locked ratio.
|
||||
|
||||
.. seealso:: setHeightSpinBox()
|
||||
%End
|
||||
|
||||
void setHeightSpinBox( QDoubleSpinBox *widget );
|
||||
%Docstring
|
||||
Registers a spin box ``widget`` as the linked "height" spin box.
|
||||
|
||||
If both a width and height spin box are linked to the button, they will automatically
|
||||
have their values updates when if the other spin box value is changed. I.e. changing the
|
||||
width spin box will automatically update the height spin box to a value which keeps the
|
||||
same locked ratio.
|
||||
|
||||
.. seealso:: setWidthSpinBox()
|
||||
%End
|
||||
|
||||
signals:
|
||||
|
||||
void lockChanged( const bool locked );
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include <QPainter>
|
||||
#include <QPushButton>
|
||||
#include <QWidget>
|
||||
#include <QDoubleSpinBox>
|
||||
|
||||
QgsRatioLockButton::QgsRatioLockButton( QWidget *parent )
|
||||
: QToolButton( parent )
|
||||
@ -48,6 +49,38 @@ void QgsRatioLockButton::buttonClicked()
|
||||
drawButton();
|
||||
}
|
||||
|
||||
void QgsRatioLockButton::widthSpinBoxChanged( double value )
|
||||
{
|
||||
if ( mUpdatingRatio || qgsDoubleNear( value, 0.0 ) || qgsDoubleNear( mPrevWidth, 0.0 )
|
||||
|| qgsDoubleNear( mPrevHeight, 0.0 ) || !mHeightSpinBox || !mLocked )
|
||||
{
|
||||
mPrevWidth = value;
|
||||
return;
|
||||
}
|
||||
|
||||
double oldRatio = mPrevHeight / mPrevWidth;
|
||||
mUpdatingRatio = true;
|
||||
mHeightSpinBox->setValue( oldRatio * value );
|
||||
mUpdatingRatio = false;
|
||||
mPrevWidth = value;
|
||||
}
|
||||
|
||||
void QgsRatioLockButton::heightSpinBoxChanged( double value )
|
||||
{
|
||||
if ( mUpdatingRatio || qgsDoubleNear( value, 0.0 ) || qgsDoubleNear( mPrevWidth, 0.0 )
|
||||
|| qgsDoubleNear( mPrevHeight, 0.0 ) || !mWidthSpinBox || !mLocked )
|
||||
{
|
||||
mPrevHeight = value;
|
||||
return;
|
||||
}
|
||||
|
||||
double oldRatio = mPrevWidth / mPrevHeight;
|
||||
mUpdatingRatio = true;
|
||||
mWidthSpinBox->setValue( oldRatio * value );
|
||||
mUpdatingRatio = false;
|
||||
mPrevHeight = value;
|
||||
}
|
||||
|
||||
void QgsRatioLockButton::changeEvent( QEvent *e )
|
||||
{
|
||||
if ( e->type() == QEvent::EnabledChange )
|
||||
@ -108,3 +141,17 @@ void QgsRatioLockButton::drawButton()
|
||||
setIconSize( currentIconSize );
|
||||
setIcon( pm );
|
||||
}
|
||||
|
||||
void QgsRatioLockButton::setWidthSpinBox( QDoubleSpinBox *widget )
|
||||
{
|
||||
mWidthSpinBox = widget;
|
||||
mPrevWidth = widget->value();
|
||||
connect( mWidthSpinBox, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsRatioLockButton::widthSpinBoxChanged );
|
||||
}
|
||||
|
||||
void QgsRatioLockButton::setHeightSpinBox( QDoubleSpinBox *widget )
|
||||
{
|
||||
mHeightSpinBox = widget;
|
||||
mPrevHeight = widget->value();
|
||||
connect( mHeightSpinBox, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsRatioLockButton::heightSpinBoxChanged );
|
||||
}
|
||||
|
@ -22,6 +22,9 @@
|
||||
#include "qgis_gui.h"
|
||||
#include "qgis.h"
|
||||
|
||||
#include <QPointer>
|
||||
class QDoubleSpinBox;
|
||||
|
||||
/** \ingroup gui
|
||||
* \class QgsRatioLockButton
|
||||
* A cross platform button subclass used to represent a locked / unlocked ratio state.
|
||||
@ -51,6 +54,30 @@ class GUI_EXPORT QgsRatioLockButton : public QToolButton
|
||||
*/
|
||||
bool locked() const { return mLocked; }
|
||||
|
||||
/**
|
||||
* Registers a spin box \a widget as the linked "width" spin box.
|
||||
*
|
||||
* If both a width and height spin box are linked to the button, they will automatically
|
||||
* have their values updates when if the other spin box value is changed. I.e. changing the
|
||||
* width spin box will automatically update the height spin box to a value which keeps the
|
||||
* same locked ratio.
|
||||
*
|
||||
* \see setHeightSpinBox()
|
||||
*/
|
||||
void setWidthSpinBox( QDoubleSpinBox *widget );
|
||||
|
||||
/**
|
||||
* Registers a spin box \a widget as the linked "height" spin box.
|
||||
*
|
||||
* If both a width and height spin box are linked to the button, they will automatically
|
||||
* have their values updates when if the other spin box value is changed. I.e. changing the
|
||||
* width spin box will automatically update the height spin box to a value which keeps the
|
||||
* same locked ratio.
|
||||
*
|
||||
* \see setWidthSpinBox()
|
||||
*/
|
||||
void setHeightSpinBox( QDoubleSpinBox *widget );
|
||||
|
||||
signals:
|
||||
|
||||
/** Emitted whenever the lock state changes.
|
||||
@ -69,10 +96,19 @@ class GUI_EXPORT QgsRatioLockButton : public QToolButton
|
||||
|
||||
bool mLocked = false;
|
||||
|
||||
QPointer< QDoubleSpinBox > mWidthSpinBox;
|
||||
double mPrevWidth = 0;
|
||||
QPointer< QDoubleSpinBox > mHeightSpinBox;
|
||||
double mPrevHeight = 0;
|
||||
bool mUpdatingRatio = false;
|
||||
|
||||
private slots:
|
||||
|
||||
void buttonClicked();
|
||||
|
||||
void widthSpinBoxChanged( double value );
|
||||
void heightSpinBoxChanged( double value );
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -115,6 +115,7 @@ ADD_PYTHON_TEST(PyQgsRasterFileWriter test_qgsrasterfilewriter.py)
|
||||
ADD_PYTHON_TEST(PyQgsRasterFileWriterTask test_qgsrasterfilewritertask.py)
|
||||
ADD_PYTHON_TEST(PyQgsRasterLayer test_qgsrasterlayer.py)
|
||||
ADD_PYTHON_TEST(PyQgsRasterColorRampShader test_qgsrastercolorrampshader.py)
|
||||
ADD_PYTHON_TEST(PyQgsRatioLockButton test_qgsratiolockbutton.py)
|
||||
ADD_PYTHON_TEST(PyQgsRectangle test_qgsrectangle.py)
|
||||
ADD_PYTHON_TEST(PyQgsRelation test_qgsrelation.py)
|
||||
ADD_PYTHON_TEST(PyQgsRelationManager test_qgsrelationmanager.py)
|
||||
|
104
tests/src/python/test_qgsratiolockbutton.py
Normal file
104
tests/src/python/test_qgsratiolockbutton.py
Normal file
@ -0,0 +1,104 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""QGIS Unit tests for QgsRatioLockButton
|
||||
|
||||
.. 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__ = '18/07/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 QgsRatioLockButton
|
||||
|
||||
from qgis.PyQt.QtWidgets import QDoubleSpinBox
|
||||
|
||||
from qgis.testing import start_app, unittest
|
||||
|
||||
start_app()
|
||||
|
||||
|
||||
class TestQgsRatioLockButton(unittest.TestCase):
|
||||
|
||||
def testLinkedWidgets(self):
|
||||
""" test linking spin boxes to combobox"""
|
||||
w = qgis.gui.QgsRatioLockButton()
|
||||
|
||||
spin_width = QDoubleSpinBox()
|
||||
spin_width.setMaximum(100000)
|
||||
spin_height = QDoubleSpinBox()
|
||||
spin_height.setMaximum(100000)
|
||||
|
||||
w.setWidthSpinBox(spin_width)
|
||||
spin_width.setValue(1000)
|
||||
self.assertEqual(spin_width.value(), 1000)
|
||||
|
||||
w.setLocked(True)
|
||||
spin_width.setValue(2000)
|
||||
self.assertEqual(spin_width.value(), 2000)
|
||||
w.setLocked(False)
|
||||
|
||||
w.setHeightSpinBox(spin_height)
|
||||
spin_width.setValue(1000)
|
||||
self.assertEqual(spin_width.value(), 1000)
|
||||
self.assertEqual(spin_height.value(), 0)
|
||||
|
||||
w.setLocked(True)
|
||||
spin_width.setValue(2000)
|
||||
self.assertEqual(spin_width.value(), 2000)
|
||||
self.assertEqual(spin_height.value(), 0)
|
||||
|
||||
spin_height.setValue(1000)
|
||||
self.assertEqual(spin_width.value(), 2000)
|
||||
self.assertEqual(spin_height.value(), 1000)
|
||||
|
||||
# ok, that was all setup tests... let's check the real thing now
|
||||
spin_width.setValue(1000)
|
||||
self.assertEqual(spin_width.value(), 1000)
|
||||
self.assertEqual(spin_height.value(), 500)
|
||||
spin_height.setValue(1000)
|
||||
self.assertEqual(spin_width.value(), 2000)
|
||||
self.assertEqual(spin_height.value(), 1000)
|
||||
|
||||
w.setLocked(False)
|
||||
spin_width.setValue(1000)
|
||||
self.assertEqual(spin_width.value(), 1000)
|
||||
self.assertEqual(spin_height.value(), 1000)
|
||||
spin_height.setValue(2000)
|
||||
self.assertEqual(spin_width.value(), 1000)
|
||||
self.assertEqual(spin_height.value(), 2000)
|
||||
|
||||
w.setLocked(True)
|
||||
spin_height.setValue(1000)
|
||||
self.assertEqual(spin_width.value(), 500)
|
||||
self.assertEqual(spin_height.value(), 1000)
|
||||
|
||||
# setting to 0 should "break" lock
|
||||
spin_height.setValue(0)
|
||||
self.assertEqual(spin_width.value(), 500)
|
||||
self.assertEqual(spin_height.value(), 0)
|
||||
spin_width.setValue(1000)
|
||||
self.assertEqual(spin_width.value(), 1000)
|
||||
self.assertEqual(spin_height.value(), 0)
|
||||
spin_height.setValue(100)
|
||||
self.assertEqual(spin_width.value(), 1000)
|
||||
self.assertEqual(spin_height.value(), 100)
|
||||
|
||||
spin_width.setValue(0)
|
||||
self.assertEqual(spin_width.value(), 0)
|
||||
self.assertEqual(spin_height.value(), 100)
|
||||
spin_height.setValue(1000)
|
||||
self.assertEqual(spin_width.value(), 0)
|
||||
self.assertEqual(spin_height.value(), 1000)
|
||||
spin_width.setValue(200)
|
||||
self.assertEqual(spin_width.value(), 200)
|
||||
self.assertEqual(spin_height.value(), 1000)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
Loading…
x
Reference in New Issue
Block a user