Countries and various areas around the world have different formatting conventions for fields like dates, times, numbers, and currency. The set of rules used in a particular region or associated with a specific language is called a locale. The QLocale class is used to format data based on the combination of a given language or country.
#include <QtCore>
#include <QtGui>
class MainWindow : public QWidget
{
public:
MainWindow();
private:
QComboBox *localeCombo;
QLineEdit *currency;
QLineEdit *number;
QLineEdit *firstDay;
QLineEdit *dateLong;
QLineEdit *dateShort;
void localeChanged(int index);
};
The MainWindow class declaration contains several line edit fields which are updated in the localeChanged() slot method based on the user selected locale.
MainWindow::MainWindow()
{
setMinimumSize(600, 400);
QLabel *localeLabel = new QLabel();
localeLabel->setText("Select Locale Setting:");
QLocale de(QLocale::German, QLocale::Germany);
QLocale us(QLocale::English, QLocale::UnitedStates);
QLocale uk(QLocale::English, QLocale::UnitedKingdom);
QLocale fr(QLocale::French, QLocale::France);
QLocale in(QLocale::Hindi, QLocale::India);
QLocale pe(QLocale::Spanish, QLocale::Peru);
QLocale es(QLocale::Spanish, QLocale::Spain);
QLocale jp(QLocale::Japanese, QLocale::Japan);
localeCombo = new QComboBox;
localeCombo->addItem("German/Germany", de);
localeCombo->addItem("English/UnitedStates", us);
localeCombo->addItem("English/UnitedKingdom", uk);
localeCombo->addItem("French/France", fr);
localeCombo->addItem("Hindi/India", in);
localeCombo->addItem("Spanish/Peru", pe);
localeCombo->addItem("Spanish/Spain", es);
localeCombo->addItem("Japanese/Japan", jp);
QLabel *currencyLabel = new QLabel(
"Currency with Symbol:");
QLabel *numberLabel = new QLabel(
"Floating Point Number:");
QLabel *firstDayLabel = new QLabel(
"First Day Of Week:");
QLabel *dateLongLabel = new QLabel(
"Long Date Format:");
QLabel *dateShortLabel = new QLabel(
"Short Date Format:");
currency = new QLineEdit();
currency->setReadOnly(true);
number = new QLineEdit();
number->setReadOnly(true);
firstDay = new QLineEdit();
firstDay->setReadOnly(true);
dateLong = new QLineEdit();
dateLong->setReadOnly(true);
dateShort = new QLineEdit();
dateShort->setReadOnly(true);
QPushButton *pb_1 = new QPushButton();
pb_1->setText("Close");
// layout
QGridLayout *grid1 = new QGridLayout();
grid1->setVerticalSpacing(15);
grid1->addWidget(localeLabel, 1, 1);
grid1->addWidget(localeCombo, 1, 2, 1, 3);
grid1->addItem(new QSpacerItem(200, 35,
QSizePolicy::Fixed, QSizePolicy::Fixed), 2, 3);
grid1->addWidget(currencyLabel, 3, 1);
grid1->addWidget(currency, 3, 2);
grid1->addWidget(numberLabel, 5, 1);
grid1->addWidget(number, 5, 2);
grid1->addWidget(firstDayLabel, 7, 1);
grid1->addWidget(firstDay, 7, 2);
grid1->addWidget(dateLongLabel, 9, 1);
grid1->addWidget(dateLong, 9, 2);
grid1->addWidget(dateShortLabel, 11, 1);
grid1->addWidget(dateShort, 11, 2);
grid1->addItem(new QSpacerItem(0, 0,
QSizePolicy::Expanding,
QSizePolicy::Expanding), 13, 3);
QHBoxLayout *layout1 = new QHBoxLayout();
layout1->addStretch();
layout1->addWidget(pb_1);
layout1->addStretch();
QVBoxLayout *layoutMain = new QVBoxLayout(this);
layoutMain->setContentsMargins(30, 40, 30, 15);
layoutMain->addLayout(grid1);
layoutMain->addLayout(layout1);
connect(localeCombo,
cs_mp_cast<int>(&QComboBox::currentIndexChanged),
this, &MainWindow::localeChanged);
connect(pb_1, &QPushButton::clicked,
this, &QWidget::close);
localeCombo->setCurrentIndex(1);
this->localeChanged(localeCombo->currentIndex());
}
The first section of this code creates several QLocale objects. The first value is an enum which indicates the spoken language in the region. The second value is the country. Looking at lines 13 and 14 we have defined the language of Spanish is spoken in both Peru and Spain. It is the combination of the language and the country which will define the various locale settings. For example, in Peru the currency symbol is “S/” and in Spain it is “€”.
On lines 18 through 25 the addItem() method is called with two arguments. The string data is what the user will see in the combo box. The locale object will converted to a QVariant and stored in the item data for the QComboBox.
The code from lines 27 to 93 are used to set up the user interface and the layout.
On line 103 we are calling localeChanged() to display the currency, numbers, and date fields for the default locale of QLocale::UnitedStates since the current index was set to a value of one.
Signal / Slot Connections
The call to connect() on line 95 in the previous block of code is a Signal/Slot connection. When the user selects a different locale in the “Select Locale Setting” combo box, the following slot method will be invoked.
void MainWindow::localeChanged(int index)
{
QLocale locale = localeCombo->itemData(index).toLocale();
currency->setText(locale.toCurrencyString(130729.47));
number->setText(locale.toString(12345678.90, 'f', 2));
Qt::DayOfWeek dow = locale.firstDayOfWeek();
firstDay->setText(locale.dayName(dow));
dateLong->setText(locale.toString(QDate::currentDate(),
QLocale::LongFormat));
dateShort->setText(locale.toString(QDate::currentDate(),
QLocale::ShortFormat));
}
Line 3 creates a new QLocale object which is used in the subsequent lines of code in this method. Let’s unpack how the locale object is created.
The value for index will be received as a parameter on line 1 when this slot is invoked. This value represents the currently selected element in the “Select Locale Setting” combo box. Elements are numbered starting with zero. The signal in our connection is triggered when the index value changes, since we are connected to the QComboBox::currentIndexChanged signal. When this signal is emitted it will invoke our slot and pass the new index value. Refer to examples 8 and 15 for information about the call to cs_mp_cast().
On line 3 we pass the new index value to the QComboBox method itemData(). This method returns a QVariant object which contains the locale object we stored in the calls to addItem() on lines 18 through 25 in the previous block of code. Now we need to convert the QVariant back to a QLocale object. This is done by calling toLocale().
As an example, suppose the combo box selection was “Spanish/Spain”. The QLocale object named es will be returned. The language/country rules for this object will be used to display the currency, numbers, and date fields.
The obvious question you might be asking, is where do the language/country rules come from? The rules are defined as part of the Unicode standard. The CopperSpice Core library contains internal tables which were created from the Unicode standard and are part of the implementation of the QLocale class.
Main Function
Since the source code for main() has not changed there is no need to show it again. Refer to example 3 or download the full source for this example.
Running the Example
To build and run this example use the same CMake build file and commands as we showed for the first example. The only suggested modification is on line 2 of the CMakeLists.txt file, change “example_1” to “example_40”.