Skip to content

Commit

Permalink
Add api to control spin box editing timeout interval
Browse files Browse the repository at this point in the history
  • Loading branch information
nyalldawson committed Dec 12, 2024
1 parent d3af853 commit b489454
Show file tree
Hide file tree
Showing 14 changed files with 196 additions and 16 deletions.
2 changes: 1 addition & 1 deletion python/PyQt6/gui/auto_additions/qgsdoublespinbox.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
QgsDoubleSpinBox.MaximumValue = QgsDoubleSpinBox.ClearValueMode.MaximumValue
QgsDoubleSpinBox.CustomValue = QgsDoubleSpinBox.ClearValueMode.CustomValue
try:
QgsDoubleSpinBox.__attribute_docs__ = {'returnPressed': 'Emitted when the Return or Enter key is used in the line edit.\n\n.. versionadded:: 3.40\n', 'textEdited': 'Emitted when the the value has been manually edited via line edit.\n\n.. versionadded:: 3.40\n', 'editingTimeout': 'Emitted when either:\n\n1. 2 seconds has elapsed since the last value change in the widget (eg last key press or scroll wheel event)\n2. or, immediately after the widget has lost focus after its value was changed.\n\nThis signal can be used to respond semi-instantly to changes in the spin box, without responding too quickly\nwhile the user in the middle of setting the value.\n\n.. versionadded:: 3.42\n'}
QgsDoubleSpinBox.__attribute_docs__ = {'returnPressed': 'Emitted when the Return or Enter key is used in the line edit.\n\n.. versionadded:: 3.40\n', 'textEdited': 'Emitted when the the value has been manually edited via line edit.\n\n.. versionadded:: 3.40\n', 'editingTimeout': 'Emitted when either:\n\n1. 2 seconds has elapsed since the last value change in the widget (eg last key press or scroll wheel event)\n2. or, immediately after the widget has lost focus after its value was changed.\n\nThis signal can be used to respond semi-instantly to changes in the spin box, without responding too quickly\nwhile the user in the middle of setting the value.\n\n.. seealso:: :py:func:`editingTimeoutInterval`\n\n.. versionadded:: 3.42\n'}
QgsDoubleSpinBox.__signal_arguments__ = {'textEdited': ['text: str'], 'editingTimeout': ['value: float']}
QgsDoubleSpinBox.__group__ = ['editorwidgets']
except (NameError, AttributeError):
Expand Down
2 changes: 1 addition & 1 deletion python/PyQt6/gui/auto_additions/qgsspinbox.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
QgsSpinBox.MaximumValue = QgsSpinBox.ClearValueMode.MaximumValue
QgsSpinBox.CustomValue = QgsSpinBox.ClearValueMode.CustomValue
try:
QgsSpinBox.__attribute_docs__ = {'returnPressed': 'Emitted when the Return or Enter key is used in the line edit\n\n.. versionadded:: 3.40\n', 'textEdited': 'Emitted when the the value has been manually edited via line edit.\n\n.. versionadded:: 3.40\n', 'editingTimeout': 'Emitted when either:\n\n1. 2 seconds has elapsed since the last value change in the widget (eg last key press or scroll wheel event)\n2. or, immediately after the widget has lost focus after its value was changed.\n\nThis signal can be used to respond semi-instantly to changes in the spin box, without responding too quickly\nwhile the user in the middle of setting the value.\n\n.. versionadded:: 3.42\n'}
QgsSpinBox.__attribute_docs__ = {'returnPressed': 'Emitted when the Return or Enter key is used in the line edit\n\n.. versionadded:: 3.40\n', 'textEdited': 'Emitted when the the value has been manually edited via line edit.\n\n.. versionadded:: 3.40\n', 'editingTimeout': 'Emitted when either:\n\n1. 2 seconds has elapsed since the last value change in the widget (eg last key press or scroll wheel event)\n2. or, immediately after the widget has lost focus after its value was changed.\n\nThis signal can be used to respond semi-instantly to changes in the spin box, without responding too quickly\nwhile the user in the middle of setting the value.\n\n.. seealso:: :py:func:`editingTimeoutInterval`\n\n.. versionadded:: 3.42\n'}
QgsSpinBox.__signal_arguments__ = {'textEdited': ['text: str'], 'editingTimeout': ['value: int']}
QgsSpinBox.__group__ = ['editorwidgets']
except (NameError, AttributeError):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,30 @@ is equal to :py:func:`~QgsDoubleSpinBox.minimum`. Typical use is to indicate tha
virtual void stepBy( int steps );


