crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

3 страниц V   1 2 3 >  
Ответить в данную темуНачать новую тему
> Отображение BLOB полей таблиц БД FireBird в QTableView Qt в Windows
Steklova Olga
  опции профиля:
сообщение 14.3.2012, 13:59
Сообщение #1


Участник
**

Группа: Участник
Сообщений: 198
Регистрация: 27.9.2011
Из: Санкт-Петербург
Пользователь №: 2912

Спасибо сказали: 5 раз(а)




Репутация:   4  


Здравствуйте :) У меня в таблице БД есть поле BLOB для хранения текста.

Вопрос 1.
Почему у меня некорректно (крокозябрами) отображается русский текст из BLOB в колонке QTableView ?
Вопрос 2.
Как сделать, чтобы текст в колонке с BLOB не отображался весь в одну строку, а переносился ?
Вопрос 3.
Что делать с шириной колонки для поля BLOB ? Ограничивать ?

Мои предположения:
- не в той кодировке пишу данные в БД ?
- не везде, где надо, правильно указала кодировку ?
- мне необходимо создать делегат, чтобы в каждой ячейке QTableView колонки с BLOB был виджет QTextEdit ?
(Сейчас никакого делегата для этого QTableView у меня нет.)

Делаю так:
в скриптах при создании БД:
----------------------
SET SQL DIALECT 3;
CREATE DATABASE 'D:\DB1.FDB' USER 'SYSDBA' PASSWORD 'masterkey'
DEFAULT CHARACTER SET WIN1251;
EXIT;
----------------------
SET SQL DIALECT 3;
SET NAMES WIN1251;
CONNECT 'D:\DB1.FDB' USER 'SYSDBA' PASSWORD 'masterkey';
CREATE DOMAIN D_INTEGER AS
INTEGER;
CREATE DOMAIN D_BLOB_TEXT_1000 AS
BLOB SUB_TYPE 1 SEGMENT SIZE 1000 --SUB_TYPE 1 == TEXT
CHARACTER SET WIN1251;
COMMIT;
EXIT;
----------------------
SET SQL DIALECT 3;
SET NAMES WIN1251;
CONNECT 'D:\DB1.FDB' USER 'SYSDBA' PASSWORD 'masterkey';
CREATE TABLE T_MSG (
    F_RECORD_NMB D_INTEGER NOT NULL,
    F_MSG_TEXT   D_BLOB_TEXT_1000 NOT NULL
);
ALTER TABLE T_MSG ADD CONSTRAINT PK_T_MSG PRIMARY KEY (F_RECORD_NMB);
COMMIT;
EXIT;
----------------------
SET SQL DIALECT 3;
SET NAMES WIN1251;
CONNECT 'D:\DB1.FDB' USER 'SYSDBA' PASSWORD 'masterkey';
INSERT INTO T_MSG (F_RECORD_NMB, F_MSG_TEXT) VALUES (1, 'PRIVET: ПРИВЕТ');
INSERT INTO T_MSG (F_RECORD_NMB, F_MSG_TEXT) VALUES (2, 'OTVET: ОТВЕТ');
COMMIT WORK;
EXIT;
----------------------

В IBExpert при регистрации БД указываю:
- Charset = WIN1251
- оставляю не включенным (как по умолчанию и есть) флаг
Do NOT perform conversion from/to UTF8
- Font Characters Set = RUSSIAN_CHARSET
При этом в IBExpert данные поля BLOB таблицы отображаются корректно,
как и при включенном флаге (не совсем понимаю, что делает этот флаг).

в main.cpp:
#include <QtCore/QTextCodec>
#define RUSCODEC "CP1251"

