Ошибка при закрытии и открытии БД на QT5 с использованием SQlite - PullRequest
1 голос
/ 06 января 2020

Я знаю, что это распространенная ошибка, так как я видел много вопросов об этом, проблема возникает из-за того, что я не смог ее исправить.

Это проблема, у меня есть эта функция чтобы обновить и центрировать данные моего QTableView в моем заголовке mainWindow.h:

QStandardItemModel * tableUpdate(){

       QStandardItemModel *modd = new QStandardItemModel();
       QSortFilterProxyModel *proxy1 = new QSortFilterProxyModel();
       QSqlTableModel *model = new QSqlTableModel();

       model->setTable("Main");
       model->select();
       proxy1->setSourceModel(model);

       for (int z =0; z< proxy1->rowCount(); ++z){
           for (int y =0; y< proxy1->columnCount(); ++y){

               QStandardItem *item= new QStandardItem();
               item->setText(proxy1->index(z,y).data().toString());
               item->setTextAlignment(Qt::AlignCenter);
               modd->setItem(z,y,item);
               }
         }
       modd->setHeaderData(0,Qt::Horizontal,tr("Name"));
       modd->setHeaderData(1,Qt::Horizontal,tr("Class"));
       modd->setHeaderData(2,Qt::Horizontal,tr("Unit"));
       modd->setHeaderData(3,Qt::Horizontal,tr("Qty"));
       modd->setHeaderData(4,Qt::Horizontal,tr("Price"));

       return modd;
   }

У меня есть функции, чтобы открывать и закрывать мою БД, эти два:

bool coonOpen(){

        db= QSqlDatabase::addDatabase("QSQLITE");
        db.setDatabaseName("/home/adan/Groostore/MainDB.db");
        db.open();

        return true;
}

   void connClose(){

        QString conexion = db.connectionName();
        db.close();
        db = QSqlDatabase();       
        db.removeDatabase(conexion);
    }

Так что, как только я мне нужно обновить мой QTableview, я делаю это из разных .cpps, когда это необходимо:

    MainWindow *mainw = new MainWindow();
    QStandardItemModel *modd = new QStandardItemModel();

    mainw->coonOpen();
    modd = mainw->tableUpdate();
    ui->tableView->setModel(modd);
    ui->tableView->horizontalHeader()->setSectionResizeMode(1,QHeaderView::Stretch);
    delete modd;
    mainw->connClose();

Все работает нормально, как нужно, но это то, что я получил на консоли отладки:

QSqlDatabasePrivate::removeDatabase: connection 'qt_sql_default_connection' is still in use, all queries will cease to work.
QSqlDatabasePrivate::addDatabase: duplicate connection name 'qt_sql_default_connection', old connection removed.

Что я делаю неправильно? это сводит меня с ума Dx! Заранее спасибо за поддержку.

1 Ответ

1 голос
/ 06 января 2020

Проблема с ошибкой заключается в том, что вы используете defaultConnection, вместо этого вы должны создать временное соединение. Также предполагая, что MainWindow является окном, я не вижу logi c, в котором есть метод, который предоставляет только модель, так как вы должны создать окно, которое не будет отображаться для предоставления этих данных, лучше, чтобы этот метод был функцией.

С другой стороны, я считаю ненужным использовать QStandardItemModel и QSortFilterProxyModel для изменения выравнивания текста, так как достаточно иметь настраиваемый QStyledItemDelegate.

Наконец, я вижу, что вы пытаетесь исключить указатель модели, поскольку это нелогично, поскольку в теории вы пытаетесь уничтожить информацию, используемую представлением, кроме того, модель является объектом QObject, поэтому при использовании delete не удаляется модель, вместо этого следует использовать deleteLater, но даже в Qt Вы не должны обращаться с памятью напрямую, лучше оставить это задание родительскому.

Обновление:

В случае QSqlTableModel оно предназначено для сохранения соединение открыто, пока существует модель, поэтому соединение не может быть удалено редактор Поэтому, если вы хотите удалить соединение, вы должны использовать QSqlQueryModel.

connection.h

#ifndef CONNECTION_H
#define CONNECTION_H

#include <QSqlDatabase>
#include <QSqlTableModel>

static QSqlQueryModel * loadTable(){
    QSqlQueryModel *model;
    {
        QSqlDatabase db= QSqlDatabase::addDatabase("QSQLITE", "db_temporal");
        db.setDatabaseName("/home/adan/Groostore/MainDB.db");
        if(!db.open())
            return nullptr;
        QSqlQuery query("select * from Main", db);
        model = new QSqlQueryModel;
        model->setQuery(query);
    }
    QSqlDatabase::removeDatabase("db_temporal");
    return model;
}
#endif // CONNECTION_H

aligncenterdelegate.h

#ifndef ALIGNCENTERDELEGATE_H
#define ALIGNCENTERDELEGATE_H

#include <QStyledItemDelegate>

class AlignCenterDelegate : public QStyledItemDelegate
{
public:
    using QStyledItemDelegate::QStyledItemDelegate;
protected:
    void initStyleOption(QStyleOptionViewItem *option, const QModelIndex &index) const;
};

#endif // ALIGNCENTERDELEGATE_H

aligncenterdelegate. cpp

#include "aligncenterdelegate.h"

void AlignCenterDelegate::initStyleOption(QStyleOptionViewItem *option, const QModelIndex &index) const
{
    QStyledItemDelegate::initStyleOption(option, index);
    option->displayAlignment = Qt::AlignCenter;
}

Теперь просто установите делегат в конструкторе:

// ...
ui->setupUi(this);
ui->tableView->setItemDelegate(new AlignCenterDelegate(this));
// ...

И затем загрузите модель с следующий код:

// ...
if(QSqlQueryModel *model = loadTable()){
    if(QAbstractItemModel *previos_model = ui->tableView->model()){
        previos_model->deleteLater();
    }
    model->setParent(this);
    ui->tableView->setModel(model);
}
// ...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...