![]() |
Здравствуйте, гость ( Вход | Регистрация )
![]() ![]() |
![]() |
Steklova Olga |
![]()
Сообщение
#1
|
![]() Участник ![]() ![]() Группа: Участник Сообщений: 198 Регистрация: 27.9.2011 Из: Санкт-Петербург Пользователь №: 2912 Спасибо сказали: 5 раз(а) Репутация: ![]() ![]() ![]() |
Здравствуйте
![]() Вопрос 1. Почему у меня некорректно (крокозябрами) отображается русский текст из BLOB в колонке QTableView ? Вопрос 2. Как сделать, чтобы текст в колонке с BLOB не отображался весь в одну строку, а переносился ? Вопрос 3. Что делать с шириной колонки для поля BLOB ? Ограничивать ? Мои предположения: - не в той кодировке пишу данные в БД ? - не везде, где надо, правильно указала кодировку ? - мне необходимо создать делегат, чтобы в каждой ячейке QTableView колонки с BLOB был виджет QTextEdit ? (Сейчас никакого делегата для этого QTableView у меня нет.) Делаю так: в скриптах при создании БД:
В IBExpert при регистрации БД указываю: - Charset = WIN1251 - оставляю не включенным (как по умолчанию и есть) флаг Do NOT perform conversion from/to UTF8 - Font Characters Set = RUSSIAN_CHARSET При этом в IBExpert данные поля BLOB таблицы отображаются корректно, как и при включенном флаге (не совсем понимаю, что делает этот флаг). в main.cpp:
в mainwindow_db.cpp (в главном окне):
в mainwindow_db.h:
|
|
|
Алексей1153 |
![]()
Сообщение
#2
|
![]() фрилансер ![]() ![]() ![]() ![]() ![]() ![]() Группа: Участник Сообщений: 2943 Регистрация: 19.6.2010 Из: Обливион Пользователь №: 1822 Спасибо сказали: 215 раз(а) Репутация: ![]() ![]() ![]() |
1 - полагаю, блобу абсолютно пофиг на кодировку - это поток байтов. Как вытаскиваешь данные для записи в блоб, так нужно и обратно заталкивать (к примеру, через посредника std::string - у QString есть метод для получения такого объекта. )
Возможно, нужно применить другой тип поля - VARCHAR или что там 2 - опять же, производится, скорее всего, попытка отобразить байтовый поток в виде строки. И это прекрасно удаётся ![]() 3 - 2 Сообщение отредактировал Алексей1153 - 14.3.2012, 14:31 |
|
|
Steklova Olga |
![]()
Сообщение
#3
|
![]() Участник ![]() ![]() Группа: Участник Сообщений: 198 Регистрация: 27.9.2011 Из: Санкт-Петербург Пользователь №: 2912 Спасибо сказали: 5 раз(а) Репутация: ![]() ![]() ![]() |
Цитата(Алексей1153) Возможно, нужно применить другой тип поля - VARCHAR В этой таблице у этого поля мне нужен тип BLOB с текстом, а не VARCHAR, потому что заранее совершенно неизвестно количество символов.Цитата Как вытаскиваешь данные для записи в блоб, так нужно и обратно заталкивать (к примеру, через посредника std::string - у QString есть метод для получения такого объекта. не понялаВ том, что у меня сейчас сделано, насколько я понимаю, везде указана одна и та же кодировка - WIN1251. Сообщение отредактировал Steklova Olga - 14.3.2012, 15:51 |
|
|
Алексей1153 |
![]()
Сообщение
#4
|
![]() фрилансер ![]() ![]() ![]() ![]() ![]() ![]() Группа: Участник Сообщений: 2943 Регистрация: 19.6.2010 Из: Обливион Пользователь №: 1822 Спасибо сказали: 215 раз(а) Репутация: ![]() ![]() ![]() |
Оля, ты, судя по всему, используешь Огнептицу
я попробовал у себя в эксперте - сделал такую же таблицу, выполнил вставку. Штатный просмотрщик блоба говорит, что всё видно. Видимо дело у тебя в кодировке текста скрипта - ты как его выполняешь ? В коде программы ? И повторюсь - у блоба нет понятия кодировки, там тупо байты. Вот таким образом, как ты делаешь вставку, я никогда не делал (хотя это сработало - скрин). Я вставлял маркер "?", а только потом данные в виде бинарного массива. Но в моём случае было WinAPI. Как тут это провернуть - я не в курсе Сообщение отредактировал Алексей1153 - 14.3.2012, 20:03 |
|
|
Tonal |
![]()
Сообщение
#5
|
![]() Активный участник ![]() ![]() ![]() Группа: Участник Сообщений: 452 Регистрация: 6.12.2007 Из: Новосибирск Пользователь №: 34 Спасибо сказали: 69 раз(а) Репутация: ![]() ![]() ![]() |
И повторюсь - у блоба нет понятия кодировки, там тупо байты. Вот таким образом, как ты делаешь вставку, я никогда не делал (хотя это сработало - скрин). Я вставлял маркер "?", а только потом данные в виде бинарного массива. Но в моём случае было WinAPI. Как тут это провернуть - я не в курсе Тут ты не совсем прав. В Firebird-е при создании блоба указывается его подтип. Ежели подтип блоба TEXT, то его кодировка так же может быть указана явно либо взята дефолтная. Раньше, кодировки установленные для блобов игнорировались, но начиная с версии 2.1 сервер работает с блобами в этом отношении так же как и с остальными текстовыми типами. Соответственно, при работе с текстовыми блобами в птичке нужно учитывать версию сервера. П. С. Судя по скриншоту, ты используешь виндовый IBExpert. Насколько я в курсе, это один из самых совершенных просмотрщиков для птички, и проблемам кодировок в нём постоянно уделяется довольно много времени. Так что не все результаты «влёгкую» полученные на нём можно просто воспроизвести на каком-либо другом продукте или в коде. ![]() Например если в русском сообществе разработчиков птицы при описании какого-нибудь эффекта/бага сервера ты используешь IBE, тебе, скорее всего, настоятельно порекомендуют повторить его на штатном консольном клиенте. ![]() Сообщение отредактировал Tonal - 15.3.2012, 8:34 |
|
|
Алексей1153 |
![]()
Сообщение
#6
|
![]() фрилансер ![]() ![]() ![]() ![]() ![]() ![]() Группа: Участник Сообщений: 2943 Регистрация: 19.6.2010 Из: Обливион Пользователь №: 1822 Спасибо сказали: 215 раз(а) Репутация: ![]() ![]() ![]() |
Tonal, возможно
|
|
|
Steklova Olga |
![]()
Сообщение
#7
|
![]() Участник ![]() ![]() Группа: Участник Сообщений: 198 Регистрация: 27.9.2011 Из: Санкт-Петербург Пользователь №: 2912 Спасибо сказали: 5 раз(а) Репутация: ![]() ![]() ![]() |
1. Использую FireBird 2.1 в Windows.
2. У меня тоже в IBExpert данные поля BLOB таблицы отображаются корректно. 3. Цитата(Tonal) В Firebird-е при создании блоба указывается его подтип. Ежели подтип блоба TEXT, то его кодировка так же может быть указана явно либо взята дефолтная Я указываю и подтип TEXT, и кодировку блоба. ![]() 4. Цитата(Алексей1153) Видимо дело у тебя в кодировке текста скрипта - ты как его выполняешь ? В коде программы ? Для начала, я попробовала вставить в таблицу T_MSG записи с BLOB с помощью скрипта вставки данных. В первом сообщении я привела тексты скриптов создания БД, доменов, таблицы и вставки данных. Тексты скриптов набирала в IBExpert. Еще есть общий скрипт, который я выполнила в IBExpert (Tools | Script Executive):
5. На самом деле, мне надо будет вставлять в таблицу T_MSG записи с BLOB в коде программы с помощью QSqlQuery "INSERT INTO T_MSG ..." Данные для очередной записи таблицы поступают ко мне в виде структуры:
|
|
|
Steklova Olga |
![]()
Сообщение
#8
|
![]() Участник ![]() ![]() Группа: Участник Сообщений: 198 Регистрация: 27.9.2011 Из: Санкт-Петербург Пользователь №: 2912 Спасибо сказали: 5 раз(а) Репутация: ![]() ![]() ![]() |
6. Для теста изменила структуру таблицы T_MSG и ее заполнение, использовала другие домены:
7. Вставила в таблицу T_MSG записи (с номерами 3 и 4) с BLOB в коде программы с помощью QSqlQuery:
В результате в QTableView: во всех записях (с номерами 1-4) в поле F_MSG_TEXT_VC русский есть, в поле F_MSG_TEXT_B русского нет. Посмотрела данные таблицы T_MSG в IBExpert: во всех записях (с номерами 1-4) в полях F_MSG_TEXT_VC и F_MSG_TEXT_B русский есть. Сообщение отредактировал Steklova Olga - 15.3.2012, 15:49 |
|
|
Steklova Olga |
![]()
Сообщение
#9
|
![]() Участник ![]() ![]() Группа: Участник Сообщений: 198 Регистрация: 27.9.2011 Из: Санкт-Петербург Пользователь №: 2912 Спасибо сказали: 5 раз(а) Репутация: ![]() ![]() ![]() |
8. Если оставить все как есть, но попробовать поменять кодировку блоба:
то результат такой же, как в пункте 7. ![]() 9. В пункте 4., при выполнении общего скрипта в IBExpert (Tools | Script Executive) из вариантов Execute charset: (ANSI, UTF8, Ask me) выбран вариант по умолчанию (ANSI). 10. А в IBExpert при регистрации БД в каком случае надо включать флаг "Do NOT perform conversion from/to UTF8" ? Сообщение отредактировал Steklova Olga - 15.3.2012, 17:55 |
|
|
Steklova Olga |
![]()
Сообщение
#10
|
![]() Участник ![]() ![]() Группа: Участник Сообщений: 198 Регистрация: 27.9.2011 Из: Санкт-Петербург Пользователь №: 2912 Спасибо сказали: 5 раз(а) Репутация: ![]() ![]() ![]() |
11. Кстати, Алексей1153, если в IBExpert открыть таблицу T_MSG, а для нее страницу Data,
то у вас в поле F_MSG_TEXT отображается иконка, а у меня вместо нее - начальные символы текста блоба, а в hint'е - полный текст блоба. И еще. Кроме вариантов просмотра блоба As Text, As Hex, As Picture, As RTF, As Web Page, которые есть у вас, у меня еще есть варианты As XML и As Unicode Text. Это связано с тем, что у нас разные версии IBExpert? 12. Открыла в IBExpert таблицу T_MSG. Нажала кнопку Export Data into Script. Отметила поле F_MSG_TEXT_B, чтобы его данные тоже записались в скрипт. Выбрала имя файла 1.sql. Нажала кнопку Export. Получила два файла: 1.sql и 1.lob. в файле 1.sql: в файле 1.lob: Смотрела файл 1.lob в Notepad++. Он говорит, что файл - в кодировке ANSI. Выглядит по-русски.":h0000000E_0000000C" означает, что данные блоба для второй записи располагаются в файле 1.lob, начиная с адреса 0000000E и занимают 0000000C байтов ? 13. Конкретно эту Qt-шную программу я не планирую переводить на другой язык (англ), поэтому unicode вроде-бы мне не нужен. Я собиралась использовать БД в WIN1251. Эксперименты продолжаются. BLOB не сдается, вредина. Но очень хотелось бы все-таки с ним разобраться! ![]() Сообщение отредактировал Steklova Olga - 15.3.2012, 18:57 |
|
|
Steklova Olga |
![]()
Сообщение
#11
|
![]() Участник ![]() ![]() Группа: Участник Сообщений: 198 Регистрация: 27.9.2011 Из: Санкт-Петербург Пользователь №: 2912 Спасибо сказали: 5 раз(а) Репутация: ![]() ![]() ![]() |
Раньше, в пункте 7. делала так:
Цитата Вставила в таблицу T_MSG записи (с номерами 3 и 4) с BLOB в коде программы с помощью QSqlQuery:
Теперь вместо этого 14. Попробовала использовать подготовленный запрос:
И вот, после выполнения query.exec() ВЫЛЕЗЛА ОШИБКА "Cannot transliterate character between character sets Unable to execute query". Как это побороть - не понимаю, помогите, пожалуйста, разобраться. ![]() |
|
|
Алексей1153 |
![]()
Сообщение
#12
|
![]() фрилансер ![]() ![]() ![]() ![]() ![]() ![]() Группа: Участник Сообщений: 2943 Регистрация: 19.6.2010 Из: Обливион Пользователь №: 1822 Спасибо сказали: 215 раз(а) Репутация: ![]() ![]() ![]() |
Оля, сразу вот такой моментик.
>>Я указываю и подтип TEXT, и кодировку блоба + >>Данные для очередной записи таблицы поступают ко мне в виде структуры: сразу резко напрашивается использование XML , а , следовательно, UTF-8, а, следовательно - всё ж таки тип блоба самый обычный - байтовый. Далее - с байтовым блобом проблем никогда не бывает. Считываешь , незабываешь зеро-терминатор на конце, подсовываешь парсеру XML запись XML в базу: QString->std::string->БД чтение : БД->std::string->обеспечить zt->QString я бы так сделал ![]() ---------------------------- >>11. Кстати, Алексей1153, если в IBExpert открыть таблицу T_MSG, а для нее страницу Data, у меня энто самое... subtype==binary )
Сообщение отредактировал Алексей1153 - 16.3.2012, 8:09 |
|
|
Steklova Olga |
![]()
Сообщение
#13
|
![]() Участник ![]() ![]() Группа: Участник Сообщений: 198 Регистрация: 27.9.2011 Из: Санкт-Петербург Пользователь №: 2912 Спасибо сказали: 5 раз(а) Репутация: ![]() ![]() ![]() |
Цитата(Алексей1153) сразу резко напрашивается использование XML , а , следовательно, UTF-8 Почему-это "следовательно" ? XML может быть и в другой кодировке. ![]() 15. Как раз у нас так в проекте: данные с других компов поступают на наш комп в виде XML с кодировкой windows-1251, и с нашего компа передаются в их сторону так же. Вот только расшифровкой / кодировкой XML занимаюсь в нашем проекте не я, а другой программист. Он же и раскладывает поступившие в XML данные в разные структуры, с которыми мы работаем, а наши выходные данные для других компов он обратно кодирует в XML. 16. Цитата(Алексей1153) запись XML в базу: QString->std::string->БД чтение : БД->std::string->обеспечить zt->QString А дальше? Как myStdString записать в БД? Как прочитать myStdString из БД? Как обеспечить zt? Как из этого получить QString?
|
|
|
Алексей1153 |
![]()
Сообщение
#14
|
![]() фрилансер ![]() ![]() ![]() ![]() ![]() ![]() Группа: Участник Сообщений: 2943 Регистрация: 19.6.2010 Из: Обливион Пользователь №: 1822 Спасибо сказали: 215 раз(а) Репутация: ![]() ![]() ![]() |
в другой то может,но как показывает практика,UTF-8 - стандарт. Всегда и везде без проблем с ним
Ты сама только что подтвердила - с другой кодировкой - проблемы (шутю наполовину ![]() А дальше? из-под Qt я с базами не работал. Насколько подсказывает гугл, нужно что-то вроде Цитата void QSqlQuery::bindValue ( const QString & placeholder, const QVariant & val, QSql::ParamType paramType = QSql::In )
кстати, QVariant умеет и с QString работать - попробуй сразу оттуда возможно, понадобится флаг QSql::Binary в общем, в любом случае -если таким образом записать из QString в двоичный блоб,а потом так же считать, то содержимое QString должно восстановиться аки птицо Феникс, независимо от кодировок Сообщение отредактировал Алексей1153 - 16.3.2012, 11:01 |
|
|
Steklova Olga |
![]()
Сообщение
#15
|
![]() Участник ![]() ![]() Группа: Участник Сообщений: 198 Регистрация: 27.9.2011 Из: Санкт-Петербург Пользователь №: 2912 Спасибо сказали: 5 раз(а) Репутация: ![]() ![]() ![]() |
17. Кодировку БД оставила WIN1251.
Опять изменила структуру таблицы T_MSG, использовала другие домены:
Использовала подготовленный запрос:
Все равно, как и в пункте 14 (независимо от того, указать QSql::In или QSql::In | QSql::Binary), после выполнения query.exec() ВЫЛЕЗАЕТ ОШИБКА "Cannot transliterate character between character sets Unable to execute query". |
|
|
Алексей1153 |
![]()
Сообщение
#16
|
![]() фрилансер ![]() ![]() ![]() ![]() ![]() ![]() Группа: Участник Сообщений: 2943 Регистрация: 19.6.2010 Из: Обливион Пользователь №: 1822 Спасибо сказали: 215 раз(а) Репутация: ![]() ![]() ![]() |
. У тебя есть скайп ? Скинь в ЛС, а то так долго получается
|
|
|
Steklova Olga |
![]()
Сообщение
#17
|
![]() Участник ![]() ![]() Группа: Участник Сообщений: 198 Регистрация: 27.9.2011 Из: Санкт-Петербург Пользователь №: 2912 Спасибо сказали: 5 раз(а) Репутация: ![]() ![]() ![]() |
OK
|
|
|
Litkevich Yuriy |
![]()
Сообщение
#18
|
![]() разработчик РЭА ![]() ![]() ![]() ![]() ![]() ![]() ![]() Группа: Сомодератор Сообщений: 9669 Регистрация: 9.1.2008 Из: Тюмень Пользователь №: 64 Спасибо сказали: 807 раз(а) Репутация: ![]() ![]() ![]() |
Почему у меня некорректно (крокозябрами) отображается русский текст из BLOB в колонке QTableView ? Потомучто:QTextCodec::setCodecForCStrings(QTextCodec::codecForName(RUSCODEC)); Не трогай кодировку "Си-строк" (CStrings) без крайней надобности. |
|
|
Steklova Olga |
![]()
Сообщение
#19
|
![]() Участник ![]() ![]() Группа: Участник Сообщений: 198 Регистрация: 27.9.2011 Из: Санкт-Петербург Пользователь №: 2912 Спасибо сказали: 5 раз(а) Репутация: ![]() ![]() ![]() |
И за что мне такое внимание сегодня с Вашей стороны, Юрий! Прям на все мои вопросы отвечаете. Спасибо большое!
![]() Цитата Не трогай кодировку "Си-строк" (CStrings) без крайней надобности. Извините, но я полный чайник в кодировках. Ничего не понимаю, что Вы хотите этим сказать. Уточните, пожалуйста. ![]() P.S. Если я в моем проекте из main.cpp уберу строки то у меня весь русский текст на экране будет крокозябрами, а не только в BLOB,а вот если оставить, то русский выглядит по-русски, в том числе и в поле VARCHAR, при том, что в это поле VARCHAR я пишу тот же текст, что и в поле BLOB. Как это объяснить? ![]() Сообщение отредактировал Steklova Olga - 4.4.2012, 9:38 |
|
|
Litkevich Yuriy |
![]()
Сообщение
#20
|
![]() разработчик РЭА ![]() ![]() ![]() ![]() ![]() ![]() ![]() Группа: Сомодератор Сообщений: 9669 Регистрация: 9.1.2008 Из: Тюмень Пользователь №: 64 Спасибо сказали: 807 раз(а) Репутация: ![]() ![]() ![]() |
Вобщем есть такая проблема:
По моему (и не только) разумению Qt должна сама разруливать ситуацию с кодировками, ведь есть функции типа QObject::trUtf8(). Т.е. указывается только кодировка исходника, дальнейшие действия идут сами по себе, т.к. внутри Qt всегда одна и та же кодировка. Так же должно быть и в случае с БД, драйвер запрашивает кодировку из БД и сам всё конвертирует туда-сюда. На практике: драйвер считает что данные из БД идут "только на английском" (т.е. кодировка Си строк) - что есть бред. Мало того, родной (от Тролтеха/Нокии) драйвер интербэйза кривой, насколько я помню для Qt версии до 4.5 невозможно задать параметры соединения (как минимум кодировку). Была попытка исправить кучу грехов на прог.орге название темы сейчас не помню, но тогда чувак родил более-мение вменяемый драйвер. Когда ты устанавливаешь кодировку для Си-строк, то работает одна БД. А вот представь себе, если тебе нужно работать с несколькими БД одновременно и у них разные кодировки (реальная жизнь). На данном этапе задача для стандартных драйверов Qt не решаемая. |
|
|
Steklova Olga |
![]()
Сообщение
#21
|
![]() Участник ![]() ![]() Группа: Участник Сообщений: 198 Регистрация: 27.9.2011 Из: Санкт-Петербург Пользователь №: 2912 Спасибо сказали: 5 раз(а) Репутация: ![]() ![]() ![]() |
Litkevich Yuriy, просмотрела кучу тем на prog.org.ru и crossplatform.ru.
Не про эту ли тему на prog.org Вы говорили? ![]() Ответ пока не нашла. Драйверы пока-что сама не писала. Пока гуглила, нашла полезную для себя cсылку: "Linuxcenter.ru » Библиотека Линуксцентра » Книги и руководства » Разработка графического интерфейса с помощью библиотеки Qt3" |
|
|
Steklova Olga |
![]()
Сообщение
#22
|
![]() Участник ![]() ![]() Группа: Участник Сообщений: 198 Регистрация: 27.9.2011 Из: Санкт-Петербург Пользователь №: 2912 Спасибо сказали: 5 раз(а) Репутация: ![]() ![]() ![]() |
из-под Qt я с базами не работал. Насколько подсказывает гугл, нужно что-то вроде Цитата void QSqlQuery::bindValue ( const QString & placeholder, const QVariant & val, QSql::ParamType paramType = QSql::In ) QSqlQuery s; s.prepare( QString( "update TABLE set FIELD=:marker where ... " ) ); s.addBindValue( QVariant (myStdString.c_str()), QSql::In/*|QSql::Binary*/ ); s.exec( ); кстати, QVariant умеет и с QString работать - попробуй сразу оттуда возможно, понадобится флаг QSql::Binary в общем, в любом случае -если таким образом записать из QString в двоичный блоб,а потом так же считать, то содержимое QString должно восстановиться аки птицо Феникс, независимо от кодировок Алексей1153, спасибо Вам большое за поддержку, оказывается, все элементарно ![]() 1. я отказалась от использования текстового блоба, так как не разбираюсь в драйверах. 2. изменила скрипт, остановившись на использовании двоичного блоба:
3. Использовала подготовленный запрос:
4. Все эти варианты работают:
5. А ошибки продолжали вылезать тогда, когда я только начала тестировать использование двоичного блоба, не из-за двоичного блоба, а из-за того, что в то время у меня и в таблице БД оставалось обязательное поле текстового блоба, и в подготовленном запросе вместе с указанием двоичного блоба я ПРОДОЛЖАЛА УКАЗЫВАТЬ ПОЛЕ ТЕКСТОВОГО БЛОБА, которое и вызывало ошибку. Слонов надо есть по частям! ![]() |
|
|
Алексей1153 |
![]()
Сообщение
#23
|
![]() фрилансер ![]() ![]() ![]() ![]() ![]() ![]() Группа: Участник Сообщений: 2943 Регистрация: 19.6.2010 Из: Обливион Пользователь №: 1822 Спасибо сказали: 215 раз(а) Репутация: ![]() ![]() ![]() |
ещё мне что-то подсказывает, что более рационально задавать сегмент размером , равным степени двойки. К примеру, не 500, а 512
|
|
|
Steklova Olga |
![]()
Сообщение
#24
|
![]() Участник ![]() ![]() Группа: Участник Сообщений: 198 Регистрация: 27.9.2011 Из: Санкт-Петербург Пользователь №: 2912 Спасибо сказали: 5 раз(а) Репутация: ![]() ![]() ![]() |
Алексей1153, да, наверное.
В книге Хелен Борри "Firebird. Руководствоо разработчика баз данных" на стр 223 в главе 12 "BLOB и массивы" нашла следующие слова: Цитата "Сегменты BLOB. Если страницы с содержимым BLOB хранят только данные BLOB и там нет никакой вспомогательной информации (в книге я не нашла подтверждения этого), то Вы правы.
Данные BLOB... хранятся в виде сегментов на одной или более страницах базы данных. ...Когда это возможно, BLOB сохраняются на той же странице, что и запись с остальными данными. При этом большие BLOB могут занимать много страниц, а их начальные страницы могут содержать не данные, а массив указателей на страницы с содержимым BLOB." |
|
|
![]() ![]() ![]() |
![]() |
|
Текстовая версия | Сейчас: 1.6.2025, 23:28 |