int editingTimeoutInterval() const;
%Docstring
Returns the timeout (in milliseconds) threshold for the :py:func:`~QgsDoubleSpinBox.editingTimeout` signal to be emitted
after an edit.

.. seealso:: :py:func:`setEditingTimeoutInterval`

.. versionadded:: 3.42
%End

public slots:

void setEditingTimeoutInterval( int timeout );
%Docstring
Sets the ``timeout`` (in milliseconds) threshold for the :py:func:`~QgsDoubleSpinBox.editingTimeout` signal to be emitted
after an edit.

.. seealso:: :py:func:`editingTimeoutInterval`

.. seealso:: :py:func:`editingTimeout`

.. versionadded:: 3.42
%End

signals:

void returnPressed();
Expand All @@ -173,6 +197,8 @@ Emitted when either:
This signal can be used to respond semi-instantly to changes in the spin box, without responding too quickly
while the user in the middle of setting the value.

.. seealso:: :py:func:`editingTimeoutInterval`

.. versionadded:: 3.42
%End

Expand Down
26 changes: 26 additions & 0 deletions python/PyQt6/gui/auto_generated/editorwidgets/qgsspinbox.sip.in
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,30 @@ is equal to :py:func:`~QgsSpinBox.minimum`. Typical use is to indicate that this
virtual void stepBy( int steps );


int editingTimeoutInterval() const;
%Docstring
Returns the timeout (in milliseconds) threshold for the :py:func:`~QgsSpinBox.editingTimeout` signal to be emitted
after an edit.

.. seealso:: :py:func:`setEditingTimeoutInterval`

.. versionadded:: 3.42
%End

public slots:

void setEditingTimeoutInterval( int timeout );
%Docstring
Sets the ``timeout`` (in milliseconds) threshold for the :py:func:`~QgsSpinBox.editingTimeout` signal to be emitted
after an edit.

.. seealso:: :py:func:`editingTimeoutInterval`

.. seealso:: :py:func:`editingTimeout`

.. versionadded:: 3.42
%End

signals:

void returnPressed();
Expand All @@ -161,6 +185,8 @@ Emitted when either:
This signal can be used to respond semi-instantly to changes in the spin box, without responding too quickly
while the user in the middle of setting the value.

.. seealso:: :py:func:`editingTimeoutInterval`

.. versionadded:: 3.42
%End

