Russian Qt Forum
Апрель 23, 2024, 17:15 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: 1 [2]   Вниз
  Печать  
Автор Тема: Проблемы кодировки cp1251 (sqlite + QSqlTableModel + QTableView)  (Прочитано 19939 раз)
LisandreL
Птица говорун
*****
Offline Offline

Сообщений: 984


Надо улыбаться


Просмотр профиля
« Ответ #15 : Май 13, 2011, 22:25 »

Да, пожалуйста. Первые 10 записей одной из таблиц.
Вот решение костыльное немного более, чем полностью:
Код
C++ (Qt)
#include <QApplication>
#include <QTextCodec>
#include <QSqlTableModel>
#include <QSqlQuery>
#include <QSqlRecord>
#include <QSqlError>
#include <QTableView>
 
class CrutchesModel: public QSqlTableModel
{
   QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const
   {
       QVariant value = QSqlTableModel::data(index, role);
       if (value.type()==QVariant::String)
       {
           // если строка, то читаем шестнадцатиричное представление поля и из него получаем нашу CP1251 строку
           QString queryString = "SELECT HEX([" + database().record(tableName()).fieldName(index.column()) + "]) FROM "+ tableName();
           if (!filter().isEmpty())
               queryString.append(" WHERE ").append(filter());
           if (!orderByClause().isEmpty())
               queryString.append(' ').append(orderByClause());
           queryString.append(" LIMIT 1 OFFSET ").append(QString::number(index.row())).append(";");
           QSqlQuery query = database().exec(queryString);
           if (query.next())
           {
               return QString(QByteArray::fromHex(query.value(0).toByteArray()));
           }
           else
           {
               return QString();
           }
       }
       return value;
   };
 
   bool setData (const QModelIndex & index, const QVariant & value, int role = Qt::EditRole)
   {
       if (value.type()==QVariant::String)
       {
           // строку пишем как массив байт
           return QSqlTableModel::setData(index, value.toString().toAscii(), role);
       }
       return QSqlTableModel::setData(index, value, role);
   };
};
 
int main(int argc, char *argv[])
{
   QTextCodec *codec=QTextCodec::codecForName("Windows-1251");
   QTextCodec::setCodecForCStrings(codec);
   QApplication a(argc, argv);
 
   QSqlDatabase db=QSqlDatabase::addDatabase("QSQLITE");
   db.setDatabaseName("database.s3db");
   CrutchesModel model;
   model.setTable("instr");
   model.select();
 
   QTableView view;
   view.setModel(&model);
   view.show();
   return a.exec();
}
Собственно в CrutchesModel переопределяем data и setData.
Увы родное data() возвращает сразу одни "знаки вопроса в ромбиках" и исходную строку приходится узнавать отдельным запросом к БД.
Так же вынужден заметить, что писать в setData оно реально будет не строку, а ByteArray (т.е. в понятиях SQLite'а - blob). Скорее всего это не вызовет проблем - SQLite к типам полей относится весьма фривольно, однако лучше эту подправленную БД опробовать на Delphi-программе, с которой вы работаете, чтобы убедиться что ничего не поломалось.

Исходный код программы в прикреплённом файле:
« Последнее редактирование: Май 13, 2011, 22:33 от LisandreL » Записан
amabilisa
Гость
« Ответ #16 : Март 29, 2017, 15:12 »

Спасибо! Выручили!

У меня та же проблема. "Умники" из другого отдела засунули в базу через API SQLite данные в 1251.

Благодаря Вашему костылю, читаю данные нормально, но проблема возникла с параметрическим запросом.

Модель у меня от QAbstractItemModel. Qt 5.4.

Ломаю голову, как заставить базу понять запрос из моего кода:

select ANTENS.ID from ANTENS where ANTENS.ANTEN_NAME = 'Антенна_1'

Пробовала сравнивать хексы, но не помогло.
Может быть, есть какие-то мысли, как это осуществить?

Вот, что было испробовано:

fieldText = QString("Антенна_1").toLocal8Bit().toHex();
queryText = QString("select ANTENS.ID from ANTENS where HEX(ANTENS.ANTEN_NAME) = HEX('" + fieldText  +"')").toLocal8Bit();

Но
query.exec(queryText);
упорно возвращает ноль результатов.

Даже напрямую в SQLite Browser запрос ничего не вернул.
select ANTENS.ID from ANTENS where HEX(ANTENS.ANTEN_NAME) = HEX('C0EDF2E5EDEDE05F31')

где C0EDF2E5EDEDE05F31 -- результат выбора в хексе названия антенны по её id (та самая "Антенна_1").

Что делаю не так, ребят?
Записан
lit-uriy
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3880


Просмотр профиля WWW
« Ответ #17 : Март 29, 2017, 18:36 »

amabilisa, а сама БД в какой кодировке?
Записан

Юра.
Страниц: 1 [2]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.08 секунд. Запросов: 22.