Поиск:

Ответ в темуСоздание новой темы Создание опроса
> [QT4] Qt4.3 + sqlite3 + blob, Как записывать в поля типа blob и как... 
V
    Опции темы
CuteBunny
Дата 13.5.2008, 05:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 77
Регистрация: 14.2.2008

Репутация: 1
Всего: 1



Привет, всем!

Искал в нете, ничего не нашел, про то, как в sqlite, средствами qt4.3 вставлять данные в поля типа blob и как их потом вытаскивать в нужном виде, к примеру в виде QPixmap'а?

Может, кто-нибудь знает?

Спасибо, заранее. 
PM MAIL   Вверх
SABROG
Дата 13.5.2008, 08:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Hacker
****


Профиль
Группа: Завсегдатай
Сообщений: 2481
Регистрация: 18.9.2006

Репутация: 81
Всего: 91



Так пробывал ?

Код

QSqlQuery qry(dbName);
QPixmap px("myFile.png", "PNG");
qry.prepare("INSERT INTO table (blobField) VALUES (?);");
qry.addBindValue(QVariant(px));


Или так ?

Код

QSqlQuery qry(dbName);
QPixmap pixmap("myFile.png", "PNG");
QByteArray bytes;
QBuffer buffer(&bytes);
buffer.open(QIODevice::WriteOnly);
pixmap.save(&buffer, "PNG");
qry.prepare("INSERT INTO table (blobField) VALUES (?);");
qry.addBindValue(QVariant(bytes));



--------------------
Национальная группа Russian Federation на QtCentre.
PM MAIL   Вверх
Elfebet
Дата 13.5.2008, 09:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 545
Регистрация: 15.5.2006
Где: Украина. Запорожь е.

Репутация: 5
Всего: 14



из базы в лейбел
Код

    QSqlQuery query("SELECT Photo FROM Table WHERE id_key = " + sKey);
    if( query.next() )
    {
        QByteArray loadimage = query.value(0).toByteArray();
        if( !loadimage.isEmpty() )
        {
            QPixmap pixmap;
            pixmap.loadFromData(loadimage);
            m_lbl->setPixmap(pixmap);
        }
        else m_lbl->setText("No Photo");
    }


из лейбла в базу
Код

    QByteArray bytes;
    QBuffer buffer(&bytes);
    buffer.open(QIODevice::WriteOnly);
    m_lbl->pixmap()->save(&buffer, "PNG");

    QSqlQuery query;
    query.prepare("UPDATE Table SET Photo = ? WHERE id_key=" + sKey);
    query.bindValue(0, bytes);
    query.exec();



--------------------
Программист не должен всё знать... он должен знать где можно посмотреть
PM MAIL ICQ GTalk   Вверх
SABROG
Дата 13.5.2008, 10:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Hacker
****


Профиль
Группа: Завсегдатай
Сообщений: 2481
Регистрация: 18.9.2006

Репутация: 81
Всего: 91



Эта строчка улыбнула smile

Код

query.prepare("UPDATE Table SET Photo = ? WHERE id_key=" + sKey);


Почему не так ?

Код

query.prepare("UPDATE Table SET Photo = ? WHERE id_key= ?");
query.bindValue(0, bytes);
query.bindValue(1, sKey);


Судя по докам к QPixmap у него перегружен оператор QVariant(), т.е. он может быть кастанут в QVariant и прямое преобразование через QByteArray не требуется.

Это сообщение отредактировал(а) SABROG - 13.5.2008, 10:30


--------------------
Национальная группа Russian Federation на QtCentre.
PM MAIL   Вверх
CuteBunny
Дата 13.5.2008, 21:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 77
Регистрация: 14.2.2008

Репутация: 1
Всего: 1



Спасибо, всем! Правда с БД работаю через индексы и модели. Но... Наткнулся на проблему...

Код

if (!eModel->index(ui.employeesTableView->currentIndex().row(), 8, QModelIndex()).data().isNull())
    {
        QByteArray *pBytes = new QByteArray;
        *pBytes=eModel->index(ui.employeesTableView->currentIndex().row(), 8, QModelIndex()).data().toByteArray();
        bool flag=photo->loadFromData(*pBytes, "PNG");
    }
    else
        photo->load("nophoto.png");
    pScene->addPixmap(*photo);


