Russian Qt Forum

Qt => Базы данных => Тема начата: Astrologer от Сентябрь 08, 2010, 12:18



Название: Прочитать DBF
Отправлено: Astrologer от Сентябрь 08, 2010, 12:18
Все доброго дня! Передо мной стоит задача считать DBF файл (в будущем огромное их количество) и, скажем, отобразить его на форме. Возможно ли использование QSqlDatabase? Огромное спасибо за любой пример.


Название: Re: Прочитать DBF
Отправлено: crossly от Сентябрь 08, 2010, 12:33
+ odbc

ну или http://qt-apps.org/content/show.php/qtDbf?content=109162 (http://qt-apps.org/content/show.php/qtDbf?content=109162)
а вообще вопрос по моему уже поднимался .... поищи..


Название: Re: Прочитать DBF
Отправлено: Astrologer от Сентябрь 08, 2010, 12:35
 :) что бы это могло значить?


Название: Re: Прочитать DBF
Отправлено: crossly от Сентябрь 08, 2010, 12:36
в каком месте не понятно??


Название: Re: Прочитать DBF
Отправлено: Astrologer от Сентябрь 08, 2010, 12:53
Спасибо огромное за ссылку. Как раз то, что нужно. Только надо будет сделать чтобы русскую кодировку понимала.


Название: Re: Прочитать DBF
Отправлено: Astrologer от Сентябрь 08, 2010, 14:05
Почему то не получается получить русскую кодировку. Кто нибудь работал с данной библиотекой?
Код:
QString tempString;
QByteArray recordData;
tempString = recordData.mid(fieldsItem->fieldOffset,fieldsItem->fieldSize);

Такое преобразование происходит.


Название: Re: Прочитать DBF
Отправлено: crossly от Сентябрь 08, 2010, 14:08
нет... а в какой кодировке БД??


Название: Re: Прочитать DBF
Отправлено: Astrologer от Сентябрь 08, 2010, 14:09
760 или 866. Точнее сказать пока не могу.


Название: Re: Прочитать DBF
Отправлено: Astrologer от Сентябрь 08, 2010, 14:22
Код:
QTextCodec *codec = QTextCodec::codecForName("IBM 866");
QString str = codec->toUnicode(recordData.mid(fieldsItem->fieldOffset,fieldsItem->fieldSize));

Так конвертируется.


Название: Re: Прочитать DBF
Отправлено: Troglodit от Сентябрь 08, 2010, 22:11
Достаточно выбрать походящий драйвер DBF ODBC.


