Russian Qt Forum

Qt => Пользовательский интерфейс (GUI) => Тема начата: ranet от Мая 23, 2010, 16:36



Название: Локаль, ОС и QT
Отправлено: ranet от Мая 23, 2010, 16:36
Добрый день! В развитие вот этого: http://www.prog.org.ru/topic_8587_0.html
Нужно как-то самому вручную разбираться с разделителем дробной и целой части. Простейший вариант типа
Код:

    QString symb;
    float b;
    b = 3/2;

    symb = QString::number(b, 'f', 1);
    symb = symb.mid(1,1);
не прокатывает, потому что подвержен тому же самому косяку - разделитель всегда получается точка, независимо от системной локали.
Значит нужно:
1)Определить винда у нас или Linux
2)У винды наверное в реестре смотреть нужно, у Linux - пока не знаю.

Кто посоветует, как из QT определить что у нас за операционка? А то кроссплатформенности не будет.. Хочется хотя бы для Win и Linux сделать, фиг с ним с маком.


Название: Re: Локаль, ОС и QT
Отправлено: Makss от Мая 23, 2010, 17:25
Код:
#if defined(Q_OS_LINUX)
//Линукс
#elif defined(Q_OS_WIN)
//Винда
#endif


Название: Re: Локаль, ОС и QT
Отправлено: alexman от Мая 23, 2010, 19:43
QLocale QLocale::system ()   [static]
double QLocale::toDouble ( const QString & s, bool * ok = 0 ) const


Название: Re: Локаль, ОС и QT
Отправлено: ranet от Мая 23, 2010, 20:54
QLocale QLocale::system ()   [static]
double QLocale::toDouble ( const QString & s, bool * ok = 0 ) const
Похожее делать пробовал, не помогает. Установленная для приложения локаль игнорируется. Не должно так быть, но увы.. Почему и взялся костыль изобретать.


Название: Re: Локаль, ОС и QT
Отправлено: ranet от Мая 23, 2010, 20:55
Код:
#if defined(Q_OS_LINUX)
//Линукс
#elif defined(Q_OS_WIN)
//Винда
#endif
Спасибо большое!!! В любом случае пригодится


Название: Re: Локаль, ОС и QT
Отправлено: spectre71 от Мая 23, 2010, 21:49
QLocale::system();
Не важно какая операционка, не важно как как определен... разделитель дробной части!
После вызова(получения) и вы всегда имеете текущие установки(они ксатати, могли и измениться в какой-то момент, после запуска вашего приложения :))

QLocale::c();
Всегда "C" локаль. Например, разделитель дробной части - "."


Название: Re: Локаль, ОС и QT
Отправлено: alexman от Мая 24, 2010, 07:25
QLocale QLocale::system ()   [static]
double QLocale::toDouble ( const QString & s, bool * ok = 0 ) const
Похожее делать пробовал, не помогает. Установленная для приложения локаль игнорируется. Не должно так быть, но увы.. Почему и взялся костыль изобретать.
Странно, у меня все работает ???


Название: Re: Локаль, ОС и QT
Отправлено: ranet от Мая 24, 2010, 08:57
QLocale::system();
...они ксатати, могли и измениться в какой-то момент, после запуска вашего приложения :))
Вот на это и похоже, причем только для привинченных через mapper LineEdit'ов. Для вьюхи, привинченной к той же таблице через другой (еще один) mapper - все нормально. То есть если в системной локали точка - получаю точку, запятая - получаю запятую. Но LineEdit упрямо выводит  точку. Можно конечно попробовать найти где это, и подправить. Но я пока решил другим путем пойти - сделать косякоустойчивый LineEdit. А именно присобачить к сигналу textChanged ( const QString & text ) слот, который бы исправлял точку на запятую. Но не всегда, а только если в системной локали запятая. Для чего и полез разбираться какая операционка и где посмотреть разделитель. Пытался тупо разделить три на два и вытащить системный разделитель оттуда - не получилось(см код в первом посте). Идея - сделать свой класс, и от него наследоваться. Не хочется конечно так делать, но ждать пока тролли со всеми косяками разберутся - ну нафиг.


Название: Re: Локаль, ОС и QT
Отправлено: ranet от Мая 24, 2010, 09:01
QLocale QLocale::system ()   [static]
double QLocale::toDouble ( const QString & s, bool * ok = 0 ) const
Похожее делать пробовал, не помогает. Установленная для приложения локаль игнорируется. Не должно так быть, но увы.. Почему и взялся костыль изобретать.
Странно, у меня все работает ???
Рискну предположить, что ты вызываешь QLocale::toDouble ( const QString & s, bool * ok = 0 ). А я этого не делаю, у меня LineEdit привинчен через mapper к полю таблицы. И заполняется автоматически. Но с таким вот косяком.


Название: Re: Локаль, ОС и QT
Отправлено: bigirbis от Мая 24, 2010, 21:50
Исследование исходников дает право утверждать, что ситуацию может исправить данная конструкция:
Код:
mapper->setItemDelegate(new QItemDelegate(mapper));


Название: Re: Локаль, ОС и QT
Отправлено: ranet от Мая 26, 2010, 11:03
QLocale::system();
Не важно какая операционка, не важно как как определен... разделитель дробной части!
После вызова(получения) и вы всегда имеете текущие установки(они ксатати, могли и измениться в какой-то момент, после запуска вашего приложения :))

QLocale::c();
Всегда "C" локаль. Например, разделитель дробной части - "."
Спасибо, Вы и alexman натолкнули на такой способ найти текущий системный разделитель целой и дробной части:
Код:
    double a;
    QString b;
    QLocale my(QLocale::system());

    a = (3.0/2);
    b=my.toString(a);

    ui->lineEdit->setText(b);