Картинки загружаются в БД 100%, смотрел через SQLite Manager, содержимое поля типа blob заполнилось кучей иероглифов.
Теперь вытащить их из БД не получается... 

Я юзаю Visual Studio EE 2003, провел дебаг, установил watch перед *pBytes=eModel->index(ui.employeesTableView->currentIndex().row(), 8, QModelIndex()).data().toByteArray(); туда заносится тоже самое, однако, при попытке loadFromData(*pBytes); всегда возвращает false???

Я не знаю, что за проблема, но в нете поискал, там у одного чела таже проблема, он юзал Qt4.2, у него похожая проблема, только в linux'е все работает, а в винде нет...


PM MAIL   Вверх
SABROG
Дата 13.5.2008, 21:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Hacker
****


Профиль
Группа: Завсегдатай
Сообщений: 2481
Регистрация: 18.9.2006

Репутация: 81
Всего: 91



А попробуй из указателя *pBytes запиши содержимое в новый .png файл и открой любым просмотрщиком фоток. Может в базу мусор попадает какой...


--------------------
Национальная группа Russian Federation на QtCentre.
PM MAIL   Вверх
CuteBunny
Дата 13.5.2008, 22:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 77
Регистрация: 14.2.2008

Репутация: 1
Всего: 1



Там все что угодно, но не изображение, значит в бд реально мусор идет, 

Код

QByteArray *pBytes = new QByteArray;
QBuffer *pBuffer = new QBuffer;
pBuffer->setBuffer(pBytes);
pBuffer->open(QIODevice::WriteOnly);
photo->save(pBuffer, "PNG");


здесь что-то нетак???
PM MAIL   Вверх
SABROG
Дата 13.5.2008, 22:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Hacker
****


Профиль
Группа: Завсегдатай
Сообщений: 2481
Регистрация: 18.9.2006

Репутация: 81
Всего: 91



А в photo точно есть что-то ? Попробуй на форму кинуть QLabel и вызвать setPixmap со своим файлом.


--------------------
Национальная группа Russian Federation на QtCentre.
PM MAIL   Вверх
CuteBunny
Дата 13.5.2008, 22:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 77
Регистрация: 14.2.2008

Репутация: 1
Всего: 1



да там, то есть, я перед тем как в бд заносить, предварительный просмотр устроил, ну и там photo показываюsmile, черт знает, посмотрел, через фар, фото, которое пытаюсь впихнуть, и сравнил с тем, что заносится в *pBytes, одинаковы только заголовки, а дальше, как будто ничего не заносится

%PNG
->

IHDR ... и т.д. - это то, что фар показывает, а то, что в *pBytes - только %PNG-> smile

Добавлено через 6 минут и 2 секунды
Код

photo->load(dm->filePath(index));
QByteArray * pBytes = new QByteArray;
QBuffer * pBuffer = new QBuffer;
pBuffer->setBuffer(pBytes);
pBuffer->open(QIODevice::WriteOnly);
photo->save(pBuffer, "PNG", 0);
QPixmap *photo1 = new QPixmap;
photo1->loadFromData(*pBytes);


странно, но так photo1 отображается и нормально, только этот код в другом месте? есть ли связь?

PM MAIL   Вверх
CuteBunny
Дата 13.5.2008, 23:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 77
Регистрация: 14.2.2008

Репутация: 1
Всего: 1



Возможно, что это из-за Sqlite'а? http://sb-news.net/sqlite.php?page=6 
Хотя, не похоже, SQlite Manager отображает изменения в бд?

Добавлено через 8 минут и 25 секунд
Код


photo->load(dm->filePath(index));
photo->save(pBuffer, "PNG");

QPixmap *photo1 = new QPixmap;
photo1->loadFromData(*pBytes); //ЗАГРУЗКА И МАССИВА БАЙТОВ!!!!!!!!
pScene->addPixmap(*photo1);   //ВОТ!!! ФОТКА ОТОБРАЖАЕТСЯ!!! БОЛЬШЕ НИЧТО НА scene не заносится!!! КАПЕЦ!!!
query->prepare("update employees set photo=:photo where id=:id");
query->bindValue(0, *pBytes);
query->bindValue(1, id);
query->exec(); //ЗДЕСЬ ЗАНОСИТСЯ В БД!!!!!!!
QMessageBox::information(0, qApp->tr("Информация"),  qApp->tr("Фотография загружена"), QMessageBox::Cancel);