Название: Re: Прочитать DBF
Отправлено: arial от Сентябрь 09, 2010, 11:45
Зная формат dbf-файла (http://www.clicketyclick.dk/databases/xbase/format/index.html), можно его прочитать. По крайней мере я в своё время так и сделал.


Название: Re: Прочитать DBF
Отправлено: Astrologer от Сентябрь 09, 2010, 14:21
Какая то ерунда с кодировкой. Даже QString::fromLocal8Bit("Трава") не помогает. Возвращает - ?????.


Название: Re: Прочитать DBF
Отправлено: Пантер от Сентябрь 09, 2010, 15:02
Кодек сначала установить нужно. Куда выводишь: консоль или гуи? Почитай раздел Интернационализация, там уже много раз говорилось как правильно сделать.


Название: Re: Прочитать DBF
Отправлено: Astrologer от Сентябрь 09, 2010, 16:21
Код:
QTextCodec::setCodecForCStrings(QTextCodec::codecForName("Windows-1251"));
QTextCodec::setCodecForTr(QTextCodec::codecForName("Windows-1251"));
QTextCodec::setCodecForLocale(QTextCodec::codecForName("Windows-1251"));
QString trava_str = tr("Трава");

Не пашет и так.


Название: Re: Прочитать DBF
Отправлено: Astrologer от Сентябрь 09, 2010, 16:30
Какая то ерунда с кодировкой. Даже QString::fromLocal8Bit("Трава") не помогает. Возвращает - ?????.

Если открываю новый проект - то безо всяких кодеков такое преобразование проходит.


Название: Re: Прочитать DBF
Отправлено: varkon от Сентябрь 09, 2010, 17:21
А почему вы кодировку cp1251 выставляете? Вам же надо cp866?


Название: Re: Прочитать DBF
Отправлено: Пантер от Сентябрь 09, 2010, 21:26
В какой кодировке исходники?


Название: Re: Прочитать DBF
Отправлено: Astrologer от Сентябрь 10, 2010, 09:43
Это файл qdbf.cpp в котором происходит чтение DBF, запись в модель и связывание модели с таблицей QTableView
Код:
#include "qdbf.h"

QDbf::QDbf(QWidget *parent) :
    QWidget(parent)
{
    QHBoxLayout *mainLayout = new QHBoxLayout(this);

    readDBF();

    QString query;
    QSqlQuery getData(QSqlDatabase::database("dbfEditor"));

            int i;

            query = "SELECT id_";
            query += tableName;
            query += ",";
            for (i=0;i<fieldsCollection.count();i++)
                {
                    query += fieldsCollection.at(i)->fieldName;
                    if (i<fieldsCollection.count()-1)
                        query += ",";
                }
            query +=" FROM ";
            query += tableName;

            model = new QDbfSqlModel(this);

            for (i=0;i<fieldsCollection.count();i++)
                {
                    if (fieldsCollection.at(i)->fieldType == "C")
                        model->addCharField(i+1);
                    if (fieldsCollection.at(i)->fieldType == "Y")
                        model->addCurrencyField(i+1);
                    if (fieldsCollection.at(i)->fieldType == "N")
                        model->addNumericField(i+1);
                    if (fieldsCollection.at(i)->fieldType == "F")
                        model->addNumericField(i+1);
                    if (fieldsCollection.at(i)->fieldType == "D")
                        model->addDateField(i+1);
                    if (fieldsCollection.at(i)->fieldType == "T")
                        model->addTimeField(i+1);
                    if (fieldsCollection.at(i)->fieldType == "B")
                        model->addDoubleField(i+1);
                    if (fieldsCollection.at(i)->fieldType == "I")
                        model->addIntField(i+1);
                    if (fieldsCollection.at(i)->fieldType == "L")
                        model->addLogicalField(i+1);
                    if ((fieldsCollection.at(i)->fieldType == "M") && (fieldsCollection.at(i)->fieldSize == 10))
                        model->addMemoField(i+1);
                    if ((fieldsCollection.at(i)->fieldType == "M") && (fieldsCollection.at(i)->fieldSize == 4))
                        model->addMemo4Field(i+1);
                    if (fieldsCollection.at(i)->fieldType == "G")
                        model->addGeneralField(i+1);
                }

            model->setQuery(query, QSqlDatabase::database("dbfEditor"));

            QTextCodec::setCodecForCStrings(QTextCodec::codecForName("Windows-1251"));
            QTextCodec::setCodecForTr(QTextCodec::codecForName("Windows-1251"));
            QTextCodec::setCodecForLocale(QTextCodec::codecForName("Windows-1251"));
            QString trava_str = tr("?????");
            //query = "SELECT SUMMA FROM " + tableName + " WHERE TYPE LIKE '%" + trava_str + "%';";
            //query = "SELECT SUMMA, MEAN FROM " + tableName;
            //model->setQuery(query, QSqlDatabase::database("dbfEditor"));

            /*QStringList myList;
            for (int i = 0 ; i < model->rowCount();i++)
                myList.push_back(model->record(i).value("TYPE").toString());
            query = "SELECT * FROM " + tableName + " WHERE TYPE LIKE '%" + myList[24] + "%';";
            model->setQuery(query, QSqlDatabase::database("dbfEditor"));*/

            //int str = model->record(0).value("ID").toInt();

            int k = 0;

            if (model->lastError().isValid())
                {
                    QMessageBox::critical(this, tr("Eroare"), model->lastError().text());
                }

            QString tempChar;
            QString tempValue;

            model->setHeaderData(0, Qt::Horizontal, tr("ID"));

            for (int i=0; i<fieldsCollection.count(); ++i)
                {
                    tempValue = fieldsCollection.at(i)->fieldName;

                    /*tempValue += " (";
                    tempValue += fieldsCollection.at(i)->fieldType;
                    tempChar.setNum(fieldsCollection.at(i)->fieldSize);
                    tempValue += tempChar;
                    if (fieldsCollection.at(i)->fieldDecimals != 0)
                        {
                            tempValue += ",";
                            tempChar.setNum(fieldsCollection.at(i)->fieldDecimals);
                            tempValue += tempChar;
                        }
                    tempValue += ")";*/

                    model->setHeaderData(i+1, Qt::Horizontal, tempValue);
                }
            view = new QTableView(this);
            view->setModel(model);

            view->resizeRowsToContents(); //
            view->resizeColumnsToContents();// Вот здесь вылетает
}

void QDbf::readDBF()
{
    QString query;
    QFile file;
    QByteArray fieldDescription;
    int i;
    int j;
    unsigned char a,b,c,d,e,f,g,h;
    double db;

    QString dbfFileName("d:\\dbf\\1.dbf");

    QFileInfo fileInfo(dbfFileName);
    tableName = "d_"+fileInfo.baseName();
    strTableName = "s_"+fileInfo.baseName();

    file.setFileName(dbfFileName);
    if (!file.open(QIODevice::ReadOnly))
        {
            QMessageBox::critical(this, tr("Error"), tr("DBF open error"));
            return;
        }

    sizesHeader.clear();

    sizesHeader = file.read(16);

    a = sizesHeader.at(4);
    b = sizesHeader.at(5);
    c = sizesHeader.at(6);
    d = sizesHeader.at(7);
    e = sizesHeader.at(8);
    f = sizesHeader.at(9);
    g = sizesHeader.at(10);
    h = sizesHeader.at(11);

    numberOfRecords = a + (b << 8) + (c << 16) + (d << 24);
    headerLength = e + (f << 8);
    recordLength = g + (h << 8);

    file.seek(0);
    dbfFileHeader = file.read(headerLength);

    file.seek(32);
    fieldDescriptions.clear();
    fieldDescriptions = file.read(headerLength - 32);
    fieldDescriptions.truncate(fieldDescriptions.lastIndexOf('\x0D'));

    numberOfFields = fieldDescriptions.count() >> 5;

    qint16 tempOffset = 1;

    for (i=0;i<numberOfFields;i++)
        {
            fieldDescription = fieldDescriptions.mid(i*32,32);
            fieldsItem = new QFieldsItem;
            fieldsItem->fieldName = "";
            j = 0;
            while (fieldDescription[j] != '\x00')
                {
                    fieldsItem->fieldName += fieldDescription[j];
                    j++;
                }

            a = fieldDescription.at(12);
            b = fieldDescription.at(13);
            c = fieldDescription.at(14);
            d = fieldDescription.at(15);
            e = fieldDescription.at(16);
            f = fieldDescription.at(17);

            fieldsItem->fieldType = fieldDescription[11];
            fieldsItem->fieldOffset = a + (b << 8) + (c << 16) + (d << 24);

            fieldsItem->fieldOffset = tempOffset;

            tempOffset += e;

            fieldsItem->fieldSize = e;
            fieldsItem->fieldDecimals = f;
            fieldsCollection.append(fieldsItem);
        }

    QSqlQuery getData(QSqlDatabase::database("dbfEditor"));

    query = "DROP TABLE IF EXISTS ";
    query += tableName;

    getData.prepare(query);
    getData.exec();
    if (getData.lastError().isValid())
        {
            QMessageBox::critical(this, tr("Error"), getData.lastError().text());
            return;
        }

    QString tempValue;

    query = "CREATE TABLE ";
    query += tableName;
    query += " ( id_";
    query += tableName;
    query += " integer primary key autoincrement,";

    for (i=0; i<fieldsCollection.count(); ++i)
        {
            query += fieldsCollection.at(i)->fieldName;

            if (fieldsCollection.at(i)->fieldType == "C")
                {
                    query += " text";
                }
            else if (fieldsCollection.at(i)->fieldType == "L")
                {
                    query += " text";
                }
            else if (fieldsCollection.at(i)->fieldType == "M")
                {
                    if (fieldsCollection.at(i)->fieldSize == 10)
                        {
                            query += " numeric";
                        }
                    if (fieldsCollection.at(i)->fieldSize == 4)
                        {
                            query += " blob";
                        }

                }
            else if (fieldsCollection.at(i)->fieldType == "N")
                {
                    query += " text";
                }
            else if (fieldsCollection.at(i)->fieldType == "F")
                {
                    query += " text";
                }
            else if (fieldsCollection.at(i)->fieldType == "D")
                {
                    query += " text";
                }
            else
                {
                    query += " blob";
                }

            if (i<(fieldsCollection.count()-1))
                query += ",\n";
        }

    query += ")";

    getData.prepare(query);
    getData.exec();
    if (getData.lastError().isValid())
        {
            QMessageBox::critical(this, tr("Error"), getData.lastError().text());
            return;
        }

    quint32 q;
    bool ok;

    for (q=0;q<numberOfRecords;q++)
        {
            query = "INSERT INTO ";
            query += tableName;
            query += " (";
            for (j=0; j<fieldsCollection.count(); ++j)
                {
                    query += fieldsCollection.at(j)->fieldName;
                    if (j<fieldsCollection.count()-1)
                        query += ",";
                }
            query += ") VALUES (";

            recordData.clear();
            file.seek(headerLength + q*recordLength);
            recordData=file.read(recordLength);
            if (recordData.at(0) == '*')
                continue;

            QString tempDate;
            QString tempString;

            for (j=0; j<fieldsCollection.count(); j++)
                {
                    fieldsItem = fieldsCollection.at(j);
                    fieldsItem->fields = "'";
                    if (fieldsItem->fieldType == "D")
                        {
                            tempDate = recordData.mid(fieldsItem->fieldOffset,fieldsItem->fieldSize);
                            if (tempDate == "        ")
                                fieldsItem->fields+="";
                            else
                                {
                                    fieldsItem->fields += tempDate.mid(0,4);
                                    fieldsItem->fields += "-";
                                    fieldsItem->fields += tempDate.mid(4,2);
                                    fieldsItem->fields += "-";
                                    fieldsItem->fields += tempDate.mid(6,2);
                                }
                        }
                    else if (fieldsItem->fieldType == "C")
                        {
                            tempString = recordData.mid(fieldsItem->fieldOffset,fieldsItem->fieldSize);
                            //fieldsItem->fields += tempString.replace("'","''");
                            //
                            QTextCodec *codec = QTextCodec::codecForName("IBM 866");
                            QString str = codec->toUnicode(recordData.mid(fieldsItem->fieldOffset,fieldsItem->fieldSize));
                            tempString = str;
                            fieldsItem->fields += tempString.replace("'","''");
                            //
                            int k=0;
                        }
                    else if ((fieldsItem->fieldType == "N") || (fieldsItem->fieldType == "F"))
                        {
                            tempString = recordData.mid(fieldsItem->fieldOffset,fieldsItem->fieldSize);
                            db = tempString.toDouble(&ok);
                            tempString.setNum(db,'f',fieldsItem->fieldDecimals);
                            fieldsItem->fields += tempString;
                        }
                    else if (fieldsItem->fieldType == "L")
                        {
                            tempString = recordData.mid(fieldsItem->fieldOffset,fieldsItem->fieldSize);
                            fieldsItem->fields += tempString;
                        }
                    else if ((fieldsItem->fieldType == "M") && (fieldsItem->fieldSize == 10))
                        {
                            tempString = recordData.mid(fieldsItem->fieldOffset,fieldsItem->fieldSize);
                            fieldsItem->fields += tempString;
                        }
                    else
                        {
                            tempString = recordData.mid(fieldsItem->fieldOffset,fieldsItem->fieldSize).toHex().toUpper();
                            fieldsItem->fields += tempString;
                        }
                    fieldsItem->fields += "'";

                    query += fieldsItem->fields;

                    if (j<fieldsCollection.count()-1)
                        query += ",";
                }
            query += ")";

            getData.prepare(query);
            getData.exec();
            if (getData.lastError().isValid())
                {
                    QMessageBox::critical(this, tr("Error"), getData.lastError().text());
                    return;
                }
        }

    query = "DROP TABLE IF EXISTS ";
    query += strTableName;

    getData.prepare(query);
    getData.exec();
    if (getData.lastError().isValid())
        {
            QMessageBox::critical(this, tr("Error"), getData.lastError().text());
            return;
        }

    query = "CREATE TABLE ";
    query += strTableName;
    query += " ( id_";
    query += strTableName;
    query += " integer primary key autoincrement, \n";
    query += "fieldName text, \n";
    query += "fieldType text, \n";
    query += "fieldLength numeric, \n";
    query += "fieldDecimals numeric)";

    getData.prepare(query);
    getData.exec();
    if (getData.lastError().isValid())
        {
            QMessageBox::critical(this, tr("Error"), getData.lastError().text());
            return;
        }

    for (i=0; i<fieldsCollection.count(); i++)
        {
            query = "INSERT INTO ";
            query += strTableName;
            query += " (fieldName, fieldType, fieldLength, fieldDecimals) VALUES ('";
            query += fieldsCollection.at(i)->fieldName;
            query += "','";
            query += fieldsCollection.at(i)->fieldType;
            query += "','";
            tempValue.setNum(fieldsCollection.at(i)->fieldSize,10);
            query += tempValue;
            query += "','";
            tempValue.setNum(fieldsCollection.at(i)->fieldDecimals,10);
            query += tempValue;
            query += "')";

            getData.prepare(query);
            getData.exec();
            if (getData.lastError().isValid())
                {
                    QMessageBox::critical(this, tr("Error"), getData.lastError().text());
                    return;
                }
        }

    file.close();
}

Вот это qdbf.h^
Код:
#ifndef QDBF_H
#define QDBF_H

#include <QWidget>
#include <QtGui>
#include <QSqlDatabase>
#include <QSqlQueryModel>
#include <QtSql>

#include "customsqlmodel.h"
#include "structures.h"

class QDbf : public QWidget
{
Q_OBJECT
public:
    explicit QDbf(QWidget *parent = 0);

    void readDBF();

    QFieldsItem* fieldsItem;
    QList<QFieldsItem*> fieldsCollection;

    QByteArray sizesHeader;
    QByteArray fieldDescriptions;
    QByteArray dbfFileHeader;
    QByteArray recordData;

    quint32 numberOfRecords;
    quint16 headerLength;
    quint16 recordLength;
    quint16 numberOfFields;

    QTableView* view;
    QDbfSqlModel* model;

    QString tableName;
    QString strTableName;

signals:

public slots:

};

#endif // QDBF_H


Вот это файл mainwindow.cpp:
Код:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "qdbf.h"


MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    QDbf* dbf_new = new QDbf(this);
    setCentralWidget(dbf_new);
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::changeEvent(QEvent *e)
{
    QMainWindow::changeEvent(e);
    switch (e->type()) {
    case QEvent::LanguageChange:
        ui->retranslateUi(this);
        break;
    default:
        break;
    }
}

Не могу понять почему вылетает. Если resize не делать, то нормально загружается, однако таблица сжата так, что ничего нельзя разобрать. Помогите пожалуйста!


Название: Re: Прочитать DBF
Отправлено: Пантер от Сентябрь 10, 2010, 10:06
http://gitorious.org/qdbfredactor
Изучай. Это мой редактор dbf. Если будут вопросы, обращайся.


Название: Re: Прочитать DBF
Отправлено: Astrologer от Сентябрь 10, 2010, 10:16
Спасибо большое - буду разбираться. Я новичок в QT и вот пытаюсь открыть ваш проект в креаторе. При попытке скомпилировать:
Код:
Выполняется сборка проекта QDBFRedactor...
Запускается: c:/qt/2010.02.1/qt/bin/qmake.exe D:/my_projects/qdbfredactor-qdbfredactor-master/qdbfredactor-qdbfredactor/QDBFRedactor.pro -spec win32-g++ -r
WARNING: Failure to find: src\dbfredactor.cpp
WARNING: Failure to find: src\dbfredactormodel.cpp
WARNING: Failure to find: src\dbfredactorsortfilterproxymodel.cpp
WARNING: Failure to find: src\filterdialog.cpp
WARNING: Failure to find: src\sortdialog.cpp
WARNING: Failure to find: src\dbfredactor.h
WARNING: Failure to find: src\dbfredactormodel.h
WARNING: Failure to find: src\dbfredactorsortfilterproxymodel.h
WARNING: Failure to find: src\filterdialog.h
WARNING: Failure to find: src\sortdialog.h
WARNING: Failure to find: src\dbfredactor.cpp
WARNING: Failure to find: src\dbfredactormodel.cpp
WARNING: Failure to find: src\dbfredactorsortfilterproxymodel.cpp
WARNING: Failure to find: src\filterdialog.cpp
WARNING: Failure to find: src\sortdialog.cpp
WARNING: Failure to find: src\dbfredactor.h
WARNING: Failure to find: src\dbfredactormodel.h
WARNING: Failure to find: src\dbfredactorsortfilterproxymodel.h
WARNING: Failure to find: src\filterdialog.h
WARNING: Failure to find: src\sortdialog.h
Завершено с кодом 0.
Запускается: C:/Qt/2010.02.1/mingw/bin/mingw32-make.exe -w
mingw32-make: Entering directory `D:/my_projects/qdbfredactor-qdbfredactor-master/qdbfredactor-qdbfredactor'
C:/Qt/2010.02.1/mingw/bin/mingw32-make -f Makefile.Debug
mingw32-make[1]: Entering directory `D:/my_projects/qdbfredactor-qdbfredactor-master/qdbfredactor-qdbfredactor'
mingw32-make[1]: Leaving directory `D:/my_projects/qdbfredactor-qdbfredactor-master/qdbfredactor-qdbfredactor'
mingw32-make: Leaving directory `D:/my_projects/qdbfredactor-qdbfredactor-master/qdbfredactor-qdbfredactor'
mingw32-make[1]: *** No rule to make target `src/dbfredactor.cpp', needed by `build/dbfredactor.o'. Stop.
mingw32-make: *** [debug] Error 2
Завершено с кодом 2.
Ошибка во время сборки проекта QDBFRedactor
Во время выполнения сборки на этапе 'Make'


Название: Re: Прочитать DBF
Отправлено: Пантер от Сентябрь 10, 2010, 10:38
Я pro не поддерживаю, надо его удалить. Открывай CMakeLists.


Название: Re: Прочитать DBF
Отправлено: Astrologer от Сентябрь 10, 2010, 18:04
Не пинайте сильно, но кто нибудь может объяснить куда сохраняется база физически. Вот открыли мы соединение, создали кучу таблиц. И как все это богатство сохранить? В каком формате, как потом опять считывать? Абстрагируясь пока от dbf файлов.  :)