В LineEdit он теперь выводится правильно, в соответствии с локалью. Я его с легкостью вытащу, и сделаю как собирался "костыль". Но может все-таки можно как-то без костыля попробовать обойтись? Пока предполагаю, что происходит следующее:
при загрузке дробного числа из базы скорей всего оно приходит в С-шной локали.. как и переменная a в этом примере. Может где-нибудь есть перезагружаемая функция, которая в соответствии с типом аргумента (С-локаль) выполняет преобразование в строку символов? И всандаливает точку как разделитель.. Или еще тупее - если при вызове функции преобразующей число в строку принудительно не указать локали, то она вместо системной (как должна бы) использует С-шную.


Название: Re: Локаль, ОС и QT
Отправлено: spectre71 от Мая 26, 2010, 11:40
В LineEdit он теперь выводится правильно, в соответствии с локалью. Я его с легкостью вытащу, и сделаю как собирался "костыль". Но может все-таки можно как-то без костыля попробовать обойтись? Пока предполагаю, что происходит следующее:
при загрузке дробного числа из базы скорей всего оно приходит в С-шной локали.. как и переменная a в этом примере. Может где-нибудь есть перезагружаемая функция, которая в соответствии с типом аргумента (С-локаль) выполняет преобразование в строку символов? И всандаливает точку как разделитель.. Или еще тупее - если при вызове функции преобразующей число в строку принудительно не указать локали, то она вместо системной (как должна бы) использует С-шную.

1)
Цитировать
из базы скорей всего оно приходит в С-шной локали
Зависит от вашей базы и ее методов.

2)
Цитировать
в соответствии с типом аргумента (С-локаль) выполняет преобразование в строку символов
Что куда и как преобразует?
QLocale::toString - чем не нравиться?

3)
Цитировать
она вместо системной (как должна бы) использует С-шную
Именно C-шная и должна быть поумолчанию, поскольку она неизменна.
Код:
QLocale sys1 = QLocale::system();
//
// Прошло некоторое время
//
QLocale sys2 = QLocale::system();
//
// sys1 может быть не равна sys2
// Например вы изменили в системе разделитель дробной части.

4)
Цитировать
void QLocale::setDefault ( const QLocale & locale )   [static]
Может вам это нужно?


Название: Re: Локаль, ОС и QT
Отправлено: ranet от Мая 26, 2010, 12:05

QLocale::toString - чем не нравиться?

Не нравится тем, что при заполнении LineEdit через mapper из базы toString явно не вызывается. Преобразование из дробного числа в строку происходит автоматически. При этом игнорируется системная локаль. setDefault ( const QLocale & locale )  - было первое, что я попробовал :'(


Название: Re: Локаль, ОС и QT
Отправлено: spectre71 от Мая 26, 2010, 12:11
Что за mapper?


Название: Re: Локаль, ОС и QT
Отправлено: ranet от Мая 26, 2010, 12:18
Что за mapper?
QDataWidgetMapper
Но похоже наличие именно его - не принципиально. Если сделать например так:
Код:
    double a;
    QString b;
    a= (3.0/2);
    b = b.setNum(a);
    ui->lineEdit->setText(b);
то в LineEdit тоже выведет точку несмотря на QLocale::setDefault(QLocale::system());

а если
Код:
    double a;
    QString b;
    QLocale my(QLocale::system());
    a = (3.0/2);
    b=my.toString(a);
    ui->lineEdit->setText(b);
- то запятую.. Вот и фиг его знает.. Пока наверно костыль сделаю..




Название: Re: Локаль, ОС и QT
Отправлено: spectre71 от Мая 26, 2010, 12:26
Что за mapper?
QDataWidgetMapper

Соответственно он работает с моделью(видимо QSqlQueryModel или QSqlTableModel). Которая наследник QAbstractItemModel.
Сделай своего наследника в котором, в:
virtual QVariant   data ( const QModelIndex & index, int role = Qt::DisplayRole )
Сделаешь все необходимые преобразования данных для нужных индексов, а для остальных отдашь данные от предка без изменений


Название: Re: Локаль, ОС и QT
Отправлено: ranet от Мая 26, 2010, 12:45
Что за mapper?
QDataWidgetMapper

Соответственно он работает с моделью(видимо QSqlQueryModel или QSqlTableModel). Которая наследник QAbstractItemModel.
Сделай своего наследника в котором, в:
virtual QVariant   data ( const QModelIndex & index, int role = Qt::DisplayRole )
Сделаешь все необходимые преобразования данных для нужных индексов, а для остальных отдашь данные от предка без изменений

Спасибо, попробую!!!


Название: Re: Локаль, ОС и QT
Отправлено: ranet от Июня 08, 2010, 14:56
Подумал, посравнивал поведение компонентов.. QSqlQueryModel - не при чем, она напрямую работает с вьюхой, и данные отображаются правильно. Точку в качестве разделителя вставляет явно QDataWidgetMapper.. А причина похоже в делегате по умолчанию, который использует сишную локаль.. Сейчас подумаю, чего тут можно сделать.. Придется создавать своего делегата, наследоваться от QAbstractItemDelegate. Как я представляю, делегат нужно сделать именно для маппера - LineEdit тут не совсем при делах, поскольку всего лишь честно отображает полученную строку символов. Чего получит, то и отобразит. А получит от mapper'а.. Похожего примера пока не нашел, вот например CreateEditor нужно переопределять? А если да, то чего в качестве типа Editor'а выбрать.. QString?