ЧЗАН smile  smile  smile 
PM MAIL   Вверх
Elfebet
Дата 14.5.2008, 09:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 545
Регистрация: 15.5.2006
Где: Украина. Запорожь е.

Репутация: 5
Всего: 14



мистика.

Приведи полный пример своего кода + покажи струткуру своей таблицы.
где-то наверное ошибка в другом месте.


--------------------
Программист не должен всё знать... он должен знать где можно посмотреть
PM MAIL ICQ GTalk   Вверх
SABROG
Дата 14.5.2008, 13:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Hacker
****


Профиль
Группа: Завсегдатай
Сообщений: 2481
Регистрация: 18.9.2006

Репутация: 81
Всего: 91



Набросал тестовый пример, все сохраняется в базу, оттуда берется и загружается на форму. По крайней мере я убедился, что BLOB'ы работают.

P.S.: файлик image.png не забыть скопировать в папку с .exeшником.

Присоединённый файл ( Кол-во скачиваний: 146 )
Присоединённый файл  InsertBlob.zip 293,15 Kb


--------------------
Национальная группа Russian Federation на QtCentre.
PM MAIL   Вверх
CuteBunny
Дата 14.5.2008, 15:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 77
Регистрация: 14.2.2008

Репутация: 1
Всего: 1



loadPhotoDialog.h

Код

#pragma once

#include <QDialog>
#include <QDirModel>
#include <QByteArray>
#include <QPixmap>
#include <QGraphicsScene>
#include <QBuffer>
#include <QModelIndex>
#include <QMessageBox>
#include <QSqlQuery>

#include "ui_loadPhotoDialog.h"

#include "employeesModel.h"

class QDialog;
class QDirModel;
class QByteArray;
class QPixmap;
class QGraphicsScene;
class QBuffer;
class QModelIndex;
class QMessageBox;
class QSqlQuery;

class loadPhotoDialog : public QDialog
{
    Q_OBJECT
private:
    int id;
    QDirModel *dm;
    QGraphicsScene *pScene;
    QPixmap *photo;
    QSqlQuery *query;
    QByteArray * pBytes;
    QBuffer * pBuffer;
    employeesModel *eModel;
    Ui::load_PhotoDialog ui;
public:
    loadPhotoDialog(QWidget *parent=0);
private slots:
    void photoDialog(const QModelIndex &index);
    void selectPhoto(const QModelIndex &index);
    void addPhoto();
};


loadPhotoDialog.cpp

Код

#include "loadPhotoDialog.h"

loadPhotoDialog::loadPhotoDialog(QWidget *parent) : QDialog(parent)
{
    ui.setupUi(this);
    pScene = new QGraphicsScene;
    dm = new QDirModel;
    photo = new QPixmap;
    eModel = new employeesModel;
    query = new QSqlQuery;
    pBytes = new QByteArray;
    pBuffer = new QBuffer;
    pBuffer->setBuffer(pBytes);
    pBuffer->open(QIODevice::WriteOnly);
    eModel->setEditStrategy(QSqlTableModel::OnFieldChange);
    dm->setHeaderData(0, Qt::Horizontal, qApp->tr("Имя"));    
    dm->setHeaderData(1, Qt::Horizontal, qApp->tr("Размер"));    
    dm->setHeaderData(2, Qt::Horizontal, qApp->tr("Тип"));    
    dm->setHeaderData(3, Qt::Horizontal, qApp->tr("Изменен"));
    ui.treeView->setModel(dm);
    ui.photoGraphicsView->setScene(pScene);
    connect(ui.cancelPushButton, SIGNAL(clicked()), this, SLOT(close()));
    connect(ui.loadPushButton, SIGNAL(clicked()), this, SLOT(addPhoto()));
    connect(ui.treeView, SIGNAL(clicked(const QModelIndex&)), this, SLOT(selectPhoto(const QModelIndex&)));
}

void loadPhotoDialog::photoDialog(const QModelIndex &index)
{
    id=index.data().toInt();
    this->show();
}

