Archived:Improving the usability of spin boxes on Qt for Symbian touch devices
Qt Quick should be used for all UI development on mobile devices. The approach described in this article (based on QWidget) is deprecated.
Article Metadata
Tested with
Compatibility
Qt 4.6.2
Article
Overview
This article shows how to the usability of Qt spin boxes (QSpinBox) on Symbian touch devices.
Description
Qt provides QSpinBox and QDoubleSpinBox widgets that allow the user to input integer and double values, respectively. The value can be modified by clicking the up and down buttons, or by clicking on the line edit field of the spin box and entering a new value manually.
When clicking on the line edit field on Symbian devices, the user has to remove the old value either by using backspace or by selecting the entire contents of the edit field before a new value can be entered. In Symbian devices with a keyboard, this is not so much a problem as pressing up or down on the navigation keys will auto-select all the text in the edit field.
On Symbian touch devices, this additional step can be avoided by automatically selecting all text when receiving a mouse press event in the line edit (QLineEdit) widget of the spin box field; the user can proceed to input new numbers directly after touching the edit field of a spin box.
Solution
Create a custom spin box class by inheriting from QSpinBox or QDoubleSpinBox, and install an event filter to intercept mouse press events:
#include <QDoubleSpinBox>
#include <QLineEdit>
#include <QTimer>
#include <QEvent>
class MySpinBox : public QDoubleSpinBox
{
Q_OBJECT
public:
explicit MySpinBox( QWidget *parent = 0 );
~MySpinBox() {}
protected:
bool eventFilter( QObject *obj, QEvent *event );
};
MySpinBox::MySpinBox( QWidget *parent ) :
QDoubleSpinBox( parent )
{
#ifdef Q_OS_SYMBIAN
lineEdit()->installEventFilter( this );
#endif
}
bool MySpinBox::eventFilter( QObject *obj, QEvent *event )
{
if ( event->type() == QEvent::MouseButtonPress ) {
// select all content in line edit widget after 250ms
QTimer::singleShot( 250, lineEdit(), SLOT( selectAll() ) );
}
// standard event processing
return QObject::eventFilter( obj, event );
}


A problem with this solution is that the text in the virtual keyboard does not appear selected (inverted) until you move the cursor with the left or right arrow keys. Without the selection highlighting this solution is worthless. It's visualy jarring and potentially frustrating for the user to tap a key or the back space and have the entire text disappear instantly.
I'm not sure why the text doesn't appear selected. It may be that the background and foregound colors are inverted initially when the timer fires, but the keypad, or some other process, immediately reverts the colors back to appear unselected while preserving the selected range internally. I tried changing the time out value to up to a second but it made no difference.