Далее. У меня большое количество dbf файлов. Мне их все нужно открыть, считать и занести в отдельную базу и с ней потом работать. Как эту базу сохранить, открыть?


Название: Re: Прочитать DBF
Отправлено: Astrologer от Сентябрь 12, 2010, 11:01
Код:
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE", "dbfEditor");
        db.setDatabaseName("myBase.dat");
        bool okk = db.open();

okk - false возвращает. Файл не существует, но я хочу чтобы база сохранялась в файл. Как это сделать?)


Название: Re: Прочитать DBF
Отправлено: nixman05 от Сентябрь 12, 2010, 11:22
Код:
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE", "dbfEditor");
        db.setDatabaseName("myBase.dat");
        bool okk = db.open();

okk - false возвращает. Файл не существует, но я хочу чтобы база сохранялась в файл. Как это сделать?)

А что возвращает db.lastError.text() ?


Название: Re: Прочитать DBF
Отправлено: Astrologer от Сентябрь 17, 2010, 08:51
Проблема решена. Все работает.


Название: Re: Прочитать DBF
Отправлено: Пантер от Сентябрь 17, 2010, 09:37
Проблема решена. Все работает.
Что было неверно?


Название: Re: Прочитать DBF
Отправлено: Astrologer от Сентябрь 17, 2010, 10:07
Код:
void QDbfReader::openConnection()
{
    {
    QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE", "dbfEditor");
   //dbFile = "myBase.dat"
    if (!QFile::exists(dbFile)) return;
    db.setDatabaseName(dbFile);
        if (!db.open()) {
            QMessageBox::critical(0, qApp->tr("Cannot open database"),
                qApp->tr("Unable to establish a database connection.\n"
                         "This example needs SQLite support. Please read "
                         "the Qt SQL driver documentation for information how "
                         "to build it.\n\n"
                         "Click Cancel to exit."), QMessageBox::Cancel);
        }

        _base_is_open = true;
    }
}

Так работает. Хотя когда писал, db.open() иногда возвращало false. Всем большое спасибо.