int main(int argc, char *argv[])
{
    ...
    QTextCodec::setCodecForCStrings(QTextCodec::codecForName(RUSCODEC));
}
в mainwindow_db.cpp (в главном окне):
void MainWindow_db::create_model_msg_list()
{
    //создание модели
    model_msg_list = new QSqlTableModel(this);
    model_msg_list->setEditStrategy(QSqlTableModel::OnFieldChange);
    model_msg_list->setTable("T_MSG");

    //задание заголовков столбцов
    model_msg_list->setHeaderData(0, Qt::Horizontal, "№ сообщ.");
    model_msg_list->setHeaderData(1, Qt::Horizontal, "Текст сообщ.");

    //задание модели для представления
    view_msg_list->setModel(model_msg_list);
    view_msg_list->setSelectionMode(QAbstractItemView::SingleSelection); //сколько выделять: один
    view_msg_list->setSelectionBehavior(QAbstractItemView::SelectRows); //что выделять: строки
    view_msg_list->setEditTriggers(QAbstractItemView::NoEditTriggers); //представление табл доступно только для чтения

    //установить ширину колонок
    view_msg_list->resizeColumnsToContents();

    view_msg_list->verticalHeader()->hide();
}
в mainwindow_db.h:
class MainWindow_db : public QMainWindow
{
    Q_OBJECT
public:
    MainWindow_db(QWidget *parent = 0);
    QSqlTableModel *model_msg_list;
    ...
private:
    QTableView *view_msg_list;
    void create_model_msg_list();
    ...
}

Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Алексей1153
  опции профиля:
сообщение 14.3.2012, 14:30
Сообщение #2


фрилансер
******

Группа: Участник
Сообщений: 2941
Регистрация: 19.6.2010
Из: Обливион
Пользователь №: 1822

Спасибо сказали: 215 раз(а)




Репутация:   34  


1 - полагаю, блобу абсолютно пофиг на кодировку - это поток байтов. Как вытаскиваешь данные для записи в блоб, так нужно и обратно заталкивать (к примеру, через посредника std::string - у QString есть метод для получения такого объекта. )

Возможно, нужно применить другой тип поля - VARCHAR или что там

2 - опять же, производится, скорее всего, попытка отобразить байтовый поток в виде строки. И это прекрасно удаётся :D . Выход - только ручками как-то выводить так, как нужно, разбавляя переносами строки

3 - 2

Сообщение отредактировал Алексей1153 - 14.3.2012, 14:31
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Steklova Olga
  опции профиля:
сообщение 14.3.2012, 14:44
Сообщение #3


Участник
**

Группа: Участник
Сообщений: 198
Регистрация: 27.9.2011
Из: Санкт-Петербург
Пользователь №: 2912

Спасибо сказали: 5 раз(а)




Репутация:   4  


Цитата(Алексей1153)
Возможно, нужно применить другой тип поля - VARCHAR
В этой таблице у этого поля мне нужен тип BLOB с текстом, а не VARCHAR, потому что заранее совершенно неизвестно количество символов.

Цитата
Как вытаскиваешь данные для записи в блоб, так нужно и обратно заталкивать (к примеру, через посредника std::string - у QString есть метод для получения такого объекта.
не поняла

В том, что у меня сейчас сделано, насколько я понимаю, везде указана одна и та же кодировка - WIN1251.

Сообщение отредактировал Steklova Olga - 14.3.2012, 15:51
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Алексей1153
  опции профиля:
сообщение 14.3.2012, 20:01
Сообщение #4


фрилансер
******

Группа: Участник
Сообщений: 2941
Регистрация: 19.6.2010
Из: Обливион
Пользователь №: 1822

Спасибо сказали: 215 раз(а)




Репутация:   34  


Оля, ты, судя по всему, используешь Огнептицу

я попробовал у себя в эксперте - сделал такую же таблицу, выполнил вставку. Штатный просмотрщик блоба говорит, что всё видно.
Прикрепленное изображение


Видимо дело у тебя в кодировке текста скрипта - ты как его выполняешь ? В коде программы ?

И повторюсь - у блоба нет понятия кодировки, там тупо байты. Вот таким образом, как ты делаешь вставку, я никогда не делал (хотя это сработало - скрин). Я вставлял маркер "?", а только потом данные в виде бинарного массива. Но в моём случае было WinAPI. Как тут это провернуть - я не в курсе

Сообщение отредактировал Алексей1153 - 14.3.2012, 20:03
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Tonal
  опции профиля:
сообщение 15.3.2012, 8:15
Сообщение #5


Активный участник
***

Группа: Участник
Сообщений: 452
Регистрация: 6.12.2007
Из: Новосибирск
Пользователь №: 34

Спасибо сказали: 69 раз(а)




Репутация:   17  


Цитата(Алексей1153 @ 15.3.2012, 0:01) *
И повторюсь - у блоба нет понятия кодировки, там тупо байты. Вот таким образом, как ты делаешь вставку, я никогда не делал (хотя это сработало - скрин). Я вставлял маркер "?", а только потом данные в виде бинарного массива. Но в моём случае было WinAPI. Как тут это провернуть - я не в курсе

Тут ты не совсем прав.
В Firebird-е при создании блоба указывается его подтип. Ежели подтип блоба TEXT, то его кодировка так же может быть указана явно либо взята дефолтная.
Раньше, кодировки установленные для блобов игнорировались, но начиная с версии 2.1 сервер работает с блобами в этом отношении так же как и с остальными текстовыми типами.

Соответственно, при работе с текстовыми блобами в птичке нужно учитывать версию сервера.

П. С. Судя по скриншоту, ты используешь виндовый IBExpert. Насколько я в курсе, это один из самых совершенных просмотрщиков для птички, и проблемам кодировок в нём постоянно уделяется довольно много времени.
Так что не все результаты «влёгкую» полученные на нём можно просто воспроизвести на каком-либо другом продукте или в коде. :)
Например если в русском сообществе разработчиков птицы при описании какого-нибудь эффекта/бага сервера ты используешь IBE, тебе, скорее всего, настоятельно порекомендуют повторить его на штатном консольном клиенте. :)