Expand Down
2 changes: 1 addition & 1 deletion python/gui/auto_additions/qgsdoublespinbox.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# The following has been generated automatically from src/gui/editorwidgets/qgsdoublespinbox.h
try:
QgsDoubleSpinBox.__attribute_docs__ = {'returnPressed': 'Emitted when the Return or Enter key is used in the line edit.\n\n.. versionadded:: 3.40\n', 'textEdited': 'Emitted when the the value has been manually edited via line edit.\n\n.. versionadded:: 3.40\n', 'editingTimeout': 'Emitted when either:\n\n1. 2 seconds has elapsed since the last value change in the widget (eg last key press or scroll wheel event)\n2. or, immediately after the widget has lost focus after its value was changed.\n\nThis signal can be used to respond semi-instantly to changes in the spin box, without responding too quickly\nwhile the user in the middle of setting the value.\n\n.. versionadded:: 3.42\n'}
QgsDoubleSpinBox.__attribute_docs__ = {'returnPressed': 'Emitted when the Return or Enter key is used in the line edit.\n\n.. versionadded:: 3.40\n', 'textEdited': 'Emitted when the the value has been manually edited via line edit.\n\n.. versionadded:: 3.40\n', 'editingTimeout': 'Emitted when either:\n\n1. 2 seconds has elapsed since the last value change in the widget (eg last key press or scroll wheel event)\n2. or, immediately after the widget has lost focus after its value was changed.\n\nThis signal can be used to respond semi-instantly to changes in the spin box, without responding too quickly\nwhile the user in the middle of setting the value.\n\n.. seealso:: :py:func:`editingTimeoutInterval`\n\n.. versionadded:: 3.42\n'}
QgsDoubleSpinBox.__signal_arguments__ = {'textEdited': ['text: str'], 'editingTimeout': ['value: float']}
QgsDoubleSpinBox.__group__ = ['editorwidgets']
except (NameError, AttributeError):
Expand Down
2 changes: 1 addition & 1 deletion python/gui/auto_additions/qgsspinbox.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# The following has been generated automatically from src/gui/editorwidgets/qgsspinbox.h
try:
QgsSpinBox.__attribute_docs__ = {'returnPressed': 'Emitted when the Return or Enter key is used in the line edit\n\n.. versionadded:: 3.40\n', 'textEdited': 'Emitted when the the value has been manually edited via line edit.\n\n.. versionadded:: 3.40\n', 'editingTimeout': 'Emitted when either:\n\n1. 2 seconds has elapsed since the last value change in the widget (eg last key press or scroll wheel event)\n2. or, immediately after the widget has lost focus after its value was changed.\n\nThis signal can be used to respond semi-instantly to changes in the spin box, without responding too quickly\nwhile the user in the middle of setting the value.\n\n.. versionadded:: 3.42\n'}
QgsSpinBox.__attribute_docs__ = {'returnPressed': 'Emitted when the Return or Enter key is used in the line edit\n\n.. versionadded:: 3.40\n', 'textEdited': 'Emitted when the the value has been manually edited via line edit.\n\n.. versionadded:: 3.40\n', 'editingTimeout': 'Emitted when either:\n\n1. 2 seconds has elapsed since the last value change in the widget (eg last key press or scroll wheel event)\n2. or, immediately after the widget has lost focus after its value was changed.\n\nThis signal can be used to respond semi-instantly to changes in the spin box, without responding too quickly\nwhile the user in the middle of setting the value.\n\n.. seealso:: :py:func:`editingTimeoutInterval`\n\n.. versionadded:: 3.42\n'}
QgsSpinBox.__signal_arguments__ = {'textEdited': ['text: str'], 'editingTimeout': ['value: int']}
QgsSpinBox.__group__ = ['editorwidgets']
except (NameError, AttributeError):
Expand Down
26 changes: 26 additions & 0 deletions python/gui/auto_generated/editorwidgets/qgsdoublespinbox.sip.in
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,30 @@ is equal to :py:func:`~QgsDoubleSpinBox.minimum`. Typical use is to indicate tha
virtual void stepBy( int steps );


int editingTimeoutInterval() const;
%Docstring
Returns the timeout (in milliseconds) threshold for the :py:func:`~QgsDoubleSpinBox.editingTimeout` signal to be emitted
after an edit.

.. seealso:: :py:func:`setEditingTimeoutInterval`

.. versionadded:: 3.42
%End

public slots:

void setEditingTimeoutInterval( int timeout );
%Docstring
Sets the ``timeout`` (in milliseconds) threshold for the :py:func:`~QgsDoubleSpinBox.editingTimeout` signal to be emitted
after an edit.

.. seealso:: :py:func:`editingTimeoutInterval`

.. seealso:: :py:func:`editingTimeout`

.. versionadded:: 3.42
%End

signals:

void returnPressed();
Expand All @@ -173,6 +197,8 @@ Emitted when either:
This signal can be used to respond semi-instantly to changes in the spin box, without responding too quickly
while the user in the middle of setting the value.

