Customizing Qt Widgets
In some cases, we find that a Qt widget requires more customization than is possible by setting its properties in Qt Designer or by calling its functions. A simple and direct solution is to subclass the relevant widget class and adapt it to suit our needs.
Figure 5.1. The HexSpinBox widget

In this section, we will develop a hexadecimal spin box to show how this works. QSpinBox only supports decimal integers, but by subclassing it's quite easy to make it accept and display hexadecimal values.
#ifndef HEXSPINBOX_H
#define HEXSPINBOX_H
#include <qspinbox.h>
class HexSpinBox : public QSpinBox
{
public:
HexSpinBox(QWidget *parent, const char *name = 0);
protected:
QString mapValueToText(int value);
int mapTextToValue(bool *ok);
};
#endif
The HexSpinBox inherits most of its functionality from QSpinBox. It provides a typical constructor and reimplements two virtual functions from QSpinBox. Since the class doesn't define its own signals and slots, it doesn't need the Q_ OBJECT macro.
#include <qvalidator.h>
#include "hexspinbox.h"
HexSpinBox::HexSpinBox(QWidget *parent, const char *name)
: QSpinBox(parent, name)
{
QRegExp regExp("[0-9A-Fa-f]+");
setValidator(new QRegExpValidator(regExp, this));
setRange(0, 255);
}
The user can modify a spin box's current value either by clicking its up and down arrows or by typing a value into the spin box's line editor. In the latter case, we want to restrict the user's input to legitimate hexadecimal numbers. To achieve this, we use a QRegExpValidator that accepts one or more characters from the ranges '0' to '9', 'A' to 'F', and 'a' to 'f'. We also set the default range to be 0 to 255 (0x00 to 0xFF), which is more appropriate for a hexadecimal spin box than QSpinBox's default of 0 to 99.
QString HexSpinBox::mapValueToText(int value)
{
return QString::number(value, 16).upper();
}
The mapValueToText() function converts an integer value to a string. QSpinBox calls it to update the editor part of the spin box when the user presses the spin box's up or down arrows. We use the static function QString::number() with a second argument of 16 to convert the value to lower-case hexadecimal, and call QString::upper() on the result to make it upper-case.
int HexSpinBox::mapTextToValue(bool *ok)
{
return text().toInt(ok, 16);
}
The mapTextToValue() function performs the reverse conversion, from a string to an integer value. It is called by QSpinBox when the user types a value into the editor part of the spin box and presses Enter. We use the QString::toInt() function to attempt to convert the current text (returned by QSpinBox::text()) to an integer value, again using base 16.Chapter 4 when we subclassed QTable and reimplemented createEditor() and endEdit().