Сообщение отредактировал Tonal - 15.3.2012, 8:34
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Алексей1153
  опции профиля:
сообщение 15.3.2012, 9:33
Сообщение #6


фрилансер
******

Группа: Участник
Сообщений: 2941
Регистрация: 19.6.2010
Из: Обливион
Пользователь №: 1822

Спасибо сказали: 215 раз(а)




Репутация:   34  


Tonal, возможно
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Steklova Olga
  опции профиля:
сообщение 15.3.2012, 11:33
Сообщение #7


Участник
**

Группа: Участник
Сообщений: 198
Регистрация: 27.9.2011
Из: Санкт-Петербург
Пользователь №: 2912

Спасибо сказали: 5 раз(а)




Репутация:   4  


1. Использую FireBird 2.1 в Windows.
2. У меня тоже в IBExpert данные поля BLOB таблицы отображаются корректно.
3.
Цитата(Tonal)
В Firebird-е при создании блоба указывается его подтип. Ежели подтип блоба TEXT, то его кодировка так же может быть указана явно либо взята дефолтная
Я указываю и подтип TEXT, и кодировку блоба. :rolleyes:
4.
Цитата(Алексей1153)
Видимо дело у тебя в кодировке текста скрипта - ты как его выполняешь ? В коде программы ?
Для начала, я попробовала вставить в таблицу T_MSG записи с BLOB с помощью скрипта вставки данных.
В первом сообщении я привела тексты скриптов создания БД, доменов, таблицы и вставки данных.
Тексты скриптов набирала в IBExpert.
Еще есть общий скрипт, который я выполнила в IBExpert (Tools | Script Executive):
/*   SeriesOfScripts.sql   */
--создание пустой БД
  INPUT 'D:\CreateDatabase.sql';
  INPUT 'D:\CreateDomains.sql';
  INPUT 'D:\CreateTables.sql';
--заполнение таблиц для тестирования программ
  INPUT 'D:\FillTables.sql';

5. На самом деле, мне надо будет вставлять в таблицу T_MSG записи с BLOB в коде программы с помощью QSqlQuery "INSERT INTO T_MSG ..."
Данные для очередной записи таблицы поступают ко мне в виде структуры:
typedef struct {
    qint32 recNmb;
    QString msg;
} tMsg;

Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Steklova Olga
  опции профиля:
сообщение 15.3.2012, 15:13
Сообщение #8


Участник
**

Группа: Участник
Сообщений: 198
Регистрация: 27.9.2011
Из: Санкт-Петербург
Пользователь №: 2912

Спасибо сказали: 5 раз(а)




Репутация:   4  