.. seealso:: :py:func:`editingTimeoutInterval`

.. versionadded:: 3.42
%End

Expand Down
26 changes: 26 additions & 0 deletions python/gui/auto_generated/editorwidgets/qgsspinbox.sip.in
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,30 @@ is equal to :py:func:`~QgsSpinBox.minimum`. Typical use is to indicate that this
virtual void stepBy( int steps );


int editingTimeoutInterval() const;
%Docstring
Returns the timeout (in milliseconds) threshold for the :py:func:`~QgsSpinBox.editingTimeout` signal to be emitted
after an edit.

.. seealso:: :py:func:`setEditingTimeoutInterval`

.. versionadded:: 3.42
%End

public slots:

void setEditingTimeoutInterval( int timeout );
%Docstring
Sets the ``timeout`` (in milliseconds) threshold for the :py:func:`~QgsSpinBox.editingTimeout` signal to be emitted
after an edit.

.. seealso:: :py:func:`editingTimeoutInterval`

.. seealso:: :py:func:`editingTimeout`

.. versionadded:: 3.42
%End

signals:

void returnPressed();
Expand All @@ -161,6 +185,8 @@ Emitted when either:
This signal can be used to respond semi-instantly to changes in the spin box, without responding too quickly
while the user in the middle of setting the value.

.. seealso:: :py:func:`editingTimeoutInterval`

.. versionadded:: 3.42
%End

Expand Down
12 changes: 11 additions & 1 deletion src/gui/editorwidgets/qgsdoublespinbox.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ QgsDoubleSpinBox::QgsDoubleSpinBox( QWidget *parent )

mLastEditTimer = new QTimer( this );
mLastEditTimer->setSingleShot( true );
mLastEditTimer->setInterval( 2000 );
mLastEditTimer->setInterval( 1000 );
connect( mLastEditTimer, &QTimer::timeout, this, &QgsDoubleSpinBox::onLastEditTimeout );
}

Expand Down Expand Up @@ -141,6 +141,16 @@ void QgsDoubleSpinBox::stepBy( int steps )
QDoubleSpinBox::stepBy( steps );
}

int QgsDoubleSpinBox::editingTimeoutInterval() const
{
return mLastEditTimer->interval();
}

void QgsDoubleSpinBox::setEditingTimeoutInterval( int timeout )
{
mLastEditTimer->setInterval( timeout );
}

void QgsDoubleSpinBox::changed( double value )
{
mLineEdit->setShowClearButton( shouldShowClearForValue( value ) );
Expand Down
25 changes: 25 additions & 0 deletions src/gui/editorwidgets/qgsdoublespinbox.h
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,29 @@ class GUI_EXPORT QgsDoubleSpinBox : public QDoubleSpinBox
void paintEvent( QPaintEvent *e ) override;
void stepBy( int steps ) override;

/**
* Returns the timeout (in milliseconds) threshold for the editingTimeout() signal to be emitted
* after an edit.
*
* \see setEditingTimeoutInterval()
*
* \since QGIS 3.42
*/
int editingTimeoutInterval() const;

public slots:

/**
* Sets the \a timeout (in milliseconds) threshold for the editingTimeout() signal to be emitted
* after an edit.
*
* \see editingTimeoutInterval()
* \see editingTimeout()
*
* \since QGIS 3.42
*/
void setEditingTimeoutInterval( int timeout );

signals:

/**
Expand All @@ -171,6 +194,8 @@ class GUI_EXPORT QgsDoubleSpinBox : public QDoubleSpinBox
* This signal can be used to respond semi-instantly to changes in the spin box, without responding too quickly
* while the user in the middle of setting the value.
*
* \see editingTimeoutInterval()
*
* \since QGIS 3.42
*/
void editingTimeout( double value );
Expand Down
12 changes: 11 additions & 1 deletion src/gui/editorwidgets/qgsspinbox.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ QgsSpinBox::QgsSpinBox( QWidget *parent )

mLastEditTimer = new QTimer( this );
mLastEditTimer->setSingleShot( true );
mLastEditTimer->setInterval( 2000 );
mLastEditTimer->setInterval( 1000 );
connect( mLastEditTimer, &QTimer::timeout, this, &QgsSpinBox::onLastEditTimeout );
}