void loadPhotoDialog::selectPhoto(const QModelIndex &index)
{
    ui.fileLineEdit->setText(index.data().toString());
    if (!dm->filePath(index).isEmpty())
    {
        photo->load(dm->filePath(index));
        
        photo->save(pBuffer, "PNG");
        
        QPixmap *photo1 = new QPixmap;
        photo1->loadFromData(*pBytes);
        pScene->addPixmap(*photo1);
        query->prepare("update employees set photo=:photo where id=:id");
        query->bindValue(0, *pBytes);
        query->bindValue(1, id);
        query->exec();
        QMessageBox::information(0, qApp->tr("Информация"),  
            qApp->tr("Фотография загружена"), QMessageBox::Cancel);
    }
}

void loadPhotoDialog::addPhoto()
{
    if (!photo->isNull())
    {
        query->prepare("update employees set photo=:photo where id=:id");
        query->bindValue(0, *pBytes);
        query->bindValue(1, id);
        query->exec();
        QMessageBox::information(0, qApp->tr("Информация"),  
            qApp->tr("Фотография загружена"), QMessageBox::Cancel);
        return;
    }
    QMessageBox::critical(0, qApp->tr("Ошибка"),  
            qApp->tr("Неверный тип файла"), QMessageBox::Cancel);
}


database.h

Код

#pragma once

#include <QSqlDatabase>
#include <QSqlQuery>
#include <QSqlError>
#include <QMessageBox>

bool connect()
{
    QSqlDatabase db=QSqlDatabase::addDatabase("QSQLITE");
    db.setDatabaseName("db.sqlite");

    if (!db.open()) 
    {
        QMessageBox::critical(0, qApp->tr("Ошибка"),  
            db.lastError().databaseText(), QMessageBox::Cancel);
        return false;
    }
    QSqlQuery * query = new QSqlQuery;
    query->exec(QObject::tr("set names 'cp1251'"));
    query->exec("create table if not exists employees( "
        "id integer primary key, "
        "name varchar(50) default null, "
        "department varchar(25) default null, "
        "duty varchar(25) default null, "
        "phone varchar(25) default null, "
        "hours int(11) default 0, "
        "password varchar(255) default null, "
        "status varchar(5) default null, "
        "photo blob default null"
        ")");
    query->exec("create table if not exists attendance( "
        "id integer primary key, "
        "employee_id integer, "
        "reg_date date, "
        "start_time int(11), "
        "end_time int(11), "
        "act_category varchar(25)"
        ")");
    return true;
};



Добавлено через 2 минуты
Сейчас попробую код SABROG'a
PM MAIL   Вверх
CuteBunny
Дата 14.5.2008, 16:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 77
Регистрация: 14.2.2008

Репутация: 1
Всего: 1



ПРОГА SABROG'A РАБОТАЕТ smile 

Значит руки у меня не из того места... хЗ? 
PM MAIL   Вверх
CuteBunny
Дата 14.5.2008, 17:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 77
Регистрация: 14.2.2008

Репутация: 1
Всего: 1



Вот только, что написал прогу, часть к моей... Все работает...  smile  smile  smile 

Присоединённый файл ( Кол-во скачиваний: 94 )
Присоединённый файл  loadphoto.rar 2,32 Kb
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С/С++: Кроссплатформенное программирование, QT/Gtk+/wxWidgets"
JackYF
Любитель
  • В заголовке темы в квадратных скобках обозначьте используемую вами библиотеку, например: [QT],[GTK],[wx].
  • Если вопрос актуален только для некоторой версии библиотеки, либо, если вы пользуетесь не самой последней версией, укажите это. Например: [QT4], [GTK2].
  • Все начинающие изучать Qt - не забудьте зайти сюда.
  • Проставьте несколько ключевых слов темы, чтобы её можно было легче найти.
  • В вопросе укажите полную версию версию библиотеки, а также все дополнительные используемые программные пакеты.
  • Не забывайте пользоваться кнопкой "Код".
  • Телепатов на форуме нет! Задавайте чёткий, конкретный и полный вопрос. Указывайте полностью ошибки компилятора и компоновщика.
  • Новое сообщение должно иметь прямое отношение к тематике этого раздела. Флуд, флейм, оффтопик запрещены.
  • Категорически запрещается обсуждение вареза, "кряков", взлома программ и т.д.

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, Любитель.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | С/С++: Кроссплатформенное программирование, Qt/Gtk+/wxWidgets | Следующая тема »


 




[ Время генерации скрипта: 0.1059 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.