6. Для теста изменила структуру таблицы T_MSG и ее заполнение, использовала другие домены:
CREATE DOMAIN D_VARCHAR_0020 AS
VARCHAR(20) CHARACTER SET WIN1251
COLLATE PXW_CYRL;
CREATE DOMAIN D_BLOB_TEXT_0020 AS
BLOB SUB_TYPE 1 SEGMENT SIZE 20 --SUB_TYPE 1 == TEXT
CHARACTER SET WIN1251;
CREATE TABLE T_MSG (
    F_RECORD_NMB D_INTEGER NOT NULL,
    F_MSG_TEXT_VC D_VARCHAR_0020 NOT NULL,
    F_MSG_TEXT_B D_BLOB_TEXT_0020 NOT NULL
);
INSERT INTO T_MSG (F_RECORD_NMB, F_MSG_TEXT_VC, F_MSG_TEXT_B)
VALUES (1, 'PRIVET1: ПРИВЕТ1', 'PRIVET1: ПРИВЕТ1');
INSERT INTO T_MSG (F_RECORD_NMB, F_MSG_TEXT_VC, F_MSG_TEXT_B)
VALUES (2, 'PRIVET2: ПРИВЕТ2', 'PRIVET2: ПРИВЕТ2');

7. Вставила в таблицу T_MSG записи (с номерами 3 и 4) с BLOB в коде программы с помощью QSqlQuery:
QString query_str;
QSqlQuery query;
query_str = "INSERT INTO T_MSG (F_RECORD_NMB, F_MSG_TEXT_VC, F_MSG_TEXT_B) "
  "VALUES (3, 'PRIVET3: ПРИВЕТ3', 'PRIVET3: ПРИВЕТ3')";
query.exec(query_str);
query_str = "INSERT INTO T_MSG (F_RECORD_NMB, F_MSG_TEXT_VC, F_MSG_TEXT_B) "
  "VALUES (4, 'PRIVET4: ПРИВЕТ4', 'PRIVET4: ПРИВЕТ4')";
query.exec(query_str);

В результате в 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
  опции профиля:
сообщение 15.3.2012, 15:58
Сообщение #9


Участник
**

Группа: Участник
Сообщений: 198
Регистрация: 27.9.2011
Из: Санкт-Петербург
Пользователь №: 2912

Спасибо сказали: 5 раз(а)




Репутация:   4  


8. Если оставить все как есть, но попробовать поменять кодировку блоба:
CREATE DOMAIN D_BLOB_TEXT_0020 AS
BLOB SUB_TYPE 1 SEGMENT SIZE 20 --SUB_TYPE 1 == TEXT
CHARACTER SET UNICODE_FSS;
то результат такой же, как в пункте 7. :unsure:

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
  опции профиля:
сообщение 15.3.2012, 18:51
Сообщение #10


Участник
**

Группа: Участник
Сообщений: 198
Регистрация: 27.9.2011
Из: Санкт-Петербург
Пользователь №: 2912

Спасибо сказали: 5 раз(а)




Репутация:   4  


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:
SET BLOBFILE 'D:\1.lob';
INSERT INTO T_MSG (F_RECORD_NMB, F_MSG_TEXT_VC, F_MSG_TEXT_B)
           VALUES (1, 'PRIVET: ПРИВЕТ', :h00000000_0000000E);
INSERT INTO T_MSG (F_RECORD_NMB, F_MSG_TEXT_VC, F_MSG_TEXT_B)
           VALUES (2, 'OTVET: ОТВЕТ', :h0000000E_0000000C);
COMMIT WORK;
в файле 1.lob:
PRIVET: ПРИВЕТOTVET: ОТВЕТ
Смотрела файл 1.lob в Notepad++. Он говорит, что файл - в кодировке ANSI. Выглядит по-русски.
":h0000000E_0000000C" означает, что данные блоба для второй записи располагаются в файле 1.lob, начиная с адреса 0000000E и занимают 0000000C байтов ?

13. Конкретно эту Qt-шную программу я не планирую переводить на другой язык (англ), поэтому unicode вроде-бы мне не нужен. Я собиралась использовать БД в WIN1251.

Эксперименты продолжаются. BLOB не сдается, вредина. Но очень хотелось бы все-таки с ним разобраться! :rolleyes:

Сообщение отредактировал Steklova Olga - 15.3.2012, 18:57
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

3 страниц V   1 2 3 >
Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0




RSS Текстовая версия Сейчас: 1.12.2024, 0:26