Expand Down Expand Up @@ -257,6 +257,16 @@ void QgsSpinBox::stepBy( int steps )
QSpinBox::stepBy( steps );
}

int QgsSpinBox::editingTimeoutInterval() const
{
return mLastEditTimer->interval();
}

void QgsSpinBox::setEditingTimeoutInterval( int timeout )
{
mLastEditTimer->setInterval( timeout );
}

int QgsSpinBox::frameWidth() const
{
return style()->pixelMetric( QStyle::PM_DefaultFrameWidth );
Expand Down
25 changes: 25 additions & 0 deletions src/gui/editorwidgets/qgsspinbox.h
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,29 @@ class GUI_EXPORT QgsSpinBox : public QSpinBox
QValidator::State validate( QString &input, int &pos ) const override;
void stepBy( int steps ) override;

/**
* Returns the timeout (in milliseconds) threshold for the editingTimeout() signal to be emitted
* after an edit.
*
* \see setEditingTimeoutInterval()
*
* \since QGIS 3.42
*/
int editingTimeoutInterval() const;

public slots:

/**
* Sets the \a timeout (in milliseconds) threshold for the editingTimeout() signal to be emitted
* after an edit.
*
* \see editingTimeoutInterval()
* \see editingTimeout()
*
* \since QGIS 3.42
*/
void setEditingTimeoutInterval( int timeout );

signals:

/**
Expand All @@ -162,6 +185,8 @@ class GUI_EXPORT QgsSpinBox : public QSpinBox
* This signal can be used to respond semi-instantly to changes in the spin box, without responding too quickly
* while the user in the middle of setting the value.
*
* \see editingTimeoutInterval()
*
* \since QGIS 3.42
*/
void editingTimeout( int value );
Expand Down
13 changes: 8 additions & 5 deletions tests/src/gui/testqgsdoublespinbox.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -216,31 +216,34 @@ void TestQgsDoubleSpinBox::editingTimeout()
spin.setMaximum( 1000 );
spin.setSingleStep( 1 );
spin.setFocus();
QCOMPARE( spin.editingTimeoutInterval(), 1000 );
spin.setEditingTimeoutInterval( 300 );
QCOMPARE( spin.editingTimeoutInterval(), 300 );

QSignalSpy spy( &spin, &QgsDoubleSpinBox::editingTimeout );
spin.selectAll();
QTest::keyClicks( &spin, QStringLiteral( "3" ) );
QTest::qWait( 500 );
QTest::qWait( 100 );
// too short, should not be signal
QCOMPARE( spy.count(), 0 );
QTest::qWait( 2000 );
QTest::qWait( 400 );
// long enough, signal should have been emitted
QCOMPARE( spy.count(), 1 );
QCOMPARE( spy.at( 0 ).at( 0 ).toInt(), 3 );

QTest::keyClicks( &spin, QStringLiteral( "2" ) );
QCOMPARE( spy.count(), 1 );
QTest::qWait( 2500 );
QTest::qWait( 400 );
// long enough, signal should have been emitted
QCOMPARE( spy.count(), 2 );
QCOMPARE( spy.at( 1 ).at( 0 ).toInt(), 32 );

// no signal if value not changed
QTest::keyClicks( &spin, QStringLiteral( "4" ) );
QTest::qWait( 500 );
QTest::qWait( 100 );
QCOMPARE( spy.count(), 2 );
QTest::keyPress( &spin, Qt::Key_Backspace );
QTest::qWait( 2500 );
QTest::qWait( 400 );
// no signal, value did not change
QCOMPARE( spy.count(), 2 );
}
Expand Down
Loading

0 comments on commit b489454

Please sign in to comment.