Название: И снова про кодировки... Отправлено: Гурман от Октября 12, 2015, 21:27 Кто-нибудь знает хотя бы способ получить имя текущей кодировки локали? Может я просто его прозевал... Чтобы не "System" отдало, а "Windows-1251" и т.д. - что на самом деле используется.
Название: Re: И снова про кодировки... Отправлено: ammaximus от Октября 13, 2015, 10:18 qDebug ()<< QTextCodec::codecForName (nl_langinfo (CODESET))-> name()
Название: Re: И снова про кодировки... Отправлено: Гурман от Октября 13, 2015, 14:38 nl_langinfo (CODESET) нет в MinGW :-(Название: Re: И снова про кодировки... Отправлено: Гурман от Октября 14, 2015, 00:11 В общем, пришлось колбасить аналогично QtCreator выбор кодировки для загружаемых файлов. Как-то Тролли с этим делом недоделали, и наверняка сами не рады.
Но есть другая проблема, тоже кодировочная, поэтому ветку отдельно не создаю. Надеюсь, заглянут и увидят те, кто уже такое решал. Общая обстановка такая, что моё ПО может работать с одними и теми же файлами как в Windows, так и в Linux (а в будущем и в других ОС). Есть пользовательские файлы с 8-и битными текстами, кодировки которым я настраиваю явным указанием. С разными кодировками текстов я справляюсь при помощи QTextStream::setCodec( QTextCodec::codecForName(<выбранное юзером имя кодека>) ). Если в Linux при указать кодировку "Windows-1251", то русские тексты сохраняются честно в UTF-8, и всё замечательно. Но есть еще файлы настроек, базирующиеся на QSettings, для переносимости используется формат INI. Настройки тоже могут использоваться в разных ОС с разными кодировками 8-и битных символов. И конечно, настройки могут содержать русские строки. Вот тут проблема - если я указываю setIniCodec("Windows-1251"), то Qt тупо сохраняет русское содержимое настроек в виндозной кодировке, в виде 8-и битных символов, а вовсе не в UTF-8. Разумеется, потом в текстовом редакторе в Linux эти строки поправить нельзя, если что. Но самое обидное - это то, что при загрузке QSettings таких настроек в Linux приложении, они... загружаются в Windows кодировке. То есть, на выход QSettings настройки кодирует, но на вход не декодирует. Буквально - я в Linux набираю в настройках приложения строку по-русски, закрываю приложение, открываю - строка в кодировке 1251 (в файле разумеется тоже в 1251 записана). Пока не ясно, как это побороть. Кто эту проблему решал, каким образом? Может я зевнул чего-то? Может есть способ заставить QSettings восстанавливать кодировку в "System" при загрузке INI-файлов? Название: Re: И снова про кодировки... Отправлено: ammaximus от Октября 14, 2015, 08:49 К прошлому вопросу:
#ifdef windows qDebug()《 GetACP (); Так и не понял зачем нужна "текстовка" кодека, тем более как это поможет кодировать файлы. Если это ваш соб твенный формат, добавьте кодировку внутрь, как xml. Даже у ворда есть выбор кодировки, если он сам не распознал. Если простые текстовые файлы, почему бы не использовать System кодек? Им тоже можно и писать и читать. Еще хотелось бы отметить, что запуск ПО под определенной ОС не означает, что все загружаемые файлы будут в кодировке этой ОС. Так что определенные защиты нужны. Название: Re: И снова про кодировки... Отправлено: ammaximus от Октября 14, 2015, 09:09 2. Чем вызван выбор ини? Нужно переносить настройки между машинами или загружать по сети? Я пользуюсь простым КуСеттингс в кроссплатформенных приложениях и мне безразлично как что он там сохраняет, лишь бы записывала та же программа, что и читает.
Название: Re: И снова про кодировки... Отправлено: Гурман от Октября 14, 2015, 13:39 Я пользуюсь простым КуСеттингс в кроссплатформенных приложениях и мне безразлично как что он там сохраняет, лишь бы записывала та же программа, что и читает. А мне нет. У меня текстовые файлы и настройки могут быть сохранены приложением в Windows, а использованы в Linux или в будущем в другой ОС. Поэтому формат INI - он поддерживается QSettings во всех ОС. И просьба не уводить в сторону - у меня давно отлажена работа настроек, используется почти в двух десятках плагинов, ничего изменять я не буду. Вопрос только в 8-и битных кодировках, их поддержке в QSettings. Если нечего сказать по существу - лучше ничего не говорить. Название: Re: И снова про кодировки... Отправлено: Igors от Октября 14, 2015, 13:50 А если записать кодировку как строку в самой QSettings?
Название: Re: И снова про кодировки... Отправлено: Bepec от Октября 14, 2015, 14:52 Установить кодировку UTF8/16 везде и не париться не вариант?
Название: Re: И снова про кодировки... Отправлено: Гурман от Октября 14, 2015, 15:33 А если записать кодировку как строку в самой QSettings? Я записываю, но этого мало. Это просто передача информации о том, какой кодировке был создан файл настроек. Если указать эту кодировку в setIniCodec() при загрузке, то именно в такой кодировке настройки и загружаются. А надо, чтобы они загрузились с кодировкой "System". Название: Re: И снова про кодировки... Отправлено: Гурман от Октября 14, 2015, 16:51 Установить кодировку UTF8/16 везде и не париться не вариант? Тут мне кое-что не понятно. По-умолчанию Qt на самом деле и так вроде бы в UTF сохраняет, нет? Тут такой момент - у меня многие строковые настройки в приложении используются в виде const char*. Это необходимо для взаимодействия со старыми библиотеками на чистом Си. Получать const char* приходится через QByteArray QString::toLocal8Bit() и далее const char* QByteArray::constData(). Но toLocal8Bit() использует установленный кодек локали для 8-и битных символов. Если файл настроек был сохранен в Windows, и кодек явно не прописать с помощью QTextCodec::setCodecForLocale( QTextCodec::codecForName("Windows-1251") ), то в Linux вызов toLocal8Bit возвращает "кракозябры" (постоянно это нельзя делать - перестают работать русские имена файлов и каталогов). Не понятно - почему декодирование работает именно с кодеком Windows-1251, если русские буквы были сохранены в UTF. Или по-умолчанию QSettings не в UTF сохраняет? Что это тогда? При установке кодировки UTF для INI с помощью QSettings::setIniCodec() русские буквы не загружаются в QString, в строке после загрузки настроек оказываются кодированные символы. О чем и вопрос был. Название: Re: И снова про кодировки... Отправлено: Bepec от Октября 14, 2015, 17:19 QString хранит данные в utf16, но при получении из QSettings они будут в той кодировке, что записаны.
Провел эксперимент, спокойно сохраняет - восстанавливает, данные хранятся в utf8, как и указано в кодеке. PS по умолчанию она локаль использует стандартную, а не utf8. Название: Re: И снова про кодировки... Отправлено: Гурман от Октября 14, 2015, 18:28 У меня с UTF-8 получились другие чудеса - все данные, которые хранятся в виде QVariant, напрочь слетели. Например в QVariant хранятся цвета QColor - там теперь ерунда какая-то, и при загрузке старых настроек все цвета искажены.
Название: Re: И снова про кодировки... Отправлено: Bepec от Октября 14, 2015, 19:11 Ну как бы логично, сохраняли вы в другой кодировке, а читать пытаетесь в utf8. Ясен пень что там бред будет.
Вам нужно старые настройки конвертировать в новый формат. Или же просто запилить конвертирование автоматическое при чтении. PS что бы там не писалось, QSettings это просто строки в нужной кодировке. Сменили кодировку - строки нечитабельны. Название: Re: И снова про кодировки... Отправлено: Гурман от Октября 14, 2015, 19:31 С UTF-8 тоже хрень получается. Сохранил в Windows настройки в UTF-8, проверил HEX-редактором - всё правильно, UTF-8. Загрузил в приложение, все строки читаются. Скопировал файл в Linux, там проверил - русские буквы в UTF-8, в HEX-редакторе тоже самое содержимое. Просматриваю файл вьюером DoubleCommander, он умеет автоматом UTF-8 определять - всё читается по-русски. Запускаю приложение в Linux, эти настройки в него загружаются - в строках бред. Причём не только после toLocal8Bit() но и просто в QString. Исходники одни и те же... Кодек устанавливаю первой строкой в конструкторе класса настроек, который наследует QSettings, но это уже после инициализации родительского класса QSettings.
Код: VariantSettings::VariantSettings( QString filename, QObject* parent ) : В Windows всё работает, как следует. В Linux если ввести в поле русский текст и сохранить настройки, то текст записывается в UTF-8. Но после запуска приложения из этой настройки читается бред. Попробую собрать в Linux ваш пример. В Windows он у меня нормально отработал. PS: проверил - работает правильно... Ну как бы логично, сохраняли вы в другой кодировке, а читать пытаетесь в utf8. Ясен пень что там бред будет. Логично было бы для строк с кириллицей... Но испортились те настройки, которые кириллицу не содержали. Откуда она, например, в QColor? Название: Re: И снова про кодировки... Отправлено: Bepec от Октября 14, 2015, 20:21 QColor будет примерно как
QRGB(00,ff,ff) Меняем кодировку и получаем џ|nу(00,ff,ff) Парсер QVariant охреневает :D Название: Re: И снова про кодировки... Отправлено: Гурман от Октября 14, 2015, 23:21 Да черт с ними, с цветами...
В приложении Linux глухо не работает UTF-8 при загрузке настроек. В QString загружаются байты, без декодирования. В приложении Windows глухо работает как надо. Исходники идентичны. Разница в ОС, и в разрядности ОС - Windows 32 бит, Linux 64 бит. Сборка Qt и сборка самого приложения в Linux тоже 64 бит. Но тестовый пример работает. Уже два бубна протёр в поисках что может влиять... Даже выносил setIniCodec() из конструктора на после создания объекта - не помогает. :( Может в Qt 64 есть какая-то дыра? ... Вроде кое-как добился загрузки в QString из UTF-8 в Linux. Но toLocal8Bit всё равно почему-то не работает без явной установки кодировки с помощью setCodecForLocale(). Название: Re: И снова про кодировки... Отправлено: Racheengel от Октября 15, 2015, 01:23 Наличие/отсутствие byte order mark (BOM) рассматривалось?
Название: Re: И снова про кодировки... Отправлено: Гурман от Октября 15, 2015, 02:32 Нет. А толку? Это же всё инкапсулировано в QSettings. Хотя я могу точно сказать, что bom там не записывается.
Название: Re: И снова про кодировки... Отправлено: Bepec от Октября 15, 2015, 04:11 приводите версию и ветку линуха, мб и поможем.
PS зачем вам toLocal8Bit? при использовании utf8 он нафиг не нужен ) Название: Re: И снова про кодировки... Отправлено: Гурман от Октября 15, 2015, 13:19 приводите версию и ветку линуха, мб и поможем. PS зачем вам toLocal8Bit? при использовании utf8 он нафиг не нужен ) Linux Kubuntu 14.04. Я сам думаю, что с системой что-то не так. В Linux строки из QString, которые были загружены QSettings в UTF-8, читаются только после... установки кодировки локали Windows. На самом деле, это не смертельно - локаль пользователю всё равно придётся выбирать, потому что она нужна для загрузки в QPlainText 8-и битных текстов данных, там в UTF-8 перейти пока нельзя. Значит я могу перед преобразованием менять локаль, затем возвращать System. Но такой поведение выглядит странно... Кроме как при загрузке в QPlainText и setCodecForTr(), "Windows-1251" нигде в приложении не используется. Зачем toLocal8Bit я раньше писал - нужны const char* варианты строк для работы со старыми С-библиотеками. Вот тут в Linux и лезут косяки с кодировками. В Windows нет проблем. Название: Re: И снова про кодировки... Отправлено: Гурман от Октября 19, 2015, 18:26 Локальная проблема была найдена - при сборке плагинов не выполнялись действия в QMAKE_POST_LINK из-за того, что там остались двойные кавычки в групповом имени файлов для удаления. То есть, в Linux сборке было
Код: QMAKE_POST_LINK = $$QMAKE_DEL_FILE \"$$DESTDIR/$${TMPFILE}*\" Код: QMAKE_POST_LINK = $$QMAKE_DEL_FILE $$DESTDIR/$${TMPFILE}* Соответственно старые файлы не удалялись, новые поэтому не создавались, и всё ехало... И причем ведь, qmake честно генерит команду rm -f .... В результате всё проскакивает молча, шито-крыто, а потом очень странно не работает. Но глобально проблема не решена - пришлось делать вызовы для принудительной установки кодировки, в которой были сохранены настройки, и для возврата System после toLocal8Bit. Поэтому тэг РЕШЕНО в заголовок не добавляю. |